#define xTaskNotifyGive( xTaskToNotify ) \
xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( 0 ), eIncrement, NULL )
#define xTaskNotifyGiveIndexed( xTaskToNotify, uxIndexToNotify ) \
xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( 0 ), eIncrement, NULL )
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, /* 要通知的任务的句柄 */
UBaseType_t uxIndexToNotify, /* 任务通知数组的索引值(任务通知相关数组下标,xTaskNotifyGive()默认为0,使用通知数组第一个元素) */
uint32_t ulValue, /* 要传递的通知值 */
eNotifyAction eAction, /* 指定通知的动作 */
uint32_t * pulPreviousNotificationValue ) /* 指向存储上一个通知值的变量的指针,如果不需要回传上一个通知值,则可以传递NULL */
{
TCB_t * pxTCB;
BaseType_t xReturn = pdPASS;
uint8_t ucOriginalNotifyState;
configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );
configASSERT( xTaskToNotify );
pxTCB = xTaskToNotify;
taskENTER_CRITICAL();
{
/* 判断是否需要通知前的通知值 */
if( pulPreviousNotificationValue != NULL )
{
/* 获取发送通知前的通知值 */
*pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ];
}
/* 记录发送通知前的任务通知状态 */
ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ];
/* 将负责接收直达任务通知的 TCB(任务控制块)中 的任务通知状态 设置为 已收到任务通知态 */
pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED;
switch( eAction )
{
/* 模拟事件组:将通知值的某些位置 1 */
case eSetBits:
pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue;
break;
/* 模拟计数型信号量:将通知值 + 1 */
case eIncrement:
( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++;
break;
/* 模拟队列:覆写通知值 */
case eSetValueWithOverwrite:
pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;
break;
/* 模拟队列:(不覆盖)写通知值 */
case eSetValueWithoutOverwrite:
/* 如果不处于收到任务通知状态,说明通知值已被读走,可以写入*/
if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )
{
pxTCB->ulNotifiedValue[ uxIndexToNotify ] = 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;
default:
/* Should not get here if all enums are handled. Artificially force an assert by testing a value the compiler can't assume is const. */
/*如果处理了所有枚举,则不应到达此处。通过测试编译器不能假定为常量的值来人为地强制断言*/
configASSERT( xTickCount == ( TickType_t ) 0 );
break;
}
traceTASK_NOTIFY( uxIndexToNotify );
/* If the task is in the blocked state specifically to wait for a notification then unblock it now. */
/*如果任务处于阻止状态,专门用于等待通知,则立即取消阻止*/
if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) /* 如果在此之前,任务因等待任务通知而被阻塞(该任务为等待通知状态),则现在解除阻塞 */
{
/* 将任务从所在任务状态链表(延时/挂起链表)中移出 */
listREMOVE_ITEM( &( 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. */
/*如果任务被阻止等待通知,则xNextTaskUnblockTime可能会设置为被阻止任务的超时时间。
如果由于超时以外的原因取消阻止任务,xNextTaskUnblockTime通常保持不变,因为当勾号计数等于xNextTTaskUnblocktime时,它将自动重置为新值。
然而,如果使用了无障碍空转,那么尽早进入睡眠模式可能更重要——因此,请在此处重置xNextTaskUnblockTime,以确保它在尽早更新*/
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(); /* 悬起 PendSV中断,准备进行任务切换 */
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
taskEXIT_CRITICAL();
return xReturn;
}
#endif /* configUSE_TASK_NOTIFICATIONS */
/*-----------------------------------------------------------*/
901-FreeRTOS202212‐xTaskNotifyGive() 与 xTaskNotifyGiveIndexed()函数
最新推荐文章于 2024-10-10 22:59:02 发布