If we need to integrate basic MCAL drivers such as flash,CAN and so on … with freeRTOS application, is there a simple approach ?
We want to keep it as simple as possibe with just freeRTOS application calling driver calls in a 1:1 or a thin layer.
If you want to call your driver APIs from FreeRTOS tasks, you need to ensure that those APIs are thread safe. If you call those APIs only from one task, it should not be an issue. Otherwise (assuming that the driver APIs are not thread safe), you need to serialize calls to the APIs.
Any example that will show the usage of driver calls on a typical freertos application ?
It will be really helpful
Are you looking for an example about how to serialize calls to a non thread-safe API to make it thread safe? If so, a very simple approach can be to use a mutex to protect API calls. Every API call will then become a 3 step sequence -
- Acquire mutex.
- Call non-thread safe API.
- Release mutex.
Another approach is to post all the requests to a queue and have a single task service all the requests posted to that queue. Similar to what is described here - Safer Interrupt Handling Demo for NXP LPCXpresso55S69 Development Board - FreeRTOS
Thank you ,
Our goal is - we have couple of peripheral drivers such as CAN, flash etc… in our legacy code which is non-RTOS and we intend to migrate those drivers to work with a freeRTOS application. this application may need services of the drivers such init/read/write and so on …
so, my question is
- Do these drivers need any special changes so as to talk to a freeRTOS application ?
meaning do we need to make those drivers kernel-aware or keep them as they are and just integrate with the freeRTOS application ?
The existing drivers of non RTOS code base are re entrant and use EI/DI pair to guard critical sections. maybe if they need to be kernel aware , then instead of EI /DI pair they may need a mutex locks and currently ISR signal occurrence of an event by a global variable and now they can give a mutex or semaphore to do same thing
or may be we can keep same EI/DI itself even after migrating to a rtos based application.
So , what is the expectation of freertos kernel from those drivers to work with its application?
I worked in other RTOSes and the Application did not need drivers to be kernel -aware in most of the cases.
Do we need any Tasks at driver level?
lets consider a CAN driver - currently send /receive are handled at function level in a non rtos driver may be in rtos based scenario, we may (or may not )need a dedicated CAN Send Task and CAN Receive Task and still, CAN send and Receive can happen in function level instead of a task level.
In order to check this out, is there any for example a kernel -aware driver , a CAN driver which use task and semaphores in may at a layer like hal_canxxx to refer to ?
Are the EI/DI to allow multiple “tasks” to access the code, at which point it was written “Thread Aware”, and making it RTOS compliant is likely mostly done, or are those protections from access via ISRs?
The biggest issue with non-RTOS aware drivers is that they will “spin-wait” while waiting for operations to complete, instead of blocking, which means that they hog the processor. A “Good” RTOS aware driver should use interrupts for most operations that can take time, with the task level code blocking on a synchronization object (Queue, Semaphore, etc) while waiting for the event to occur.
Sometimes it is just a minor adaptation of the driver, sometimes it needs.a complete rewrite.
ok, thanks for the reply
yes, EI/DI pair provide at present, concurrent access to multiple applications ( non-RTOS) lets say 3 subscribers want Read service from driver and call same driver routine at same time. Maybe not both read/write are interrupt driven but only say , read is interrupt driver and write is by polled mode.
as you said, if application developer creates Send/Receive tasks and those tasks want to interact with the driver routine for unilateral rendezvous or signal event occurence via ISR to App.task, then driver should ideally support synchronisation primitive such as MsgQ or semaphore, this is where the legacy driver may need to additionally support RTOS aware ability.
if we have such a RTOS aware driver in any sample projects provided, it will be helpful to refer to it to refactor the legacy driver to be rtos aware.
that means driver can either have a dedicated Send task and Receive Task or still manage with existing Send and Receive functions if they take of no l
When you say “multiple applications (non-RTOS), do you REALLY mean that it is designed as a thread/task aware driver? Just maybe not for a “Real-Time” threading system. If that is really true, they should be documenting how it interfaces into such a system, and you just need to implement that interface.
If you are just assuming that these DI/EI blocks will let that happen, you may be solely mistaken. They may just be providing protection between “Application” level access and ISR level access to some data structures, which is a lot less that true multiple-application access.
My experience is a “legacy” driver will normally be NOT RTOS aware, and for initial work you might be able to use it where you either restrict usage to a single task or you wrap access in a Mutex, or you might find one that is generic RTOS aware with an EXPLICIT porting layer to allow it to be adapted to a specific RTOS.
The non-RTOS aware drivers almost always need to be rewritten before you get to release to be RTOS aware to avoid killing the Real Time nature of the system.
The FreeRTOS website provides a few examples of making a driver event driven, allowing tasks that interact with the driver to wait in the blocked state (so not consume any CPU time, allowing other tasks to execute) while waiting for driver operations. For example:
There are also examples in the free to download book.
Thank you for the reply,
now understand the essence of a kernel aware driver as opposed to a normal driver.
thanks to point to the links , will check out the examples,