1.1 xTaskGenericNotify()不带中断保护的发送通知API函数实际都是调用函数xTaskGenericNotify()实现的,我们看一下这个函数原型:
BaseType_t xTaskGenericNotify(
TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotificationValue )
- xTaskToNotify:被通知的任务句柄。
- ulValue:更新的通知值
- eAction:枚举类型,指明更新通知值的方法,枚举变量成员以及作用见表1-2所示。
- pulPreviousNotifyValue:回传未被更新的任务通知值。如果不需要回传未被更新的任务通知值,这里设置为NULL。
表1-2:eNotifyAction枚举成员以及作用
与入队操作相比较,发送通知API函数显得非常简单,整理后的源码如下所示:
BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue )
{
TCB_t * pxTCB;
BaseType_t xReturn = pdPASS;
uint8_t ucOriginalNotifyState;
configASSERT( xTaskToNotify );
pxTCB = ( TCB_t * ) xTaskToNotify;
taskENTER_CRITICAL();
{
if( pulPreviousNotificationValue != NULL )
{
/* 回传更新前的通知值*/
*pulPreviousNotificationValue = pxTCB->ulNotifiedValue;
}
ucOriginalNotifyState = pxTCB->ucNotifyState;
pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED;
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
{
/* 上次的通知值还未取走,本次通知值丢弃 */
xReturn = pdFAIL;
}
break;
case eNoAction:
/* 不需要更新通知值*/
break;
}
traceTASK_NOTIFY();
/* 如果被通知的任务因为等待通知而阻塞,现在将它解除阻塞 */
if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
{
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
prvAddTaskToReadyList( pxTCB );
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
{
/* 如果被通知的任务优先级高于当前任务,则触发PendSV中断,退出临界区后进行上下文切换T*/
taskYIELD_IF_USING_PREEMPTION();
}
}
}
taskEXIT_CRITICAL();
return xReturn;
}
函数的功能可以概括为:按照指定的方法更新通知值,如果被通知的任务处于阻塞状态,则将它解除阻塞,解除阻塞任务的优先级如果大于当前任务的优先级,则触发一次任务切换。
与释放信号量API函数相比,本函数少了很多调用子函数开销、少了很多判断、少了对事件列表的操作等等,确实是比释放信号量的实现要简洁的多。这也是有原因的,因为任务通知有它自己的局限性,并不能完全代替信号量。比如一个任务只能阻塞到一个通知上,如想要实现多个任务阻塞到同一个事件上,只能使用信号量了。也正是因为这种局限性,使得任务通知实现起来简单高效,并且大多数情况下,任务通知的方法就已经能解决问题了。
|