FreeRTOS provides several mechanisms for task and event synchronization, including semaphores, queues, and task notifications. Typically, each event would require a dedicated instance of one of these primitives. Coordinating multiple primitives to unblock a task can be difficult. For this reason, FreeRTOS supports a primitive called an EventGroup.
EventGroups support waiting on combinations of events (bitwise conditions), allowing tasks to block until one or more specified bits are set. Compared to other synchronization primitives, EventGroups offer greater flexibility and consume less SRAM.
Creating an Event Group
FreeRTOS provides the EventGroupHandle_t type to to access an Event Group. This handle is declared as a global variable which allows multiple tasks to access the same Event Group. An event Group is initialized using the xEventGroupCreate() function.
Defining Events
Each event in an Event Group is represented by a specific bit within the group. Designers define these bit-level events based on the system’s operational needs—determining which conditions require task synchronization or triggering. A single event group supports up to 24 unique events. Events within an event group can be defined using a macro. Each macro should be defined so that a single bit represents a single event. Let’s see how you would create macros for a system with 3 buttons. Each of these events will represent pressing one of the 3 buttons.
Because each event is represented by a single bit, this will allow for efficient bit masking to unblock tasks.
Setting an Event
When the firmware detects a hardware event—such as a button press, incoming UART data, or timer expiration—the associated task (or interrupt service routine) sets the corresponding bit in the Event Group using the xEventGroupsSetBits() function. This signals other tasks that an event of interest has occurred.
Parameters:
- The first parameter is the handle of the EventGroup.
- The second parameter is a bitmask of the event(s) that have been detected.
Waiting for One of Multiple Events
A FreeRTOS task can wait for one or more events using the xEventGroupWaitBits() function.
Function Parameters:
- Event Group Handle: The first parameter specifies the handle of the target Event Group.
- Bitmask: The second parameter is a bitmask representing the event(s) the task is waiting for.
- Clear on Exit: The third parameter tells FreeRTOS whether to clear the specified bits after the task is unblocked.
- Wait Condition: The fourth parameter determines if the task should unblock when any of the bits are set (logical OR) or all of them (logical AND).
- Timeout: The fifth parameter defines how long the task should wait for the specified event bits to be set.
Here is an example of a task that waits for any of the buttons to be pressed (logical OR).
Software can determine which events occurred by examining the bits that were returned using the same event bitmasks.
Waiting for All Events
This example shows how a task can wakeup when ALL the specified events have occurred (logical AND).