I know C very well, not C++ - and want to create a hardware driver in C++. I need some pointers.
In C, I would create a structure, with function pointers and populate the func-pointers accordingly, ether at run time, or by compile time initialization {like the device drivers re initialized in Linux Kernel drivers}. Linux device drivers often have a 'driver private' element that lets the driver keep an implementation specific pointer (holding other stuff)
What I don't know how to do - is create the same thing using C++ classes.
My example would be for a serial port.
The Hardware portion of the driver - in C would be something like this:
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
};
To be clear; I do need the two different levels of abstraction. I know well how to do this in straight C - in the Linux kernel -that is a cake walk.
What I don't know how to do is handle the extra hardware specific stuff using C++ that would be keep in the private data structures. It seems that should be in a derived class or something?
I'm thinking something like this:
/* 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;
};
So I sort of have a VEN-Diagram of classes, my question is how do I do this in C++. I can do this in C, it is simple. I completely understand that technique.
What i have is two types of class pointers that need to point to the same base class.
in plain C, I hide things in an implementation specific structure via the 'intptr_t private' - which is a pointer in hiding.
In C++, I think this is kept in the derived class.
The same idea could be extended - and I could create a 'ByteStream" class - that could handle a stream of bytes - either to a file, or to a serial port, or - perhaps to a buffer in memory.
Please note: I'm using a serial port as an example, but these same would apply to an I2C port. I might have a I2C port implemented in hardware, or perhaps implemented via bit-bang IO or SPI port
Thanks.