《FreeRTOS任务删除篇》

  1. 介绍FreeRTOS任务删除函数的执行过程,逐行分析源代码。
  2. 要使用任务删除函数vTaskDelete,需要配置宏INCLUDE_vTaskDelete为1。
  3. 删除任务函数vTaskDelete的参数为待删除任务的任务句柄(即任务控制块)。
  4. 当函数参数为NULL时,代表删除的是调用函数的任务本身(即正在运行的任务)。

源码

/* 示例,在正在运行的任务中调用任务删除函数。*/
vTaskDelete(NULL); 
/* 任务删除 */
#if ( INCLUDE_vTaskDelete == 1 ) /* 需要INCLUDE_vTaskDelete宏配置为1 */

    void vTaskDelete( TaskHandle_t xTaskToDelete ) /* 函数参数为待删除任务的任务句柄,可以用NULL代替当前任务句柄。 */
    {
   
        TCB_t * pxTCB;

        taskENTER_CRITICAL(); /* 进入临界区,本质是关闭全局中断。 */
        {
   
            /* If null is passed in here then it is the calling task that is
             * being deleted.
             * 如果在此处传递NULL,则删除的是调用函数的任务本身。
             */
            pxTCB = prvGetTCBFromHandle( xTaskToDelete );

            /* Remove task from the ready/delayed list.
             * 从就绪/延迟列表中删除任务
             * 如果删除后列表中没有列表项,则uxListRemove返回0
             */
            /* 将任务控制块的成员状态列表项xStateListItem从列表中移除 */
            if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
            {
   
                taskRESET_READY_PRIORITY( pxTCB->uxPriority );
            }
            else
            {
   
                mtCOVERAGE_TEST_MARKER();
            }

            /* Is the task waiting on an event also?
             * 任务是否也在等待事件?
             * 任务控制块的成员xEventListItem是否挂载在其他列表中
             */
            if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
            {
   
                /* 将事件列表项从等待事件列表中移出 */
                ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
            }
            else
            {
   
                mtCOVERAGE_TEST_MARKER();
            }

            /* Increment the uxTaskNumber also so kernel aware debuggers can
             * detect that the task lists need re-generating.  This is done before
             * portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will
             * not return.
             * 同时自增uxTaskNumber,以便内核感知调试器可以检测到任务列表需要重新生成。
             * 这是在portPRE_TASK_DELETE_HOOK之前完成的,因为在Windows端口中,宏不会返回
             */
            uxTaskNumber++; /* 任务列表需要重新生成 */

            /* 删除的是调用任务本身时 */
            if( pxTCB == pxCurrentTCB )
            {
   
                /* A task is deleting itself.  This cannot complete within the
                 * task itself, as a context switch to another task is required.
                 * Place the task in the termination list.  The idle task will
                 * check the termination list and free up any memory allocated by
                 * the scheduler for the TCB and stack of the deleted task.
                 * 一个任务正在删除自己。
                 * 这无法在任务本身内完成,因为需要切换到另一个任务的上下文。
                 * 将任务放入等待结束列表中。
                 * 空闲任务将检查等待结束列表,并释放调度器为准备删除任务分配的TCB和堆栈内存。
                 */
                vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );

                /* Increment the ucTasksDeleted variable so the idle task knows
                 * there is a task that has been deleted and that it should therefore
                 * check the xTasksWaitingTermination list.
                 * 递增ucTasksDeleted变量,以便空闲任务知道有一个任务已被删除,
                 * 因此它应该检查xTasksWaitingTermination列表。
                 */
                ++uxDeletedTasksWaitingCleanUp;

                /* Call the delete hook before portPRE_TASK_DELETE_HOOK() as
                 * portPRE_TASK_DELETE_HOOK() does not return in the Win32 port.
                 * 在调用portPRE_TASK_delete_hook之前调用delete钩子,
                 * 因为portPRE_TAS K_delete_ hook在Win32端口中不返回。
                 */
                traceTASK_DELETE( pxTCB );

                /* The pre-delete hook is primarily for the Windows simulator,
                 * in which Windows specific clean up operations are performed,
                 * after which it is not possible to yield away from this task -
                 * hence xYieldPending is used to latch that a context switch is
                 * required.
                 * 预删除挂钩主要用于Windows模拟器,
                 * 在该模拟器中执行特定于Windows的清理操作,之后不可能放弃此任务,
                 * 因此xYieldPending用于锁定需要进行上下文切换。
                 */
                portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
            }
            else
            {
   
                --uxCurrentNumberOfTasks; /* 当前任务个数自减一 */
                traceTASK_DELETE( pxTCB );

                /* Reset the next expected unblock time in case it referred to
                 * the task that has just been deleted.
                 * 重置下一个预期的解锁时间,以防它引用了刚刚被删除的任务
                 */
                prvResetNextTaskUnblockTime()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值