vTaskDelete 的作用
以下是添加了详细中文注释的 vTaskDelete函数,逐段解释其逻辑和关键操作:
函数定义与变量声明
void vTaskDelete(TaskHandle_t xTaskToDelete)
{TCB_t *pxTCB; // 指向任务控制块(TCB)的指针功能:删除指定的FreeRTOS任务。
参数:
xTaskToDelete:要删除的任务句柄(若为NULL则删除当前任务)。
进入临界区
taskENTER_CRITICAL(); // 进入临界区,防止任务调度干扰{作用:保护任务删除操作的原子性。
获取任务TCB
/* 若参数为NULL,则删除当前正在运行的任务 */pxTCB = prvGetTCBFromHandle(xTaskToDelete);关键点:
prvGetTCBFromHandle:将任务句柄转换为TCB结构体指针。若传入
NULL,内部会自动获取当前任务的TCB。
从就绪/阻塞列表中移除任务
/* 将任务从就绪/阻塞列表中移除 */if (uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0){taskRESET_READY_PRIORITY(pxTCB->uxPriority); // 若该优先级无其他任务,清除就绪位}else{mtCOVERAGE_TEST_MARKER(); // 覆盖率测试标记(无实际代码)}逻辑:
uxListRemove:从列表移除任务,返回剩余任务数。若返回0,表示该优先级无其他就绪任务,需重置优先级位图。
检查事件等待列表
/* 检查任务是否在等待事件(如信号量、队列) */if (listLIST_ITEM_CONTAINER(&(pxTCB->xEventListItem)) != NULL){(void)uxListRemove(&(pxTCB->xEventListItem)); // 从事件列表中移除}else{mtCOVERAGE_TEST_MARKER();}作用:确保任务不会因删除导致事件列表出现悬空指针。
更新任务编号
/* 递增任务编号,便于调试工具检测任务列表变化 */uxTaskNumber++;用途:内核感知型调试器可通过此值判断任务列表是否需要刷新。
处理当前任务自删除
if (pxTCB == pxCurrentTCB) // 如果是当前任务删除自身{/* 将任务TCB插入终止列表,由空闲任务负责内存回收 */vListInsertEnd(&xTasksWaitingTermination, &(pxTCB->xStateListItem));/* 通知空闲任务有任务待清理 */++uxDeletedTasksWaitingCleanUp;/* 调用跟踪钩子函数(用于调试) */traceTASK_DELETE(pxTCB);/* 平台特定的删除前钩子(如Windows模拟器清理) */portPRE_TASK_DELETE_HOOK(pxTCB, &xYieldPending);}关键流程:
自删除任务无法立即释放资源(需切换上下文)。
将TCB放入终止列表,由空闲任务异步回收内存。
钩子函数用于平台特定清理(如模拟器环境)。
处理其他任务删除
else // 删除其他任务{--uxCurrentNumberOfTasks; // 更新全局任务计数器traceTASK_DELETE(pxTCB); // 调试跟踪prvDeleteTCB(pxTCB); // 直接释放TCB和栈内存/* 重置下一个任务解除阻塞时间(避免引用已删除任务) */prvResetNextTaskUnblockTime();}区别:
非自删除任务可直接同步释放资源。
需检查并更新调度器的时间基准。
退出临界区
}taskEXIT_CRITICAL(); // 退出临界区作用:恢复中断和任务调度。
触发任务调度
/* 若删除的是当前任务且调度器已启动,强制触发上下文切换 */if (xSchedulerRunning != pdFALSE){if (pxTCB == pxCurrentTCB) // 自删除场景{configASSERT(uxSchedulerSuspended == 0); // 确保调度器未挂起portYIELD_WITHIN_API(); // 主动让出CPU}else{mtCOVERAGE_TEST_MARKER();}}
}关键点:
自删除任务必须立即切换上下文,否则会继续执行非法内存。
portYIELD_WITHIN_API:触发调度器选择下一个就绪任务。
总结流程图
开始│├─ 进入临界区│ ├─ 获取TCB│ ├─ 从就绪/阻塞列表移除│ ├─ 从事件列表移除(若存在)│ ││ ├─ 如果是自删除任务:│ │ ├─ 加入终止列表│ │ ├─ 通知空闲任务清理│ │ └─ 调用平台钩子│ ││ └─ 如果是其他任务:│ ├─ 释放TCB内存│ └─ 重置解除阻塞时间│└─ 退出临界区│└─ 若自删除且调度器运行:└─ 强制上下文切换
结束注意事项
内存安全:
自删除任务的栈和TCB由空闲任务回收,需确保空闲任务有执行机会。
资源泄漏:
任务删除前应释放其占用的所有资源(如动态内存、外设句柄)。
实时性:
在中断中调用时,需使用
xTaskDeleteFromISR并处理上下文切换请求。
