每个任务都有一个32位的通知值,在创建任务时该值被初始化为零。 任务通知是直接发送到任务的事件,它可以解除对接收任务的阻塞,并可以选择更新接收任务的通知值。任务通知功能与信号量类似,但更简洁。
#include "freertos/task.h"
uint32_t ulTaskNotifyTake(
BaseType_t xClearCountOnExit, //pdTRUE:函数退出时将通知值清零 == 二值信号量; pdFALSE:函数退出时将通知值减1 == 计数信号量
TickType_t xTicksToWait );//等待时间
xTaskNotify()用于将事件直接发送到任务,可以选择以下列方式之一更新接收任务的通知值:
BaseType_t xTaskNotify(
TaskHandle_t xTaskToNotify,//任务句柄
uint32_t ulValue,//用于更新通知值,其解释方式取决于eAction参数得.
eNotifyAction eAction );
eAction 参数说明:
xTaskNotifyGive() 是一个宏,调用了 xTaskNotify() 函数并将 eAction 参数设置为 eIncrement(增量)
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );//任务句柄
BaseType_t xTaskNotifyWait(
uint32_t ulBitsToClearOnEntry,//函数等待前清除相应bit,0xffffffff (ULONG_MAX):将清除所有bit
uint32_t ulBitsToClearOnExit,//函数退出时清除相应bit,
uint32_t *pulNotificationValue,//通知值指针,通过该指针可获取通知值
TickType_t xTicksToWait );//等待时间
//返回值:pdTRUE : 接收到通知; pdFALSE: 超时
#include
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
int iCount = 100;
void mytask1(void *pvParameter)
{
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
for (int i = 0; i < 5; i++)
{
printf("task1: iCount = %d\n", iCount);
vTaskDelay(1000 / portTICK_PERIOD_MS);
iCount++;
}
vTaskDelete(NULL);
}
void mytask2(void *pvParameter)
{
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
for (int i = 0; i < 5; i++)
{
printf("task2: iCount = %d\n", iCount);
vTaskDelay(1000 / portTICK_PERIOD_MS);
iCount++;
}
vTaskDelete(NULL);
}
void app_main(void)
{
TaskHandle_t myTastHandle1 = NULL;
TaskHandle_t myTastHandle2 = NULL;
xTaskCreate(mytask1, "mytask1", 1024 * 5, NULL, 1, &myTastHandle1);
xTaskCreate(mytask2, "mytask2", 1024 * 5, NULL, 1, &myTastHandle2);
printf("app_main: Create task1 and task2 \n");
//通知任务1计算5s
xTaskNotifyGive(myTastHandle1);
vTaskDelay(10000 / portTICK_PERIOD_MS);
//通知任务2计算5s
xTaskNotifyGive(myTastHandle2);
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
效果
app_main: Create task1 and task2
task1: iCount = 100
task1: iCount = 101
task1: iCount = 102
task1: iCount = 103
task1: iCount = 104
task2: iCount = 105
task2: iCount = 106
task2: iCount = 107
task2: iCount = 108
task2: iCount = 109
#include
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#define Notify_0_BIT (1 << 0)
#define Notify_1_BIT (1 << 1)
#define Notify_2_BIT (1 << 2)
void mytask1(void *pvParameter)
{
uint32_t value;
printf("task1 start \n");
while (1)
{
xTaskNotifyWait(
0, //函数等待前清除相应bit,0xffffffff (ULONG_MAX):将清除所有bit
ULONG_MAX, //函数退出时清除相应bit,
&value, //通知值指针,通过该指针可获取通知值
portMAX_DELAY); //等待时间
if ((value & 0x01) != 0)
{
/* Bit 0 was set - process whichever event is represented by bit 0. */
printf("Bit 0 was set \n");
}
if ((value & 0x02) != 0)
{
/* Bit 1 was set - process whichever event is represented by bit 1. */
printf("Bit 1 was set \n");
}
if ((value & 0x04) != 0)
{
/* Bit 2 was set - process whichever event is represented by bit 2. */
printf("Bit 2 was set \n");
}
printf("----------------------\n");
}
}
void app_main(void)
{
TaskHandle_t myTastHandle1 = NULL;
xTaskCreate(mytask1, "mytask1", 1024 * 5, NULL, 1, &myTastHandle1);
//通知任务1计算5s
while (1)
{
vTaskDelay(5000 / portTICK_PERIOD_MS);
xTaskNotify(
myTastHandle1,
Notify_0_BIT | Notify_1_BIT | Notify_2_BIT, //用于更新通知值,其解释方式取决于eAction参数得.
eSetBits);
vTaskDelay(5000 / portTICK_PERIOD_MS);
xTaskNotify(
myTastHandle1,
Notify_0_BIT, //用于更新通知值,其解释方式取决于eAction参数得.
eSetBits);
vTaskDelay(5000 / portTICK_PERIOD_MS);
xTaskNotify(
myTastHandle1,
Notify_1_BIT, //用于更新通知值,其解释方式取决于eAction参数得.
eSetBits);
vTaskDelay(5000 / portTICK_PERIOD_MS);
xTaskNotify(
myTastHandle1,
Notify_2_BIT, //用于更新通知值,其解释方式取决于eAction参数得.
eSetBits);
}
}
效果
task1 start
Bit 0 was set
Bit 1 was set
Bit 2 was set
----------------------
Bit 0 was set
----------------------
Bit 1 was set
----------------------
Bit 2 was set
----------------------