ulTaskNotifyTake() helps a task wait for a signal or event from another task or interrupt. It makes tasks sleep until something important happens.
ulTaskNotifyTake() for binary/counting notification in FreeRTOS
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait);
xClearCountOnExit: Use 1 (pdTRUE) to reset the notification count to zero after taking it (binary behavior). Use 0 (pdFALSE) to keep counting notifications (counting behavior).
xTicksToWait: How long the task waits if no notification is available. Use portMAX_DELAY to wait forever.
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
ulTaskNotifyTake(pdFALSE, 100);This program creates two tasks. The sender sends three notifications with 500ms delay each. The receiver waits and counts notifications using ulTaskNotifyTake() in counting mode (xClearCountOnExit = pdFALSE). It prints how many notifications it got each time. When it receives all three, it stops.
#include "FreeRTOS.h" #include "task.h" #include <stdio.h> TaskHandle_t xTaskHandle = NULL; void vSenderTask(void *pvParameters) { for (int i = 1; i <= 3; i++) { vTaskDelay(pdMS_TO_TICKS(500)); xTaskNotifyGive(xTaskHandle); // Send notification printf("Sender: Notification %d sent\n", i); } vTaskDelete(NULL); } void vReceiverTask(void *pvParameters) { uint32_t ulCount; uint32_t ulTotalCount = 0; while (1) { ulCount = ulTaskNotifyTake(pdFALSE, portMAX_DELAY); // Counting mode printf("Receiver: Got %lu notifications\n", ulCount); ulTotalCount += ulCount; if (ulTotalCount >= 3) { printf("Receiver: Received all notifications, exiting.\n"); break; } } vTaskDelete(NULL); } int main(void) { xTaskCreate(vReceiverTask, "Receiver", 1000, NULL, 2, &xTaskHandle); xTaskCreate(vSenderTask, "Sender", 1000, NULL, 2, NULL); vTaskStartScheduler(); return 0; }
ulTaskNotifyTake() returns the number of notifications received since last call if counting mode is used.
Use pdTRUE for binary notification to clear count after taking it.
ulTaskNotifyTake() is efficient and lightweight compared to semaphores.
ulTaskNotifyTake() lets a task wait for notifications from other tasks or interrupts.
Use xClearCountOnExit = pdTRUE for binary (single) notification, pdFALSE for counting multiple notifications.
It helps tasks sleep and save CPU until something important happens.