FreeRTOS任务通知
FreeRTOS在每创建一个任务时,在任务控制块TCB中有一个32位的通知值成员变量ulNotifiedValue和一个表示状态的成员变量ucNotifyState。假如某个任务通知的接收任务因为等待任务通知而阻塞的话,向这个接收任务发送任务通知以后就会解除这个任务的阻塞状态。
使用任务通知比起创建队列、二进制信号量、计算信号量或事件组速度更快、占用的RAM更小。但是也有一些限制:
只能有一个任务接收通知事件。
接收任务可以因为接收任务通知而进入阻塞态,但是发送任务不会因为任务通知发送失败而阻塞。
1、发送通知-方法1
1.1、函数描述
xTaskNotifyGive( xTaskToNotify )
可以使用该API函数代替二进制或计数信号量,但是速度更快。在这种情况下,使用函数ulTaskNotifyTake来等待通知。
1.2、参数描述
xTaskToNotify—被通知的任务句柄。
2、获取通知-方法1
2.1、函数描述
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
ulTaskNotifyTake是专门为使用更轻量级更快的方法来代替二进制或计数信号量定制的。
API函数ulTaskNotifyTake有2种方法处理任务通知值:一种方法是在函数退出时将通知值清零,这种方法适用于实现二进制信号量;另一种方法是在函数退出时将通知值减1,这种方法用于实现计数信号量,选择哪种方法有参数 xClearCountOnExit 决定。
2.2、参数描述
xClearCountOnExit—如果为pdFALSE,则在函数退出时将通知值减1;如果为pdTRUE,则函数退出时将通知值清零。
xTicksToWait—因等待通知而进入阻塞状态的最大时间。
3、发送通知-方法2
3.1、函数描述
xTaskNotify( xTaskToNotify, ulValue, eAction )
这是一个宏,向指定任务发送通知值,通知值由ulValue和eAction参数共同决定,源码如下:
switch( eAction )
{
case eSetBits :
pxTCB->ulNotifiedValue |= ulValue;
break;
case eIncrement :
( pxTCB->ulNotifiedValue )++;
break;
case eSetValueWithOverwrite :
pxTCB->ulNotifiedValue = ulValue;
break;
case eSetValueWithoutOverwrite :
if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )
{
pxTCB->ulNotifiedValue = ulValue;
}
else
{
/* The value could not be written to the task. */
xReturn = pdFAIL;
}
break;
case eNoAction:
/* The task is being notified without its notify value being
updated. */
break;
}
3.2参数描述
xTaskToNotify—被通知的任务句柄。
ulValue—通知更新值。
eAction—枚举类型,指明更新通知值的方法。
3.3、返回值
参数eAction为eSetValueWithoutOverwrite时,如果被通知任务还没取走上一个通知,又接收到了一个通知,则这次通知值未能更新并返回pdFALSE,否则返回pdPASS。
4、获取通知-方法2
4.1、函数描述
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
4.2、参数描述
ulBitsToClearOnEntry—在使用通知之前,先将任务通知值进行如下操作:
pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;
ulBitsToClearOnExit—在函数退出前,将任务通知值进行如下操作:
pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;
pulNotificationValue—向外回传任务通知值。
xTicksToWait—因等待通知而进入阻塞状态的最大时间。
4.3、返回值
如果接收到通知,返回pdTRUE,如果API函数xTaskNotifyWait()等待超时,返回pdFALSE。