#if( configUSE_TASK_NOTIFICATIONS == 1 )
//给任务发送任务通知
//参数为: xTaskToNotify:任务句柄 ulValue:任务通知值 eAction:任务通知更新方式 *pulPreviousNotificationValue:保存更新前的任务通知值
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有效,说明需要保存更新前的任务通知值
{
*pulPreviousNotificationValue = pxTCB->ulNotifiedValue; //保存更新前的任务通知值
}
ucOriginalNotifyState = pxTCB->ucNotifyState; //保存任务通知状态到ucOriginalNotifyState中,后面要用到
pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; //修改目前任务通知状态为taskNOTIFICATION_RECEIVED
switch( eAction ) //eAction为任务通知更新方式
{
case eSetBits : //如果为eSetBits的话:更新接受任务通知值的一个或多个bit
pxTCB->ulNotifiedValue |= ulValue;
break;
case eIncrement : //如果是eIncrement的话:就将任务通知值加一
( pxTCB->ulNotifiedValue )++;
break;
case eSetValueWithOverwrite : //如果是eSetValueWithOverwrite的话:覆盖原来的任务通知值
pxTCB->ulNotifiedValue = ulValue;
break;
case eSetValueWithoutOverwrite : //如果是eSetValueWithoutOverwrite的话:判断原来的任务通知值是否被处理,如果已经被处理了就更新为任务通知值
//如果此前的任务通知值话没有被处理的话就标记xRenturn为pdFAIL
if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) //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;
}
traceTASK_NOTIFY(); //退出临界区
/* If the task is in the blocked state specifically to wait for a
notification then unblock it now. */
if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) //根据保存的任务通知状态来判断此任务是不是因为等待而阻塞
{
( void ) uxListRemove( &( pxTCB->xStateListItem ) ); //将阻塞的任务从状态列表中移除
prvAddTaskToReadyList( pxTCB ); //将任务添加到就绪列表中
/* The task should not have been on an event list. */
configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
#if( configUSE_TICKLESS_IDLE != 0 )
{
/* If a task is blocked waiting for a notification then
xNextTaskUnblockTime might be set to the blocked task's time
out time. If the task is unblocked for a reason other than
a timeout xNextTaskUnblockTime is normally left unchanged,
because it will automatically get reset to a new value when
the tick count equals xNextTaskUnblockTime. However if
tickless idling is used it might be more important to enter
sleep mode at the earliest possible time - so reset
xNextTaskUnblockTime here to ensure it is updated at the
earliest possible time. */
prvResetNextTaskUnblockTime();
}
#endif
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) //如果此任务的优先级比当前正在运行的任务优先级高就进行任务切换
{
/* The notified task has a priority above the currently
executing task so a yield is required. */
taskYIELD_IF_USING_PREEMPTION(); //进行任务切换
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else //如果此任务并没有阻塞就继续
{
mtCOVERAGE_TEST_MARKER();
}
}
taskEXIT_CRITICAL(); //退出临界区
return xReturn;
}
#endif /* configUSE_TASK_NOTIFICATIONS */
任务通知发送函数xTaskGenericNotify详解
最新推荐文章于 2024-05-18 17:08:17 发布