FreeRTOS学习笔记——任务删除 vTaskDelete() API

任务可以使用API函数 vTaskDelete() 删除自己或其他任务。

空闲任务的责任是要将分配给已删除任务的内存释放掉。注意:只有内核为任务分配的内存空间才会在任务被删除后自动回收,任务自己占用的内存或资源需要由应用程序自己显式地释放。

         void vTaskDelete( xTaskHandle pxTaskToDelete );

其中pxTaskToDelete 被删除任务的句柄(目标任务) 。可参照创建任务时使用 FreeRTOS 的API 函数xTaskCreate(),

portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,
const signed portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pxCreatedTask ); 

 其中pxCreatedTask    用于传出任务的句柄。这个句柄将在API 调用中对该创建出来的任务进行引用,比如改变任 务优先级,或者删除任务。如果应用程序中不会用到这个任务的句柄,则pxCreatedTask 可以被设为NULL。

任务可以通过传入NULL值来删除自己。

例程如下:

/* main() 函数实现 */

int main( void )
{
/* 任务1创建在优先级1上 */

xTaskCreate( vTask1, "Task 1", 1000, NULL, 1, NULL );

/* 任务1以优先级 1创建 */

/* 开启任务调度器,执行任务1 */
vTaskStartScheduler();

/* main() should never reach here as the scheduler has been started. */
for( ;; );
}


/*任务1 代码*/

void vTask1( void *pvParameters )
{
const portTickType xDelay100ms = 100 / portTICK_RATE_MS; /*当前的每个tick的MS值为100*/
for( ;; )
{

/* Print out the name of this task. */

vPrintString( "Task1 is running\r\n" );

/* 创建任务2为最高优先级。 */

xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, &xTask2Handle );   /* 最后一个参数为任务句柄 */

/* 因为任务2具有最高优先级,所以任务1运行到这里时,任务2已经完成执行,删除了自己。任务1得以

执行,延迟100ms阻塞一段时间 */

vTaskDelay( xDelay100ms );  /*此时任务1进入阻塞状态,空闲任务得到执行机会,空闲任务会释放内核为已删除的任务2分配的内存*/

}
}


任务 1 离开阻塞态后,再一次成为就绪态中具有最高优先级的任务,因此会抢占
空闲任务。又再一次创建任务2,如此往复。


void vTask2( void *pvParameters )
{

/* 任务2什么也没做,只是删除自己。删除自己可以传入NULL值,这里为了演示,还是传入其自己的句柄。 */

vPrintString( "Task2 is running and about to delete itself\r\n" );
vTaskDelete( xTask2Handle );
}



附:FreeRTOS关于vTaskDelete()的源码:

void vTaskDelete( xTaskHandle pxTaskToDelete )

{

    tskTCB *pxTCB;

    taskENTER_CRITICAL();

    {

        if( pxTaskToDelete == pxCurrentTCB )

        {

            pxTaskToDelete = NULL; /*任务通过传入NULL值来删除自己*/

        }

        pxTCB = prvGetTCBFromHandle( pxTaskToDelete );


        vListRemove( &( pxTCB->xGenericListItem ) );/* 将任务从就绪链表中删除 */


        if( pxTCB->xEventListItem.pvContainer ) /* 检查任务是否等待任何事件 */

        {

            vListRemove( &( pxTCB->xEventListItem ) );/* 将任务从事件链表中删除 */

        }

/*将任务添加到终止链表中,Idle 任务会将其真正删除(prvCheckTasksWaitingTermination) */

        vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );

        

        ++uxTasksDeleted;/* Idle 任务根据这个变量知道有需要删除的任务 */


        /* 通知 kernel aware debuggers 更新任务列表. */

        uxTaskNumber++; /* 这里似乎应该是 uxTaskNumber--; */


        traceTASK_DELETE( pxTCB );

    }

    taskEXIT_CRITICAL();


    /* 如果删除的是当前任务,则需要任务调度 */

    if( xSchedulerRunning != pdFALSE )

    {

        if( ( void * ) pxTaskToDelete == NULL )

        {

            portYIELD_WITHIN_API();

        }

    }

}

你可能感兴趣的:(学习笔记)