任务通知
FreeRTOS 从 V8.2.0 版本开始提供任务通知这个功能,每个任务都有一个 32 位的通知
值,在大多数情况下,任务通知可以替代二值信号量、计数信号量、事件组,也可以替代
长度为 1 的队列(可以保存一个 32位整数或指针值)。
简单版和复杂版使用的函数不一样,简单版可以替代一个二值信号量,复杂版可替代很多,关键在于xTaskNotify最后一个参数的设置
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
typedef enum { eNoAction = 0, /* Notify the task without updating its notify value. */ eSetBits, /* Set bits in the task's notification value. */ eIncrement, /* Increment the task's notification value. */ eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ } eNotifyAction;
参数 eAction 为 eSetValueWithoutOverwrite 时,如果被通知任务还没取走上一个通知,
又接收到了一个通知,则这次通知值未能更新并返回 pdFALSE,而其他情况均返回pdPASS。
下面是示例:
简单版
static void send_Task(void* pvParameters) { while(1) { xTaskNotifyGive(receive_Task_handle); //等待 接收任务 发通知 ulTaskNotifyTake( pdTRUE, portMAX_DELAY); printf("接收 receive_Task\n\r"); } } static void receive_Task(void* pvParameters) { while(1) { //等待 发送任务 发通知 ulTaskNotifyTake( pdTRUE, portMAX_DELAY); printf("接收 send_Task\n\r"); xTaskNotifyGive(send_Task_handle); vTaskDelay(1000); } }
复杂版
static void send_Task(void* pvParameters) { uint32_t va = 0; while(1) { //最后一个参数设置很重要 if(xTaskNotify(receive_Task_handle, va, eSetValueWithOverwrite) == pdTRUE) va++; vTaskDelay(100); } } static void receive_Task(void* pvParameters) { uint32_t va=0; while(1) { xTaskNotifyWait( 0, 0 , &va, portMAX_DELAY); printf("接收到 %d\n\r",va); vTaskDelay(1000); } }