FreeRTos笔记(12c):从事件链表里删除节点 xTaskRemoveFromEventList、

(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)

谢谢

相关推荐
La Pulga17 小时前
【FreeRTOS源码学习笔记】任务延时列表
笔记·mcu·学习·嵌入式·freertos·实时操作系统
橘色的喵18 小时前
coact:让嵌入式事件处理更可控
freertos·rt-thread·事件驱动·coact
人邮异步社区2 天前
学习FreeRTOS推荐哪本书?
freertos·rtos·嵌入式固件工程师
La Pulga4 天前
【FreeRTOS源码学习笔记】空闲任务与阻塞延时
笔记·mcu·学习·嵌入式·freertos·实时操作系统
La Pulga5 天前
【FreeRTOS源码学习笔记】任务切换
单片机·mcu·学习·嵌入式·freertos·实时操作系统
La Pulga7 天前
【FreeRTOS源码学习笔记】链表的实现
数据结构·笔记·stm32·mcu·链表·嵌入式·freertos
La Pulga7 天前
【FreeRTOS源码学习笔记】任务创建
笔记·stm32·mcu·学习·嵌入式·freertos·实时操作系统
天吾cc12 天前
FreeRTOS 事件标志组
freertos
编码追梦人13 天前
基于 ESP32-S3 的便携式多参数环境监护仪设计:从硬件选型到 FreeRTOS 多任务落地
数据库·单片机·嵌入式硬件·mongodb·esp32·freertos·低功耗设计