第1章:固定优先级调度(FPS)与速率单调调度(RMS)算法原理

各位同学,咱们今天聊聊实时系统里最经典的一个调度算法——速率单调调度(RMS)。说实话,我做了十几年嵌入式系统,RMS 是我最早接触的调度算法之一。那时候刚入行,带我的老工程师就说:「小子,先把 RMS 搞明白,后面的事就好办了。」现在回想起来,这话一点不假。

1.1 什么是固定优先级调度?

固定优先级调度(FPS),说白了就是每个任务在系统启动时就定好了优先级,运行过程中谁也不许改。你想想看,这就像公司里的职级——你是 P7 就永远是 P7,不会因为今天活干得多就变成 P8。

在 FPS 里,优先级怎么定呢?最常见的方式就是按周期来。周期越短的任务,优先级越高。这就是 RMS 的核心思想。

核心要点:RMS 是一种静态优先级调度算法,任务的优先级与它的周期成反比——周期越短,优先级越高。

1.2 速率单调调度(RMS)算法原理

RMS 的全称是 Rate Monotonic Scheduling。这里的「速率」指的是任务释放的频率。你想想看,一个每 10ms 执行一次的任务,它的释放速率就是 100Hz;另一个每 100ms 执行一次的任务,速率就是 10Hz。RMS 的做法很简单:速率高的任务,优先级就高。

我举个例子你就明白了:

任务 T1:周期 10ms,执行时间 3ms
任务 T2:周期 20ms,执行时间 5ms
任务 T3:周期 50ms,执行时间 8ms

按照 RMS:
T1 的周期最短 → 优先级最高
T2 的周期次之 → 优先级中等
T3 的周期最长 → 优先级最低

嗯,这里要注意一点:RMS 假设所有任务都是周期性的,而且任务之间没有依赖关系。我在实际项目中遇到过有人把非周期任务硬塞进 RMS 框架里,结果调度一塌糊涂。千万别这么干。

1.3 RMS 的可调度性分析(Liu & Layland 定理)

好,现在问题来了:你按照 RMS 分配了优先级,怎么知道这些任务能不能在规定时间内跑完?这就引出了 Liu & Layland 定理。

1973 年,Liu 和 Layland 两位大神提出了一个充分条件(注意,是充分条件,不是充要条件):

Liu & Layland 定理:对于 n 个独立的周期性任务,如果所有任务的 CPU 利用率满足以下条件,则这些任务在 RMS 调度下是可调度的:

U ≤ n(2^(1/n) - 1)

这个公式看着有点吓人,我帮你算几个值:

任务数量 n 利用率上界 U_max
1 1.000
2 0.828
3 0.779
4 0.756
5 0.743
ln 2 ≈ 0.693

看到了吗?当任务数量趋于无穷时,利用率上界收敛到约 69.3%。也就是说,如果你的 CPU 利用率超过了 69.3%,RMS 就不能保证所有任务都能按时完成。

我的经验:在实际项目中,我一般会把 CPU 利用率控制在 60% 以下。为什么?因为 Liu & Layland 定理只是一个充分条件,不是必要条件。利用率在 69.3% 以下只是「保证」可调度,但实际系统中还有中断、上下文切换开销等因素。留点余量,心里踏实。

1.4 RMS 的优缺点

做了这么多年嵌入式,我对 RMS 的感情很复杂。它简单好用,但也不是万能的。咱们客观地聊聊它的优缺点。

优点

  • 实现简单:优先级在编译时就定好了,运行时不需要动态调整。我记得第一次在 uC/OS-II 上实现 RMS,只改了几行代码就搞定了。
  • 可预测性强:只要通过了可调度性分析,系统行为就是确定的。这对安全关键系统来说太重要了。
  • 理论成熟:Liu & Layland 定理给了我们一个清晰的判断标准。不像某些调度算法,调不调得通全靠运气。
  • 资源开销小:不需要像 EDF 那样维护动态优先级队列,对 CPU 和内存的消耗都很低。

缺点

  • CPU 利用率受限:刚才说了,理论上限只有 69.3%。实际项目中能用到 50%-60% 就不错了。
  • 对非周期任务不友好:RMS 天生是为周期性任务设计的。非周期任务怎么处理?我一般会把它转成周期任务,或者用服务器机制来处理。
  • 优先级反转问题:这个我后面会专门讲。简单说就是低优先级任务占着资源不放,高优先级任务干等着。我曾经在一个无人机项目里被这个问题坑惨了。
  • 任务周期必须已知:如果任务的周期不确定,RMS 就没法用了。

避坑指南:我曾经在一个项目中,把中断处理函数也当作 RMS 任务来调度。结果发现中断的优先级比所有任务都高,导致 RMS 的优先级分配完全失效。记住:RMS 只适用于任务级别的调度,中断是另一回事。

1.5 小结

RMS 是实时系统调度领域的基石。它简单、可靠、理论扎实。虽然有一些局限性,但在很多实际场景中依然是最优选择。我个人习惯在项目初期先用 RMS 搭一个原型,如果发现利用率不够或者有特殊需求,再考虑换成其他调度算法。

下一章咱们聊聊 RMS 在实际工程中的应用,以及怎么处理那些「不听话」的非周期任务。到时候我会分享一个我在工业控制项目中踩过的坑,保证让你印象深刻。