xTaskNotifyGive() lets tasks signal each other quickly and simply, like passing a small note to say 'I'm done' or 'Go ahead'. It works like a lightweight semaphore to control access or sync tasks without heavy overhead.
xTaskNotifyGive() as lightweight semaphore in FreeRTOS
void xTaskNotifyGive(TaskHandle_t xTaskToNotify);
xTaskToNotify is the handle of the task you want to notify.
This function sends a notification that increments the notified task's notification value by 1.
xTaskHandle that an event occurred.xTaskNotifyGive(xTaskHandle);
xTaskNotifyGiveFromISR(xTaskHandle, &xHigherPriorityTaskWoken);
This program creates two tasks. Task 1 does some work, then notifies Task 2 using xTaskNotifyGive(). Task 2 waits for this notification using ulTaskNotifyTake() and runs when notified. This shows how xTaskNotifyGive() acts like a lightweight semaphore to sync tasks.
#include "FreeRTOS.h" #include "task.h" #include <stdio.h> TaskHandle_t xTask1Handle = NULL; TaskHandle_t xTask2Handle = NULL; void vTask1(void *pvParameters) { while (1) { printf("Task 1: Doing work...\n"); vTaskDelay(pdMS_TO_TICKS(1000)); printf("Task 1: Notifying Task 2\n"); xTaskNotifyGive(xTask2Handle); // Signal Task 2 } } void vTask2(void *pvParameters) { while (1) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // Wait for notification printf("Task 2: Received notification, running...\n"); } } int main(void) { xTaskCreate(vTask1, "Task1", 1000, NULL, 1, &xTask1Handle); xTaskCreate(vTask2, "Task2", 1000, NULL, 1, &xTask2Handle); vTaskStartScheduler(); return 0; }
ulTaskNotifyTake() is used by the receiving task to wait for the notification and optionally clear it.
This method is lighter and faster than traditional semaphores but only supports one notification count per task.
Use xTaskNotifyGiveFromISR() if notifying from an interrupt.
xTaskNotifyGive() sends a simple signal from one task to another.
It works like a lightweight semaphore to sync tasks with less overhead.
Use ulTaskNotifyTake() to wait for the signal and continue work.