| Event Group API Function | Description |
|---|---|
| xEventGroupCreate() | Create an event group using dynamic memory allocation |
| xEventGroupCreateStatic() | Create an event group using user-provided static memory |
| xEventGroupClearBits() | Clear specified event bits from an event group |
| xEventGroupClearBitsFromISR() | Request specified event bits to be cleared from an ISR |
| xEventGroupSetBits() | Set specified event bits in an event group |
| xEventGroupSetBitsFromISR() | Request specified event bits to be set from an ISR |
| xEventGroupGetBits() | Return the current event-bit value of an event group |
| xEventGroupGetBitsFromISR() | Return the current event-bit value from an ISR |
| xEventGroupWaitBits() | Block a task until specified event bits are set or a timeout occurs |
| xEventGroupSync() | Sets event bits and waits for all specified bits |
Event groups allow a task to wait in the blocked state for a combination of one of more events to occur. Event groups unblock all the tasks that were waiting for the same event, or combination of events, when the event occurs. Event groups reduce RAM usage by allowing us to replace multiple binary semaphores with a single event group.
- Synchronizing tasks
- Broadcasting events to multiple tasks
When configUSE_16_BIT_TICKS is set to 0, TickType_t is a 32-bit data type, so EventBits_t is also a 32-bit data type. A variable of type EventBits_t can store 24 event bits, while the upper 8 bits are reserved for internal use. Event bit 0 is stored in bit 0 of the variable, event bit 1 is stored in bit 1, and so on. For STM32 devices, an event group can therefore contain up to 24 usable event bits.

- An event group is a set of event flags
- An event flag is a boolean value (1 or 0) used to indicate whether an event has occurred or not
- An event flag is stored in a single bit and the state of all event flags can be stored in a single variable
xEventGroupCreate() dynamically allocates the required memory and creates a new event group. It returns an EventGroupHandle_t for use with other event-group functions, or NULL if memory allocation fails. This function is available only when configSUPPORT_DYNAMIC_ALLOCATION is enabled. When the event group is no longer needed, call vEventGroupDelete() to free the allocated memory.
EventGroupHandle_t xEventGroupCreate(void)
// ---------------------- Example ----------------------
EventGroupHandle_t xEventGroupHandler;
xEventGroupHandler = xEventGroupCreate();xEventGroupCreateStatic() creates an event group using memory supplied by the application rather than allocating memory from the FreeRTOS heap. The application must provide a StaticEventGroup_t variable that remains valid for the entire lifetime of the event group. This function is useful in systems that require deterministic memory usage or do not permit dynamic allocation, and it is available only when configSUPPORT_STATIC_ALLOCATION is enabled.
EventGroupHandle_t xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer)xEventGroupClearBits() clears one or more specified bits in an event group from task context. The bits are selected using a bit mask: each bit set to 1 in the mask is cleared, while all other bits remain unchanged. The function returns the event-group value before the bits were cleared, allowing the task to inspect the previous event state. It must not be called from an interrupt service routine.
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear)xEventGroupClearBitsFromISR() requests that one or more specified event bits be cleared from interrupt context. Because clearing event bits may unblock multiple waiting tasks, the operation is deferred to the FreeRTOS timer daemon task rather than performed directly within the ISR. The function returns pdPASS if the request is successfully posted to the timer command queue, or pdFAIL if the queue is full.
BaseType_t xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet)xEventGroupSetBits() sets one or more specified bits in an event group from task context. Tasks waiting for those bits are then evaluated and may be moved from the Blocked state to the Ready state. Multiple bits can be set simultaneously by combining them with the bitwise OR operator. The function returns the event-group value after the bits have been set and any automatically cleared bits have been processed.
EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet)
// ---------------------- Example ----------------------
#define EVENTBIT_0 (1 << 0)
#define EVENTBIT_1 (1 << 1)
#define EVENTBIT_2 (1 << 2)
#define EVENTBIT_ALL (EVENTBIT_0 | EVENTBIT_1 | EVENTBIT_2)
xEventGroupSetBits(xEventGroupHandler, EVENTBIT_1);
xEventGroupSetBits(xEventGroupHandler, EVENTBIT_2); xEventGroupSetBitsFromISR() requests that one or more event bits be set from an interrupt service routine. Because setting event bits may unblock multiple tasks and is not a constant-time operation, the request is deferred to the FreeRTOS timer daemon task. The xHigherPriorityTaskWoken parameter indicates whether processing the request may make a higher-priority task ready to run. The function returns pdPASS if the request is successfully posted to the timer command queue, or pdFAIL if the queue is full.
BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken)
// ---------------------- Example ----------------------
BaseType_t YieldRequired = pdFALSE;
BaseType_t xHigherPriorityTaskWoken;
YieldRequired = xEventGroupSetBitsFromISR(xEventGroupHandler,
EVENTBIT_0,
&xHigherPriorityTaskWoken);
if(YieldRequired != pdFAIL) {
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} xEventGroupGetBits() reads and returns the current value of an event group from task context without modifying any bits. The returned EventBits_t value can be tested with bit masks to determine which events are currently set. Because another task or interrupt may change the event group immediately afterward, the returned value should be treated as a snapshot of its state at the time of the call.
EventBits_t xEventGroupGetBits(EventGroupHandle_t xEventGroup)
// ---------------------- Example ----------------------
EventBits_t newValue;
newValue = xEventGroupGetBits(xEventGroupHandler);xEventGroupGetBitsFromISR() reads and returns the current value of an event group from interrupt context without modifying any bits. It provides an ISR-safe way to check which event conditions are currently set. Like xEventGroupGetBits(), the returned value is only a snapshot of the event group at the time of the call and may change immediately afterward.
EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup)xEventGroupWaitBits() allows a task to wait for one or more specified event bits. The task can be configured to unblock when either any requested bit is set or all requested bits are set. It can also automatically clear the matched bits before returning and wait indefinitely or for a specified timeout. The function returns the event-group value that caused the task to unblock, or the value present when the timeout expired.
EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
const TickType_t xTicksToWait)
// ---------------------- Example ----------------------
EventBits_t EventValue;
// This code blocks the current FreeRTOS task until all event bits
// specified by EVENTBIT_ALL are set
EventValue = xEventGroupWaitBits((EventGroupHandle_t) xEventGroupHandler,
(EventBits_t ) EVENTBIT_ALL,
(BaseType_t ) pdTRUE,
(BaseType_t ) pdTRUE,
(TickType_t ) portMAX_DELAY);
// This call blocks the current task until any bit defined in EVENTBIT_ALL becomes set,
// then clears the matched event bits and stores the previous event-group value in EventValue
EventValue = xEventGroupWaitBits((EventGroupHandle_t) xEventGroupHandler, // Event group to monitor
(EventBits_t ) EVENTBIT_ALL, // Bit mask to wait for
(BaseType_t ) pdTRUE, // Clear matched bits before returning
(BaseType_t ) pdFALSE, // Wait for ANY bit, not all bits
(TickType_t ) portMAX_DELAY); // Wait indefinitely xEventGroupSync() synchronizes multiple tasks at a common execution point. It atomically sets the event bits specified by uxBitsToSet, then blocks the calling task until all bits in uxBitsToWaitFor are set or the timeout expires. The function returns the event-group value that caused the task to unblock, allowing the task to determine whether synchronization was completed successfully.
EventBits_t xEventGroupSync(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait)
// ---------------------- Example ----------------------
#define TASK1_BIT (1UL << 0UL)
#define TASK2_BIT (1UL << 1UL)
#define TASK3_BIT (1UL << 2UL)
EventGroupHandle_t xEventGroup;
EventBits_t uxAllSyncBits = (TASK1_BIT | TASK2_BIT | TASK3_BIT);
xEventGroup = xEventGroupCreate();
void vTask1Task(void *pvParameters) {
EventBits_t uxReturn;
while(1) {
uxReturn = xEventGroupSync(xEventGroup, TASK1_BIT, uxAllSyncBits, portMAX_DELAY);
if( uxAllSyncBits == (uxReturn & uxAllSyncBits) ) {
// Do something
}
}
}
void vTask2Task(void *pvParameters) {
EventBits_t uxReturn;
while(1) {
uxReturn = xEventGroupSync(xEventGroup, TASK2_BIT, uxAllSyncBits, portMAX_DELAY);
if( uxAllSyncBits == (uxReturn & uxAllSyncBits) ) {
// Do something
}
}
}
void vTask3Task(void *pvParameters) {
EventBits_t uxReturn;
while(1) {
uxReturn = xEventGroupSync(xEventGroup, TASK3_BIT, uxAllSyncBits, portMAX_DELAY);
if( uxAllSyncBits == (uxReturn & uxAllSyncBits) ) {
// Do something
printf("All tasks set \r\n");
vTaskDelay(_200ms);
}
}
} Back to top of the page