(101)
c
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) //tasks.c 2790
{
TCB_t * pxUnblockedTCB;
BaseType_t xReturn; // 本函数的返回值,表示是否要进行任务切换
//此函数必须在临界区调用。它也可以从中断服务程序(ISR)内的临界区调用。
//事件列表按优先级排序,因此列表中的第一个可以被移除,因为它被认为是最高优先级。
//从延迟列表中移除 TCB,并将其添加到就绪列表中。
//如果某个事件对应的队列处于锁定状态,则该函数永远不会被调用--队列上的锁计数会被修改。
//这意味着在此处对事件列表的独占访问得到了保证。此函数假设已检查过 pxEventList 不为空。
pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
configASSERT( pxUnblockedTCB );
listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) );
if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) // 调度器没有被挂起,全局变量
{
listREMOVE_ITEM( &( pxUnblockedTCB->xStateListItem ) );
prvAddTaskToReadyList( pxUnblockedTCB );
//#define configUSE_TICKLESS_IDLE 0
/* 1: 使能tickless低功耗模式, 默认: 0 */ // 默认不使能低功耗模式
// 主动把这个心跳关掉,让 CPU 安心睡个长觉,不被 tick 频繁吵醒。所以是暂时关闭 tick 计数
#if ( configUSE_TICKLESS_IDLE != 0 )
{
//如果任务在内核对象上被阻塞,则 xNextTaskUnblockTime 可能会被设置为该阻塞任务的超时时间。
//如果任务因超时以外的原因被解除阻塞,通常不会更改 xNextTaskUnblockTime,
// 因为当滴答计数等于xNextTaskUnblockTime 时,它会自动重置为新的值。
//然而,如果使用无滴答空闲模式,尽早进入睡眠模式可能更为重要一因此在此处重置 xNextTaskUnblockTime,
// 以确保它在最早可能的时间更新。
prvResetNextTaskUnblockTime(); //此函数更新下一次要唤醒的时刻,记录于下面
}
#endif
}
else // 因为调度器挂起,把刚删除下来的任务节点,插入到全局待就绪链表 xPendingReadyList
{ // 延迟和就绪列表无法访问,因此请将此任务挂起,直至调度器恢复。
/* The delayed and ready lists cannot be accessed, so hold this task pending until the scheduler is resumed. */
listINSERT_END( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
}
if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
{
//如果从事件列表中移除的任务优先级高于调用任务,则返回 true。这使得调用任务能够知道是否应立即强制上下文切换。
xReturn = pdTRUE;
//标记一个等待的 yield,以防用户未使用"xHigherPriorityTaskWoken"参数调用 ISR 安全的 FreeRTOS 函数。
xYieldPending = pdTRUE; // 这是全局变量
}
else
xReturn = pdFALSE;
return xReturn;
}
++ 被上面调用 :
c
static void prvResetNextTaskUnblockTime( void )
{ // xNextTaskUnblockTime 是全局变量
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) // 判定链表为空, is empty
xNextTaskUnblockTime = portMAX_DELAY; // portMAX_DELAY = ( TickType_t ) 0xffffffffUL
else
//新的当前延迟列表不为空,获取延迟列表头部项的值。这是延迟列表头部任务应从阻塞状态移除的时间.
xNextTaskUnblockTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxDelayedTaskList );
}
(102)
谢谢