gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 16:21:12 27 4
gpt4 key购买 nike

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

在 C 中,我会创建一个结构,其中包含函数指针并相应地填充函数指针,在运行时以太坊或通过编译时初始化{就像在 Linux 内核驱动程序中重新初始化设备驱动程序}。 Linux 设备驱动程序通常有一个“驱动程序私有(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++ 处理额外的硬件特定内容,这些内容将保留在私有(private)数据结构中。好像应该在派生类什么的?

我是这样想的:

/* 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-Diagram of classes,我的问题是我如何在 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 是接口(interface)类。 C 中的函数指针赋值(例如 wrBytes)在 C++ 中是在创建对象时通过虚拟函数指针完成的。

但是,serial_port 类不必从 serial_hw_level 派生。 Composition 更适合它,因为您需要一个名称,以及一个抽象的 serial_hw_level 对象。

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

关于c++ - 如何创建 C++ 设备驱动程序类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23977213/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com