Device Drivers Patterns

I want to know how to handle input and output drivers with the FreeRTOS Kernel.
The way that I’m handling drivers is like this:
I have a top priority task (let’s call it “process”) that blocks and waits for events triggered by device driver tasks.

My device has a touch keypad and LCD screen. I implemented the State Pattern to show various menus and stuff on LCD screen according to each state.

The “process” task implements the state pattern machine, and triggers state events.
As an example:
the keypad driver task notifies my process task that a key has been pressed, then the process task triggers the corresponding event within the state context and shows stuff on the LCD screen.

I feel that the fact that each device driver task needs to know about the process task is not right, so I am wondering if there’s a better way to handle this sort of device drivers.

Most of my devices signal their actions to a Queue or Semaphore assigned to that device. Something like your keypad driver would get the interrupt of a key press and put into a Queue a code to say what just happened. The task then blocks on the Queue waiting for a keypress.

For something like an I2C bus, the task calls the driver for the I2C bus, which sets up the operation, then blocks on a semaphore related to that device, which gets signaled when the transaction is done.

If you want to use Direct-to-task notifications instead of a semaphore, then set a variable shared between the driver and the ISR to the task handle before starting, and it can use that value to signal.

Hi, thank you for your response.

I like the idea of using a queue.
As you said, my keypad driver blocks waiting for an interrupt signaling a keypress, then it processes the information and now it could write to the queue to report the keypress. Specifically, the keypad is based on a QTouch chip.

I am thinking of implementing a new layer, this “input” layer would block on a queue that is written by, in this case, the QTouch driver and a system for virtual key presses over ethernet.

Or alternatively you could use notifications as light weight event group as explained here FreeRTOS task notifications, fast Real Time Operating System (RTOS) event mechanism
I’m using this pattern for devices drivers which are handled by a single post-processing task because their events belong together and trigger a single state machine similar to your user interface/process task.
Depending on your device driver design this might be combined with FreeRTOS message buffers - circular buffers or FreeRTOS or custom queues to signal the corresponding event data if the event data handling can’t be deferred to the post-processing task due to latency constraints.