0
0
FreeRTOSprogramming~5 mins

xTaskNotifyGive() as lightweight semaphore in FreeRTOS

Choose your learning style9 modes available
Introduction

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.

When one task needs to tell another task that some work is finished.
When you want to control access to a shared resource without using full semaphores.
When you want a simple way to count events or signals between tasks.
When you want faster task synchronization with less memory use.
When you want to avoid complex semaphore setup but still need task coordination.
Syntax
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.

Examples
Notify the task identified by xTaskHandle that an event occurred.
FreeRTOS
xTaskNotifyGive(xTaskHandle);
Notify a task from an interrupt service routine (ISR), with a flag to request a context switch if needed.
FreeRTOS
xTaskNotifyGiveFromISR(xTaskHandle, &xHigherPriorityTaskWoken);
Sample Program

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.

FreeRTOS
#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;
}
OutputSuccess
Important Notes

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.

Summary

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.