从之前学习的过程中,任务间通信是需要创建队列、二进制信号量、计数信号量或事件组,这些都需要消耗内核资源;
而任务通知就更为的灵活,按照官方说法,使用任务通知比通过信号量等 ICP 通信方式解除阻塞的任务要快 45%,并且更加省 RAM 内存空间(使用 GCC 编译器,-o2 优化级别),任务通知的使用无需创建队列。
configUSE_TASK_NOTIFICATIONS 1
几种方式
- (eSetValueWithoutOverwrite)发送通知给任务, 如果有通知未读,不覆盖通知值。
- (eSetValueWithOverwrite)发送通知给任务,直接覆盖通知值。
- (eSetBits)发送通知给任务,设置通知值的一个或者多个位 ,可以当做事件组来使用。
- (eIncrement)发送通知给任务,递增通知值,可以当做计数信号量使用。
- (eNoAction)对象任务接收任务通知,但是任务自身的任务通知值不更新,
限制
- 只能有一个任务接收通知消息,因为必须指定接收通知的任务。。
- 只有等待通知的任务可以被阻塞,发送通知的任务,在任何情况下都不会因为发
送失败而进入阻塞态。
函数
发送任务通知函数
xTaskNotifyGive( xTaskToNotify );/* 信号量*/
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,
BaseType_t *pxHigherPriorityTaskWoken);
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify,
uint32_t ulValue,/* 队列,最大四个字节*/
eNotifyAction eAction );/* 覆盖方式*/
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
BaseType_t *pxHigherPriorityTaskWoken );
BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotifyValue );/*eSetValueWithoutOverwrite,回传上一个通知值*/
BaseType_t xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotifyValue,
BaseType_t *pxHigherPriorityTaskWoken );
获取任务通知函数
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit,/*pdFALSE,减一;pdTURE,清零*/
TickType_t xTicksToWait );
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry,/*在使用前,根据值进行对应位清零*/
uint32_t ulBitsToClearOnExit,/*在退出前,根据值进行对应位清零*/
uint32_t *pulNotificationValue,/*保存接收到的通知值*/
TickType_t xTicksToWait );