Electronic – Unified Driver model for low speed and high speed microcontrollers with limited and good memory

devicedriver

I am trying to develop an experimental RTOS. I am stuck in the driver layer design. I want to make the driver layer libraries friendly for the other layers but then again I would like to have high performance.
I have narrowed this down to a mixture of 2 approaches. The first is to have a structure for the controller with callbacks as elements.
For eg:

struct peripheral_controller { 
    int32_t (*init) (struct peripheral_instance_regs *peripheral_instance_regs);
    int32_t (*isFull) (struct peripheral_instance_regs *peripheral_instance_regs);
};

The second approach is to have helper macros which take the peripheral_instance_regs as arguements.

For eg:

#define isFull(reg)
 (reg&0x01 == 1)

Is this the right approach? Will it confuse the users of my library? The problem with the callbacks as I see is in the interrupt routine where I would not want to call any functions.

Best Answer

(See also Is there a standard for writing device drivers for microcontrollers? ; as your question relates purely to software you might get a better answer on the software stackexchange.)

In C, functions are strongly preferred over macros wherever possible. They're easier to debug, and can inline just as well if you're concerned about speed. You say "in the interrupt routine where I would not want to call any functions"; what target platform are you writing for and do you have a hard stack limit? Banning functions entirely from interrupt handlers is not a great style either. You might want to invest in a "top half"/"bottom half" architecture as used by Linux.

Having said that, the quasi-object-orientated style (I wouldn't call it "callback") of passing a map of peripheral registers around doesn't work well on the very small platforms such as PIC, where indirection is unreasonably expensive. Those are really too small for a meaningful operating system with drivers.