簡體   English   中英

如何創建C ++設備驅動程序類

[英]how to create a C++ device driver class

我非常了解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
};

要清楚; 我確實需要兩個不同的抽象層次。 我知道如何在直接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;
};

所以我有一個類的VEN圖,我的問題是我如何在C ++中做到這一點。 我可以用C做到這一點,很簡單。 我完全理解這種技巧。

我有兩種類型的類指針需要指向相同的基類。

在普通的C中,我通過'intptr_t private'隱藏了一個特定於實現的結構 - 這是一個隱藏的指針。

在C ++中,我認為它保存在派生類中。

同樣的想法可以擴展 - 我可以創建一個'ByteStream'類 - 它可以處理一個字節流 - 無論是文件,還是串行端口,或者 - 也許是內存中的緩沖區。

請注意:我使用串行端口作為示例,但這些也適用於I2C端口。 我可能有一個以硬件實現的I2C端口,或者可能通過bit-bang IO或SPI端口實現

謝謝。

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)
};

serial_hw_level是接口類。 C中的函數指針賦值(如wrBytes)是在創建對象時通過虛函數指針在C ++中完成的。

但是,serial_port類不必從serial_hw_level派生。 組合更適合它,因為你需要一個名稱,還有一個抽象的serial_hw_level對象。

接下來是全局命名空間中的對象。 如果希望它是全局的,在C中,您可以簡單地為它指定函數指針。 您甚至沒有派生類或派生對象。 你所擁有的只是初始時的基類,基礎對象和虛函數指針賦值(在C ++的視圖中)。 在C ++中,當您派生類和虛函數指針時,通過指針或引用實現對基類的賦值。 由於您需要全局對象,因此可以新建派生對象,在初始時將它們分配給基指針,並在進程由類serial_port的析構函數自動退出之前刪除它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM