5.5 任务优先级
1 任务优先级
在 FreeRTOS 中,每个任务都可以设置一个优先级。
优先级的作用是:
当多个任务都处于就绪态时,优先级高的任务会优先获得 CPU。
在这个例子中:
defaultTask的优先级是osPriorityNormalLightTask的优先级是osPriorityNormalColorTask的优先级是osPriorityNormalSoundTask的优先级是osPriorityNormal + 1
这说明:
音乐任务 SoundTask 的优先级高于其他普通任务。
因此,当按下遥控器 play 键创建出 SoundTask 后,如果它处于就绪态,它会比 defaultTask、LightTask、ColorTask 更容易被优先调度执行。:contentReference[oaicite:0]{index=0} :contentReference[oaicite:1]{index=1} :contentReference[oaicite:2]
1.1 怎么修改任务优先级
修改任务优先级有两种常见方法。
1.1.1 在创建任务时直接设置优先级
例如本例中创建 SoundTask 时:
ret = xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal + 1, &xSoundTaskHandle);这里的第 5 个参数就是任务优先级。
如果想让任务优先级更高或更低,可以直接修改这个参数。
例如:
osPriorityNormal
osPriorityNormal + 1
osPriorityAboveNormal这说明:
任务在创建时,就可以通过优先级参数决定它的调度优先级。 :contentReference[oaicite:3]
1.1.2 在任务运行过程中修改优先级
FreeRTOS 还提供了专门的函数:
vTaskPrioritySet()它可以在任务已经创建并运行后,动态修改任务优先级。
例如:
vTaskPrioritySet(xSoundTaskHandle, osPriorityNormal + 2);这表示把 xSoundTaskHandle 对应任务的优先级修改为更高一级。
如果想获取某个任务当前的优先级,可以使用:
uxTaskPriorityGet()例如:
UBaseType_t prio = uxTaskPriorityGet(xSoundTaskHandle);1.2 修改优先级时要注意
修改优先级后,如果该任务处于就绪态,调度结果可能会立刻发生变化。
例如,某个任务优先级被提高后,它可能马上抢占当前正在运行的低优先级任务。
因此,优先级修改本质上会直接影响任务调度顺序。
2 从这个例子理解优先级
这个例子说明了优先级最核心的一点:
优先级决定“谁先运行”,而不是“谁一定一直运行”。
也就是说:
- 高优先级任务一旦就绪,通常会先执行
- 低优先级任务并不是永远不能运行
- 当前提是高优先级任务要么运行结束,要么阻塞,要么主动让出 CPU
所以,在这个例子里,SoundTask 之所以设置成更高优先级,是因为音乐播放任务希望比普通显示或测试任务更快得到响应。:contentReference[oaicite:4]
3 Tick 是什么
Tick 可以理解为 FreeRTOS 的系统时钟节拍。
FreeRTOS 会依靠一个周期性中断,按照固定时间间隔不断产生 Tick。
每产生一次 Tick,中断计数就加 1,这个计数值通常称为 Tick Count。
因此可以简单理解为:
Tick 是 FreeRTOS 用来衡量时间和推动任务调度的基本时间单位。
4 Tick 的作用
Tick 在 FreeRTOS 中主要有两个作用:
4.1 提供时间基准
很多延时函数、超时等待,都是基于 Tick 实现的。
例如:
- 任务延时
- 队列等待超时
- 信号量等待超时
本质上都离不开 Tick 计数。
4.2 触发调度检查
每次 Tick 到来时,系统都会检查:
- 是否有延时结束的任务需要变为就绪态
- 是否需要进行任务切换
- 是否需要进行同优先级任务的时间片轮转
所以,Tick 是任务调度正常运行的重要基础。
5 从这个例子怎么理解 Tick
虽然这个例子里没有直接写 vTaskDelay() 或 osDelay(),但任务的运行仍然离不开 Tick。
因为 FreeRTOS 的调度器本身就是依靠 Tick 中断不断推进的。
你可以这样理解:
defaultTask一直在循环读取遥控器- 当按下
play键时,创建出高优先级的SoundTask - 调度器在系统运行过程中,根据任务优先级和 Tick 节拍决定哪个任务运行
所以,这个例子主要体现了:
- 优先级决定任务的调度先后
- Tick 提供任务调度和时间管理的基础节拍
6 小结
这个例子中,SoundTask 的优先级被设置为 osPriorityNormal + 1,高于其他普通任务,因此创建后会优先得到调度执行。:contentReference[oaicite:5]
任务优先级既可以在创建任务时通过函数参数设置,也可以在任务运行过程中通过 vTaskPrioritySet() 动态修改。对应地,可以使用 uxTaskPriorityGet() 获取任务当前优先级。
同时,虽然代码中没有直接操作 Tick,但 FreeRTOS 的任务切换、延时管理和调度机制本质上都依赖 Tick 中断来推进。因此可以把:
- 任务优先级 理解为“决定谁先运行的规则”
- Tick 理解为“推动系统时间流动和任务调度的时钟节拍”
