基于RTOS开发时,经常会遇到一个棘手问题:有一堆周期性任务,大家都有自己的执行时间和截止期限,那到底该按照什么规则去分配优先级,才能既不浪费CPU,又能保证关键任务的实时性?这就引出了一个经典方法——速率单调调度
,也就是大家常说的 RMA。
为什么需要调度算法
嵌入式系统,尤其是实时系统,讲究的是 时间就是生命。比如在汽车电子中,刹车控制系统的任务必须在几十毫秒内响应,否则后果不堪设想;在工业控制里,PLC的周期性任务也得严格按照时间点执行。实时调度算法的核心目标,就是确保任务能在截止时间前完成,即满足 硬实时 或 软实时 的要求。
静态优先级 vs 动态优先级
在嵌入式实时系统中,大多数会用 抢占式多任务 的方式,尤其是基于实时操作系统(RTOS)的场景。RTOS会根据任务的优先级,优先执行最高优先级的任务。而优先级怎么定?这就得靠调度算法了。常见的调度算法分为 静态优先级、动态优先级 和 混合优先级 三类。
静态优先级在设计时就固定好,任务运行期间不变;动态优先级会根据运行时的参数(比如截止时间)动态调整;混合优先级则是两者的结合。
对我们搞嵌入式开发的来说,静态优先级用得最多,原因很简单:易于分析,方便调试,而且多数商用RTOS都只提供固定优先级调度。
一个小例子

我们用一个例子来直观感受下。假设系统中有两个周期性任务:
任务1:周期T1=50ms,执行时间C1=25ms 任务2:周期T2=100ms,执行时间C2=40ms
先来算算 CPU利用率。任务的利用率定义为执行时间除以周期,即Ui = Ci/Ti。所以:
任务1的利用率 U1 = 25/50 = 50% 任务2的利用率 U2 = 40/100 = 40% 总利用率 U = U1 + U2 = 90%

90%的CPU利用率看起来没问题,CPU还有10%的空闲时间,理论上应该能跑得动这两个任务。但优先级怎么排?我们试试两种情况:
任务1优先级高于任务2:因为任务1的周期(50ms)比任务2(100ms)短,按照RMA规则,任务1优先级更高。这种情况下,两个任务都能按时完成。 任务1优先级低于任务2:这时候任务1可能会因为被任务2抢占,导致错过截止时间,即便CPU还有10%的空闲。
这个例子说明,优先级分配不当,哪怕CPU利用率不到100%,也可能导致任务超时。
RMA 的核心思想
RMA 的规则其实非常简单粗暴:谁的周期短,谁的优先级高。
为什么这么安排?因为周期短的任务执行频率高,通常意味着它对时间的敏感度更高。比如一个每10毫秒触发一次的任务,显然比一个每100毫秒触发一次的任务更急迫。
回到上面的例子,Task1 周期 50ms,比 Task2 的 100ms 更短,所以 Task1 优先级更高。事实证明,这样的分配方式才能保证两个任务都不超时。
RMA的厉害之处就在于,它通过 周期决定优先级 的简单规则,最大化了任务的可调度性(schedulability),也就是让所有任务都能按时完成。
RMA 的结论也很硬气:如果某个任务集合用 RMA 都调度不了,那它就不可能用任何静态优先级算法调度成功。
RMA是静态优先级算法中的 最优解。所谓最优,意思是如果一个任务集用RMA调度都无法满足所有截止时间,那换其他静态优先级算法也没戏。
RMA 的局限性
虽然 RMA 已经是固定优先级里最优的,但它还是有上限。最大的问题在于 CPU利用率的理论上限。理论上,RMA的调度能力受限于一个公式:
Wn = n × (2^(1/n) − 1)
这里 n 是任务数。随着任务数增加,这个上限会逐渐逼近 69.3%(约等于ln(2))。 也就是说,哪怕你系统总利用率只有 70%,也可能因为任务周期分布不合理,导致调度失败。

举个例子,假设任务2的周期改成75ms,执行时间改成30ms,总利用率还是90%,但用RMA调度(任务1优先级高于任务2),任务2可能会错过截止时间。这种情况下,静态优先级算法无能为力,只能考虑动态优先级算法,比如 最早截止时间优先(EDF),但动态算法实现复杂,很多商用RTOS(比如国内常用的FreeRTOS)并不支持。
不过,如果任务的周期是谐波关系(比如 10ms、20ms、40ms),那CPU就能被充分利用到 100%。这也是为什么很多工业控制任务,周期都会设计成倍数关系,方便调度。
小结
最后总结几条经验:
固定优先级的系统里,优先级一定要按照 RMA 来分配,别自己拍脑袋。 如果总利用率小于等于理论上限 Wn,那不用再纠结,肯定能调度成功。 如果大于 Wn,就得具体分析,画时序图或者用工具仿真一下,看是不是能跑通。 周期设计尽量用谐波关系,这样CPU利用率能榨干到极致。
很多时候,RMA 不仅仅是一个算法,更是一种设计思路。只要掌握了它的原理,再结合项目的具体需求,就能在嵌入式系统里做到既稳定又高效的任务调度。
