Hint: Use the tree menu to navigate groups of related pages
FreeRTOS Support Archive
The FreeRTOS support forum can be used for active support both from Amazon Web Services and the community. In return for using our software for free, we request you play fair and do your bit to help others! Sign up to receive notifications of new support topics then help where you can.
This is a read-only archive of threads posted to the FreeRTOS support forum. The archive is updated every week, so will not always contain the very latest posts. Use these archive pages to search previous posts. Use the Live FreeRTOS Forum link to reply to a post, or start a new support thread.
I’ve done research for my next project, which is a modern version of an existing system. This system relies heavily on events. It seems that FreeRTOS would be the right choice for the project, even though it lacks this crucial feature. So, if/since I’m going to use FreeRTOS, I need to implement events. I haven’t programmed with FreeROTS before, so I’m asking your views and suggestions about the best approach for this task.
To clarify what I mean by events: An event is a global notice of something. For example, when a monitoring task signals an event that a status have changed, it shouldn’t be concerned about what tasks are running that might be interested about such notice, it just signals the event. The other tasks (logging, user interface, network interface, debug utilities, …) take notice about the event if they are interested and do appropriate action. The current system also uses events for commands. For example, for a control tasks its irrelevant where the command event to toggle a switch came from (network, debug window, user interface, remote user interface…), it just handles the switch. But maybe there is a better mechanism for this functionality inside FreeRTOS already?
I guess there would be a event handler task, that the other tasks communicate somehow. This task has knowledge about tasks that would be sending and receiving events, and would distribute events accordingly, using queues, I suppose. It seems that there isn’t much else to do than copying event messages to listeners and handling issues about what tasks are active at any given time.
Please comment with your views, practicality, what mechanisms would you use etc. Also, I would appreciate pointers if there is already something like this implemented.
> I’ve done research for my next project, which is a modern
> version of an existing
> system. This system relies heavily on events. It seems that
> FreeRTOS would be
> the right choice for the project, even though it lacks this
> crucial feature.
Not necessarily. There is no universal definition of an ‘event’ and often just a semaphore is sufficient. FreeRTOS supports events in the sence that mechanisms exist for interrupts to unblock tasks when an ‘event’ occurs. There are some sorts of events that it doesn’t support, the reasons for which I will describe below.
> So, if/since I’m going to use FreeRTOS, I need to implement
> events. I haven’t
> programmed with FreeROTS before, so I’m asking your views and
> about the best approach for this task.
> To clarify what I mean by events:
An excellent place to start :o)
> An event is a global notice
> of something.
> For example, when a monitoring task signals an event that a
> status have changed,
> it shouldn’t be concerned about what tasks are running that
> might be interested
> about such notice, it just signals the event. The other tasks
> (logging, user
> interface, network interface, debug utilities, …) take
> notice about the event
> if they are interested and do appropriate action.
Ok, so this is a very limited definition.
Some systems implement event flags (basically integers) whereby a task can choose to unblock when a combination of bits are set. For example Bit0 && Bit1 && !Bit30, or as another example Bit2 || Bit4. The problem with this type of scheme is the efficiency of its implementation. To elaborate, say you have three tasks that are all blocked on the same event flag and something changes a bit in the flag, the scheduler would then have to walk a list of tasks and inspect the unblock requirements of each. There are two problems with this – first this type of operation is going to require some form of mutual exclusion and FreeRTOS attempts to never walk a list (a potentially lengthy operation) from a critical section – second who takes responsibility for clearing a bit in a flag once the bit has caused a task to unblock? There may be other tasks waiting for the same bit but in a different combination.
I think the most important thing in your definition here is the use of the word ‘global’. Am I right to think then that your ‘event’ is simply binary (a single bit in a flag if you like)? If so and only one task will block on the event at a time then you can use any of the queue or semaphore implementations that already exist to achieve your goal. If you want more than one task to block on the same event at the same time then half of what you need is already implemented – you can have multiple tasks block on the same queue/semaphore already but only one will automatically get unblocked when the event occurs. This can be cured by using a loop to unblcok all tasks, but again be careful about critical sections that are too long.
> The current
> system also uses
> events for commands. For example, for a control tasks its
> irrelevant where the
> command event to toggle a switch came from (network, debug
> window, user interface,
> remote user interface…), it just handles the switch. But
> maybe there is a
> better mechanism for this functionality inside FreeRTOS already?
FreeRTOS can do this already and it’s a very common technique. Any number of tasks can write to a single queue and any number of tasks can read from a single queue (although usful applications of the latter are rare). You can have a controller task that receives updates to set points, etc. on a queue from any number of places – HMI, CAN bus, Ethernet, etc. – it doesn’t care. Use the queue to send a structure that contains both the meaning of the data and the new value for the data (and the source if that is relevant).
> I guess there would be a event handler task, that the other
> tasks communicate
> somehow. This task has knowledge about tasks that would be
> sending and receiving
> events, and would distribute events accordingly, using
> queues, I suppose. It
> seems that there isn’t much else to do than copying event
> messages to listeners
> and handling issues about what tasks are active at any given time.
Using a task to do this could get around some of the mutual exclusion issues, but has the overhead of having another task.
I would suggest a look at Quantum Leaps (http://www.state-machine.com/index.htm) which offers an open source event processing framework, and a view on how to achieve such a framework. It can apparently cooperate with FreeRTOS, although I haven’t yet tried it.
The author (Miro Samek) also wrote a book Practical UML Statecharts in C/C++ (Newnes) which demonstrate the ideas behind his event framework.