如何创建C++设备驱动程序类

use*_*153 10 c++ device-driver

我非常了解C,而不是C++ - 并且想要用C++创建硬件驱动程序.我需要一些指示.

在C中,我将创建一个结构,使用函数指针并相应地填充func指针,在运行时填充ether,或者通过编译时初始化{就像在Linux内核驱动程序中重新初始化的设备驱动程序}.Linux设备驱动程序通常有一个'driver private'元素,让驱动程序保持一个特定于实现的指针(保存其他东西)

我不知道该怎么做 - 使用C++类创建相同的东西.

我的例子是一个串口.

驱动程序的硬件部分 - 在C中将是这样的:

struct serail_driver;
struct serial_hw_level;

struct serial_hw_level {
    // points to implementation specific details
    inptr_t  hw_private;

    // basically pure virtual functions
    int (*wrBytes)( struct serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes );
    int (*rdBytes)( struct serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes );

    /* there would be other member funds, but this is is a short example */
};

/* the generic serial port */
struct serial_generic_driver {
     const char *name;

     struct serial_hw_driver *hw_Driver;
};

/* create two serial ports at the hardware level */
struct serial_hw_level arm9_serial_port = {
    .hw_private = (intptr_t)(&hw_driver_
    .wr_bytes   = arm9_uart_wr_bytes,
    .rd_bytes   = arm9_uart_rd_bytes
};

struct serial_hw_level usb_emulated_port = {
    .hw_private = (inptr_t)(&usb_private_stuff),
    .wr_bytes   = usb_serial_wr_bytes,
    .rd_bytes   = usb_serial_rd_bytes
};

/* create generic serial port stuff */
struct serial_port usb_serial = {
   .name = "USBSERIAL",
   .hw_driver = &usb_emulated_port
};

struct serial_port hw_serial = {
    .name = "HW SERIAL",
    .hw_driver = &arm9_serial_port
};
Run Code Online (Sandbox Code Playgroud)

要清楚; 我确实需要两个不同的抽象层次.我知道如何在直接C中执行此操作 - 在Linux内核中 - 这是一个蛋糕行走.

我不知道该怎么做是使用C++来处理额外的硬件特定内容,这些内容将保留在私有数据结构中.看来应该是派生类还是什么?

我在想这样的事情:

/* the base class */
class serial_hw_level {
    intptr_t hw_private;  
    virtual int wr_bytes( uint8_t *pBytes, int bytes );
    virtual int rd_bytes( uint8_t *pBytes, int bytes );
 };

/* The generic usb serial port... */
class serial_port : public serial_hw_level {
    string name;    
};


/* another derived class */    
class usb_serial : public serial_hw_level {
   int usb_endpoint;
   int usb_controller;
   int emualted_handshake_pins;
};
Run Code Online (Sandbox Code Playgroud)

所以我有一个类的VEN图,我的问题是我如何在C++中做到这一点.我可以用C做到这一点,很简单.我完全理解这种技巧.

我有两种类型的类指针需要指向相同的基类.

在普通的C中,我通过'intptr_t private'隐藏了一个特定于实现的结构 - 这是一个隐藏的指针.

在C++中,我认为它保存在派生类中.

同样的想法可以扩展 - 我可以创建一个'ByteStream'类 - 它可以处理一个字节流 - 无论是文件,还是串行端口,或者 - 也许是内存中的缓冲区.

请注意:我使用串行端口作为示例,但这些也适用于I2C端口.我可能有一个以硬件实现的I2C端口,或者可能通过bit-bang IO或SPI端口实现

谢谢.

Ala*_*ght 2

struct serial_driver;

class serial_hw_level {
public:
    virtual ~serial_hw_level() { }
    virtual int wrBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes) = 0;
    virtual int rdBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes) = 0;
};

class arm9_uart: public serial_hw_level {
public:
    arm9_uart(int sutff);
    virtual ~arm9_uart();
    virtual int wrBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes);
    virtual int rdBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes);

private:
    int arm9_stuff;
};

class usb_emulated: public serial_hw_level {
public:
    usb_emulated(int endpoint, int controller, int handshake_pins);
    virtual ~usb_emulated();
    virtual int wrBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes);
    virtual int rdBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes);

private:
    int usb_endpoint;
    int usb_controller;
    int emulated_handshake_pins;
};

class serial_port {
public:
    serial_port(const string& serial_name, serial_hw_level* driver);
    ~serial_port();
    string get_name() const;

private:
    string name;
    serial_hw_level* hw_driver;
};


// Implementation *.cpp files

arm9_uart::arm9_uart(int stuff)
    : arm9_stuff(stuff) {
}

arm9_uart::~arm9_uart() {
    // free resources
}

int arm9_uart::wrBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes) {
    // do things
    return 0;
}

int arm9_uart::rdBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes) {
    // do things
    return 0;
}


usb_emulated::usb_emulated(int endpoint, int controller, int handshake_pins)
    : usb_endpoint(endpoint),
      usb_controller(controller),
      emulated_handshake_pins(handshake_pins) {
}

usb_emulated::~usb_emulated() {
    // free resources
}

int usb_emulated::wrBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes) {
    // do things
    return 0;
}

int usb_emulated::rdBytes(serial_driver *pDriver, uint8_t *ptr_bytes, int nBytes) {
    // do things
    return 0;
}

serial_port::serial_port(const string& serial_name, serial_hw_level* driver)
    : name(serial_name),
      hw_driver(driver) {
}

serial_port::~serial_port() {
    delete hw_driver;
    hw_driver = NULL;
}

string serial_port::get_name() const {
    return name;
}


serial_port hw_serail = {
    "HW SERIAL",
    new arm9_uart(arm9_stuff)
};

serial_port usb_serial = {
    "USBSERIAL",
    new usb_emulated(usb_endpoint, usb_controller, emulated_handshake_pins)
};
Run Code Online (Sandbox Code Playgroud)

Serial_hw_level 是接口类。C 中的函数指针赋值(例如 wrBytes)在 C++ 中是在创建对象时通过虚拟函数指针完成的。

然而,serial_port 类不必从serial_hw_level 派生。组合更适合它,因为您需要它的名称,以及抽象的serial_hw_level对象。

接下来是全局命名空间中的对象。当您希望它是全局的时,在 C 中,您可以简单地将函数指针分配给它。您甚至没有派生类或派生对象。您所拥有的只是初始时的基类、基对象和虚函数指针赋值(在 C++ 中)。在C++中,当有派生类和虚函数指针时,对基类的赋值是通过指针或引用来实现的。由于您需要全局对象,因此您可以新建派生对象,在初始时将它们分配给基指针,并在进程退出之前通过类serial_port的析构函数自动删除它们。