FreeRTOS Deep Dive · Part 2 of 8

Task Notifications vs Event Groups

FreeRTOS STM32 Intermediate Source Code
FreeRTOS Part 2
FreeRTOS Deep Dive — Part 2
Task Notifications vs Event Groups
38:15
Part 2 / 8
38:15
Intermediate
FreeRTOS v10 · STM32F4
01

Overview

Task notifications are FreeRTOS's fastest, lightest signalling mechanism — 45% faster than a semaphore with zero extra RAM. Every task has a built-in 32-bit notification value. This part covers when notifications beat semaphores and event groups, and exactly how to use all four notification actions.

  • Understand the 32-bit notification value and its four action modes
  • Use ulTaskNotifyTake() as a zero-overhead binary or counting semaphore
  • Use xTaskNotifyWait() as a 32-flag event group without extra memory
  • Send notifications safely from ISRs with vTaskNotifyGiveFromISR()
02

Notification Actions

Increment
Increment the notification value. Acts as a counting semaphore Give with no overhead.
eIncrement
🚩
Set Bits
OR bits into the notification value — 32 independent event flags with no extra memory.
eSetBits
🔢
Set Value
Write a 32-bit value directly to the notification register. Receive it with xTaskNotifyWait.
eSetValueWithOverwrite
03

Code

01
ISR to Task — notification vs semaphore
notify_isr.c
C
TaskHandle_t xProcessHandle;

// ISR — notification is faster than xSemaphoreGiveFromISR
void EXTI0_IRQHandler(void) {
    BaseType_t xWoken = pdFALSE;
    vTaskNotifyGiveFromISR(xProcessHandle, &xWoken);
    portYIELD_FROM_ISR(xWoken);
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

// Task: ulTaskNotifyTake acts like a counting semaphore Take
void vProcessTask(void *pv) {
    while(1) {
        uint32_t n = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        ProcessEvents(n); // n = how many ISRs fired
    }
}

// Multi-flag events with xTaskNotifyWait
#define EVT_SENSOR  (1<<0)
#define EVT_UART    (1<<1)
#define EVT_BTN     (1<<2)

void vEventTask(void *pv) {
    uint32_t flags;
    while(1) {
        xTaskNotifyWait(0, 0xFFFFFFFF, &flags, portMAX_DELAY);
        if(flags & EVT_SENSOR) ReadSensor();
        if(flags & EVT_UART)   HandleUART();
        if(flags & EVT_BTN)    HandleButton();
    }
}
⚠️
Notifications are one-to-one only
A task notification targets a single specific task. For broadcast events to multiple tasks, use an Event Group. For data transfer, use a Queue.

Continue the Series

Work through all 8 parts of the FreeRTOS Deep Dive to master real-time embedded systems programming.