任务删除函数
- 介绍FreeRTOS任务删除函数的执行过程,逐行分析源代码。
- 要使用任务删除函数vTaskDelete,需要配置宏INCLUDE_vTaskDelete为1。
- 删除任务函数vTaskDelete的参数为待删除任务的任务句柄(即任务控制块)。
- 当函数参数为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()