在RTOS中,任务的删除通常使用vTaskDelete
函数来实现。这个函数的原型定义在task.h
中,其作用是从RTOS内核管理中移除一个任务,该任务将不再存在于任何就绪、阻塞、挂起或事件列表中。
怎么删除任务?举个不好的例子:
void vTaskDelete( TaskHandle_t xTaskToDelete );
自杀: vTaskDelete(NULL)
被杀:别的任务执行 vTaskDelete(pvTaskCode) ,pvTaskCode是自己的句柄
杀人:执行 vTaskDelete(pvTaskCode) ,pvTaskCode是别的任务的句柄
我们要做这些事情:
创建任务1:任务1的大循环里,创建任务2,然后休眠一段时间
任务2:打印一句话,然后就删除自己
任务1的代码如下:
void vTask1( void *pvParameters )
{
const TickType_t xDelay100ms = pdMS_TO_TICKS( 100UL );
BaseType_t ret;
/* 任务函数的主体一般都是无限循环 */
for( ;; )
{
/* 打印任务的信息 */
printf("Task1 is running\r\n");
ret = xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, &xTask2Handle );
if (ret != pdPASS)
printf("Create Task2 Failed\r\n");
// 如果不休眠的话, Idle任务无法得到执行
// Idel任务会清理任务2使用的内存
// 如果不休眠则Idle任务无法执行, 最后内存耗尽
vTaskDelay( xDelay100ms );
}
}
任务2的代码如下:
void vTask2( void *pvParameters )
{
/* 打印任务的信息 */
printf("Task2 is running and about to delete itself\r\n");
// 可以直接传入参数NULL, 这里只是为了演示函数用法
vTaskDelete(xTask2Handle);
}
main函数代码如下
int main( void )
{
prvSetupHardware();
xTaskCreate(vTask1, "Task 1", 1000, NULL, 1, NULL);
/* 启动调度器 */
vTaskStartScheduler();
/* 如果程序运行到了这里就表示出错了, 一般是内存不足 */
return 0;
}
任务运行图: main函数中创建任务1,优先级为1。
任务1运行时,它创建任务2,任务2的优先级是2。
任务2的优先级最高,它马上执行。
任务2打印一句话后,就删除了自己。
任务2被删除后,任务1的优先级最高,轮到任务1继续运行,它调用 vTaskDelay() 进入Block状 态 任务1 Block期间,轮到Idle任务执行:它释放任务2的内存(TCB、栈) 时间到后,任务1变为最高优先级的任务继续执行。 如此循环。
在任务1的函数中,如果不调用vTaskDelay,则Idle任务用于没有机会执行,它就无法释放创建任务2是 分配的内存。
而任务1在不断地创建任务,不断地消耗内存,最终内存耗尽再也无法创建新的任务。
任务1的代码中,需要注意的是:xTaskCreate的返回值。
很多手册里说它失败时返回值是pdFAIL,这个宏是0 其实失败时返回值是errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY,这个宏是-1 为了避免混淆,我们使用返回值跟pdPASS来比较,这个宏是1