2. RTOS基础回顾
在进入 Tickless 低功耗设计之前,有必要把 RTOS 中与“时间”和“功耗”直接相关的几个基础机制重新梳理一遍。很多低功耗改造之所以效果不佳,并不是 Tickless 本身配置错误,而是对任务调度、时钟节拍、中断管理、空闲任务之间的耦合关系理解不到位。本节从功耗视角重新审视这些基础概念,为后续章节建立统一的认知框架。
一、任务调度:功耗的“决策源头”
RTOS 的调度器决定任意时刻哪个任务占用 CPU。从功耗角度看,调度结果直接决定了 CPU 是处于运行态、就绪态还是阻塞态。常见的调度策略包括抢占式优先级调度和时间片轮转调度:
- 抢占式优先级调度:高优先级任务就绪时立即抢占,响应快,但频繁切换会增加上下文切换开销,间接抬高动态功耗。
- 时间片轮转:同优先级任务按时间片轮流执行,切换次数与时间片长度成反比,时间片越短,切换越频繁,功耗越高。
- 阻塞与挂起:任务等待信号量、队列或延时进入阻塞态,此时不占用 CPU,是低功耗的前提条件。
关键结论是:只有当所有任务都进入阻塞或挂起状态时,系统才可能进入空闲任务,进而有机会进入低功耗模式。因此,任务设计是否合理,直接决定了低功耗窗口的大小。
二、时钟节拍:系统的心跳与功耗的“隐形税”
大多数 RTOS 使用一个周期性硬件定时器产生系统节拍(SysTick 或通用定时器),每个节拍触发一次中断,在中断中处理延时到期、超时、时间片递减等逻辑。这个节拍频率通常为 100Hz~1000Hz。
从功耗角度看,时钟节拍带来两个问题:
- 周期性唤醒:即使系统无事可做,每个节拍中断都会把 CPU 从低功耗模式唤醒,处理完再睡下。频率越高,唤醒越频繁,平均功耗越高。
- 无法深度睡眠:如果低功耗模式退出时间较长,而节拍周期较短,系统可能还没来得及进入深度睡眠就被下一次节拍打断,导致低功耗模式形同虚设。
三、中断管理与空闲任务
中断是 RTOS 响应外部事件的唯一异步入口。中断服务程序(ISR)应尽可能短,只做标志置位、数据搬运等必要操作,把耗时处理交给任务。中断过于频繁或 ISR 过长,会持续占用 CPU,压缩低功耗时间。
空闲任务是系统中优先级最低的任务,当没有其他就绪任务时运行。它的核心职责有两个:一是回收被删除任务的内存,二是在空闲钩子中执行低功耗指令。传统设计中,空闲任务通常只是执行 WFI(Wait For Interrupt)指令,让 CPU 停止直到下一次中断到来。
void vApplicationIdleHook(void)
{
/* 进入浅睡眠,等待任意中断唤醒 */
__WFI();
}
但问题在于:如果节拍中断每 1ms 就来一次,那么 WFI 最多只能睡 1ms,无法进入更深的 STOP 或 STANDBY 模式。这正是 Tickless 要解决的核心矛盾。
四、系统节拍与功耗的关系:一张图看清耦合
下面这张图从信号与状态流转的角度,展示节拍中断、任务调度、空闲任务与低功耗模式之间的耦合关系。可以看到,节拍是打断睡眠的“元凶”,而 Tickless 的本质就是在空闲时关闭周期性节拍,改用一次性定时器在下一个任务到期时刻唤醒。
五、典型场景与参数对照
下表对比了不同节拍频率与低功耗模式组合下的行为差异,帮助理解参数选择对功耗的影响。
| 节拍频率 | 节拍周期 | 可进入的最低功耗模式 | 每秒唤醒次数 | 功耗影响 |
|---|---|---|---|---|
| 1000 Hz | 1 ms | SLEEP(浅睡) | 1000 | 唤醒开销大,难以深度睡眠 |
| 100 Hz | 10 ms | SLEEP / 短时 STOP | 100 | 中等,仍受周期限制 |
| Tickless | 按需 | STOP / STANDBY | 仅任务到期时 | 显著降低,睡眠时间大幅延长 |
六、常见误区与复盘
总结来看,任务调度决定“谁在跑”,时钟节拍决定“多久醒一次”,中断管理决定“谁能打断睡眠”,空闲任务决定“睡多深”。四者共同构成 RTOS 功耗行为的基础模型。理解这个模型,才能在后续 Tickless 设计中准确判断:哪些节拍可以关、哪些唤醒必须保留、低功耗模式该选哪一级。