您的位置:首页 > 其它

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

2013-03-19 10:09 369 查看
任务可以使用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();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: