5.4 删除任务
示例3:删除任务
这个例子的功能是:
当检测到遥控器的 Power 按键被按下后,删除音乐播放任务。
也就是说,这个例子演示的是 FreeRTOS 中如何删除一个已经创建好的任务。
1 代码的基本逻辑
程序在 while(1) 循环中不断读取红外遥控器的数据。
如果检测到不同按键,就执行不同操作:
- 按下
play键:创建音乐播放任务 - 按下
power键:删除音乐播放任务
因此,这段代码实现的是:
通过遥控器按键动态创建和删除任务。
2 创建任务的部分
当检测到 play 键时,程序会执行下面的代码:
if (data == 0xa8) /* play */
{
extern void PlayMusic(void *params);
if (xSoundTaskHandle == NULL)
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Create Task");
ret = xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);
}
}这段代码表示:
- 如果当前还没有音乐任务
- 就创建一个名为
SoundTask的任务 - 任务函数是
PlayMusic - 任务句柄保存在
xSoundTaskHandle中
这里判断:
if (xSoundTaskHandle == NULL)是为了防止重复创建同一个任务。
3 删除任务的部分
当检测到 power 键时,程序会执行下面的代码:
else if (data == 0xa2) /* power */
{
if (xSoundTaskHandle != NULL)
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Delete Task");
vTaskDelete(xSoundTaskHandle);
PassiveBuzzer_Control(0); /* 停止蜂鸣器 */
xSoundTaskHandle = NULL;
}
}这段代码表示:
- 如果当前音乐任务存在
- 就调用
vTaskDelete(xSoundTaskHandle)删除这个任务 - 删除后关闭蜂鸣器
- 最后把任务句柄清零
4 vTaskDelete() 的作用
在这个例子中,真正完成任务删除的函数是:
vTaskDelete(xSoundTaskHandle);它的作用是:
删除指定任务句柄对应的任务。
这里传入的是 xSoundTaskHandle,所以被删除的是音乐播放任务 SoundTask。
5 为什么删除后要把句柄设为 NULL
代码中删除任务后,还有一句:
xSoundTaskHandle = NULL;它的作用是:
表示这个任务已经不存在了。
这样做有两个好处:
- 后面可以通过
xSoundTaskHandle == NULL判断任务是否存在 - 防止后续误操作一个已经被删除的任务
所以,任务删除后把句柄清零,是一种很常见也很好的写法。
6 为什么还要停止蜂鸣器
代码中在删除任务后,还执行了:
PassiveBuzzer_Control(0);这是因为音乐播放任务被删除后,蜂鸣器可能还保持在发声状态。
所以这里手动关闭蜂鸣器,保证任务删除后设备状态也恢复正常。
也就是说:
删除任务不仅要删除软件任务本身,还要注意清理任务运行过程中留下的硬件状态。
7 本例的核心思想
这个例子主要说明了两点:
7.1 任务可以动态创建
按下 play 键时,可以在程序运行过程中创建一个新的任务。
7.2 任务也可以动态删除
按下 power 键时,可以在程序运行过程中删除已经存在的任务。
这说明 FreeRTOS 中的任务并不是只能在系统启动时一次性创建好,也可以根据运行条件动态增删。
8 小结
这个例子演示了 FreeRTOS 中任务的动态删除过程。程序通过遥控器按键控制音乐任务的创建和删除:按下 play 键时创建 SoundTask,按下 power 键时调用 vTaskDelete() 删除该任务。删除完成后,还需要关闭蜂鸣器并将任务句柄设为 NULL,以表示任务已经不存在。
