Hi,
I will need to solve this problem: I will refresh HW (let’s say digital imputs) through ISR and than I need to wake up several task, which wait for this refresh. It seems to me, that using mutex/binary semaphor will result in waking up only for 1 (highest) task. Am I right?
I am also looking for a way to implement one-to-many and many-to-one
task synchronization. I guess it could be done with a combination of semaphores and event flags.
I am thinking about how to efficiently integrate event flags in FreeRTOS.
Richard, do you have any plans for this? Is something maybe already in the pipeline?
This is a topic that comes up here from time to time (as does ‘timers’, which is more appropriate for tick hooks).
There are two problems with talking about ‘events’:
- First there is no universal definition of what an ‘event’ is. People normally talk at cross purposes. People from a uCOS background will talk about events in the way uCOS does, but others will mean something completely different. For example, when porting a TCP/IP stack to FreeRTOS I was told it was impossible because FreeRTOS didn’t support ‘events’, but I found during the exercise that they thought an event was simple a way of one task signalling another, or an interrupt signalling a task. All that was needed was a binary semaphore!
- The second problem is, if you do mean events in the same way uCOS does then I have never found an implementation that was suitably efficient for inclusion in FreeRTOS. Nowhere in FreeRTOS are linked lists walked while interrupts are disabled, or from within interrupts for that matter.
It would be great to have an elaborate bitwise event mechanism, but its not going to happen soon. If you want to have multiple tasks signal one task then you can use a queue with multiple writers and a single reader - then pass a structure on the queue to say where the message came from or what the data it contains represents.
I understand that it is not quite easy to add new feature. But it seems to me that there is now “clever” workaroud for my project. As I wrote above, I need to signal from 1 ISR to unknown count of tasks. The finest way is to wait for event “HW updated”. So, could you write (shortly) what is according to you “the best way” with current FreeRTOS?
If I were to have an application that needed to send an “event” to many (possibly unknown number at compile time) tasks, what I would do was to have the interrupt use a single semaphore/queue to flag a distribution task, and each task that wants to be notified of the event register a semaphore/queue with that task. The distribution task waits for a signal from the interrupt, and passes it to the list of tasks that have registered they want to know of the interrupt. The distribution task should have a priority higher than any task that wants to be notified. Using a task avoids to distribute keeps down the length of time the system can’t see new interrupts.
How to store the list of tasks to be notified can be done a number of ways depending on how well you know how many tasks may need to be notified
Hi Richard,
so you think it is better to use special distribution task instead of handling several semaphores inside ISR, don’t you? I think (for simplicity) that handling a dynamic link list of binary semaphores (10 at maximum I asume) in ISR is possible, it will not take big long time, I hope.
Tomas
I agree with Richard, because the main requirement on any RTOS is its responsiveness. This depends on longest critical section. By distributting several semaphores from ISR you are increasing execution time of critical section, which affect whole system.
Having distribution task which runs on highest priority doen’t compromise RTOS responsiveness regardless of amount of semaphores to be distributed. Distribution task execution time will be almost the same as ISR (task has overhead for context switch, but it is not big). The drawback is that this solution is slightly more complicated than pure ISR. But it is also much more generic.
I personally prefer distribution task solution, but it is up to you which solution you will use.
Running the list in the ISR will “work”, assuming you can tolerate the additional interrupt latency in your system. If you do it in the ISR, since ISRs are critical sections, no other interrupt which needs to interface with FreeRTOS can occur (or none at all if your port doesn’t support interrupt nesting). Doing the distribution in a task allows you to get the interrupt back online faster. While the distribution task should have higher priority than all the tasks it is activating, it might be lower than some other very high priority task that might be triggered by another interrupt.
If the list of tasks really is no more than ten, and you can afford interrupts being down for a bit, your concept of doing it in the interrupt may be acceptable. One thought is if you really can put a hard upper limit that low, it may make more sense for the list of semaphores to be stored in a static array with a counter for how many elements there are instead of a linked list.