Freertos系列教学(删除函数的使用)
如果不想看的可以直接使用git把我的代码下载出来,里面工程挺全的,后期会慢慢的补注释之类的
码云地址:stm32学习笔记: stm32学习笔记源码
如果不会使用git快速下载可以选择直接下载压缩包或者去看看git的使用
Git入门教程-CSDN博客
目录
一 函数讲解
二 删除任务的流程编辑
三 实际测试
3.1 中断直接删除其他任务
3.2 通过任务2来删除任务1
3.3 通过计数删除本身
一 函数讲解
函数说明:vTaskDelete 传入任务句柄即可,如果要删除本身填写NULL即可,任务会在任务执行结束后删除本身。
二 删除任务的流程
宏INCLUDE_vTaskDelete 配置为 1将 INCLUDE_vTaskDelete
定义为 1
,就可以使用 vTaskDelete
函数来删除任务。
内部流程:获取要删除的任务控制块->将传入的任务移除所在列表->判断要删除的任务是其他任务还是本身,如果是其他任务就删除,如果是本身则需要添加到等待列表,之后再空闲任务执行删除->最后更新阻塞时间,方式下一个任务是被删除任务导致死机
三 实际测试
3.1 中断直接删除其他任务
PS:函数的整体在前面一章创建函数内有,这里直接只讲删除任务了哦。
首先我们粘贴一个按钮的驱动:这里使用按键去删除一个任务(在操作系统中,中断一般只发送信号量,不去处理复杂的程序,我们这里只是因为做测试使用了一下问题不大,后面到了信号量之类的会用到中断之类的)
移植按钮中断驱动大家应该都会把= =这里就不加赘述了哦。
任务还是之前两个:
void task1( void * pvParameters )
{while (1){printf("task 1\r\n");vTaskDelay(pdMS_TO_TICKS(500));}
}void task2( void * pvParameters )
{while (1){printf("task 2\r\n");vTaskDelay(pdMS_TO_TICKS(500));}
}
这里使用中断的方式直接删除
void KEY1_IRQHandler(void)
{//确保是否产生了EXTI Line中断if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {taskENTER_CRITICAL();vTaskDelete(task2_handler);taskEXIT_CRITICAL();//清除中断标志位EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE); }
}
为了避免在删除任务过程中出现数据不一致或其他竞态条件(中断被更高优先级的任务打断),先进入临界区。在 FreeRTOS 中可以使用 taskENTER_CRITICAL()
来实现,不担心被高优先级的打断可以不进入临界区。
中断完成后,在退出临界区
看看正常运行的效果
之后我们按下按钮任务直接被删除了
3.2 通过任务2来删除任务1
代码如下:
通过计数来删除任务1,这里需要注意,我们需要判断task1handler不为空,如果为空还去删除它,我们的程序会死机的。
void task1( void * pvParameters )
{while (1){printf("task 1\r\n");vTaskDelay(pdMS_TO_TICKS(500));}
}void task2( void * pvParameters )
{u8 i=0;while (1){printf("task 2\r\n");i++;// 只在 task1 未被删除时执行删除操作if (task1_handler != NULL && i==10) {vTaskDelete(task1_handler);task1_handler = NULL; // 标记句柄失效,避免重复删除}vTaskDelay(pdMS_TO_TICKS(500));}
}
可以看出来,我们的任务会被正常删除:那么如果我们一直让task2运行不去释放CPU,并且在task2中删除自己,能够成功吗?
3.3 通过计数删除本身
不释放CPU
void task2( void * pvParameters )
{u8 i=0;u32 j=0;while (1){printf("task 2\r\n");i++;for(j=0;j<10000000;j++){}// 只在 task1 未被删除时执行删除操作if (task2_handler != NULL && i==10) {vTaskDelete(NULL);task1_handler = NULL; // 标记句柄失效,避免重复删除}//vTaskDelay(pdMS_TO_TICKS(500));}
}
这里很明显:task2被成功删除了,之前说过,任务删除会在任务结束后进行,那么我们这里任务明明没有释放CPU也被删除了,是delete直接终止了任务吗?
测试一下:
void task2( void * pvParameters )
{u8 i=0;u32 j=0;while (1){printf("task 2\r\n");i++;// 只在 task1 未被删除时执行删除操作if (task2_handler != NULL && i==10) {vTaskDelete(NULL);task1_handler = NULL; // 标记句柄失效,避免重复删除}printf("task 11111\r\n");vTaskDelay(pdMS_TO_TICKS(500));}
}
这里正常打印应该是2 11111 1 之后删除掉task2 这里删除之前只打印出来了2 删除任务2 1
很明显,这里任务直接没了:所以说在调用函数的时候任务直接被删除了,但是内存会在任务结束之后有空闲任务去清除。这里看看官方文档。这里没有明说,但是确实是调用之后,就被从所有的列表删除掉了。