第1章:任务调度机制——抢占式调度、时间片轮转、空闲任务、调度锁

大家好,我是你们的老朋友。今天咱们聊聊RTOS里最核心的东西——任务调度。

说实话,我刚开始做嵌入式那会儿,对调度机制的理解也就停留在“能跑就行”。直到有一次,一个按摩仪项目在客户手里频繁死机,我才真正意识到:不懂调度,你连Bug都找不到在哪

这一章,咱们就把抢占式调度、时间片轮转、空闲任务和调度锁这四块硬骨头啃下来。别怕,我会用我踩过的坑给你铺路。

1.1 抢占式调度:谁优先级高谁先跑

抢占式调度,说白了就是“强者优先”。高优先级的任务一旦就绪,立马打断当前正在运行的低优先级任务,抢过CPU的使用权。

我习惯这么理解:就像你在排队打饭,突然来了个VIP客户,他可以直接插队到最前面。你虽然不爽,但规则就是这样。

核心要点:

  • 每个任务都有一个优先级(数值越小优先级越高,或者反过来,看具体RTOS)
  • 高优先级任务就绪时,立即发生任务切换
  • 低优先级任务只有在高优先级任务阻塞或主动让出CPU时才能运行

我在项目中遇到过一个问题:一个按键扫描任务优先级设得太高,结果它一直占用CPU,导致电机控制任务响应延迟,按摩头卡住了。嗯,这就是典型的“优先级反转”前兆。

我的建议:优先级分配要遵循“紧急且短”的任务高优先级,“不紧急或长”的任务低优先级。比如按键响应可以高,但LED闪烁就放低。

1.2 时间片轮转:大家轮流用CPU

如果所有任务优先级都一样呢?那就用时间片轮转。

每个任务分配一个固定的时间片(比如10ms),时间到了就切换到下一个任务。你想想看,这就像几个朋友轮流开车,每人开10分钟,公平合理。

时间片轮转的典型场景:

  • 多个同等重要的后台任务(比如数据采集、日志记录)
  • 没有明确优先级差异的用户界面刷新
  • 调试阶段,避免某个任务饿死

我记得有一次调试一个按摩仪,三个传感器采集任务优先级相同,但其中一个采集时间特别长。结果另外两个任务老是抢不到CPU,数据丢失严重。后来我把它们改成时间片轮转,每个任务给5ms,问题就解决了。

注意:时间片太短会导致频繁切换,浪费CPU在上下文切换上;时间片太长又会让其他任务等太久。一般建议在1ms~20ms之间,具体看你的系统时钟节拍。

1.3 空闲任务:CPU没事干的时候

当所有任务都阻塞或挂起时,CPU总不能空转吧?这时候空闲任务就登场了。

空闲任务是RTOS自动创建的,优先级最低,永远处于就绪状态。它的主要职责是:

  • 让CPU进入低功耗模式(比如WFI指令)
  • 统计CPU利用率
  • 做一些系统级的清理工作

我曾经犯过一个低级错误:在空闲任务里加了一个延时函数,结果系统功耗反而升高了。为什么?因为空闲任务本该让CPU睡觉,结果它自己在那数数,CPU根本睡不了。

避坑指南:空闲任务里不要做任何阻塞操作!不要加延时!不要加死循环!让它干干净净地调用休眠指令就好。

1.4 调度锁:关键时刻的“暂停键”

调度锁,说白了就是临时关闭任务调度。你可能会问:为什么要关调度?

想象一下这个场景:你在更新一个全局变量,刚写到一半,突然被高优先级任务打断,它也来读写这个变量——数据就乱套了。

这时候,调度锁就派上用场了。它告诉RTOS:“先别切换任务,等我干完这点活再说。”

使用调度锁的典型场景:

  • 保护临界区代码(比如操作共享变量)
  • 需要原子操作的硬件配置序列
  • 避免中断和任务之间的竞态条件

重要原则:调度锁要快进快出!锁住的时间越短越好,一般不超过几十微秒。我曾经见过一个同事把调度锁一锁就是100ms,结果系统响应直接崩了。

代码示例(以FreeRTOS为例):

// 进入临界区,关闭调度
taskENTER_CRITICAL();

// 这里操作共享变量,安全!
g_motor_speed = 100;
g_motor_direction = 1;

// 退出临界区,恢复调度
taskEXIT_CRITICAL();

警告:调度锁内不要调用任何可能阻塞的函数(比如延时、等待信号量)。否则系统会直接死锁,连空闲任务都救不了你。

小结一下

这一章咱们聊了四种调度机制:

机制 核心思想 典型用途
抢占式调度 高优先级打断低优先级 实时性要求高的任务
时间片轮转 同优先级任务轮流执行 后台批量处理
空闲任务 CPU无事可做时运行 低功耗、统计CPU利用率
调度锁 临时关闭任务切换 保护临界区、原子操作

我个人觉得,理解这四种机制,你就掌握了RTOS调度的80%。剩下的20%,是在实际项目中慢慢磨出来的。

下一章,咱们聊聊任务状态与状态切换——为什么任务会“卡住”?怎么让它“活过来”?到时候见。

课后小作业:打开你的RTOS工程,看看空闲任务的钩子函数里有没有加延时?如果有,试着去掉,测一下功耗变化。你会回来感谢我的。


公众号:蓝海资料掘金营,微信deep3321