3. 任务调度基础:单速率任务、多速率任务、任务优先级与抢占

好,咱们今天聊聊任务调度。这是实时系统的核心,也是很多初学者容易踩坑的地方。

我记得刚接触dSPACE那会儿,总觉得任务调度不就是让几个函数轮流跑嘛,有什么难的?结果第一次做多速率项目,系统直接跑飞了。嗯,从那以后我再也不敢小看调度了。

3.1 单速率任务:最朴素的调度方式

单速率任务,说白了就是所有任务都按同一个频率执行。比如你有一个控制循环,固定每1ms跑一次。这就是单速率。

在dSPACE的RTI(Real-Time Interface)里,单速率任务通常对应一个定时器中断。你设置好周期,系统到点就触发。

核心特点:

  • 所有任务共享同一个时间基准
  • 任务执行顺序固定,没有优先级竞争
  • 实现简单,适合功能单一的系统

我个人的习惯是,如果系统功能简单,比如就一个传感器采集加一个控制输出,我肯定用单速率。省心,不容易出幺蛾子。

但单速率有个硬伤:如果某个任务执行时间超过了周期,系统就崩了。你想想看,一个1ms的任务跑了2ms,下一个周期来了怎么办?

注意:单速率任务必须满足:最坏情况执行时间(WCET) < 任务周期。这是硬约束,没得商量。

3.2 多速率任务:现实世界的常态

实际项目中,很少有只用单速率的。比如一个汽车ECU,发动机控制要1kHz,车身控制100Hz就够了,诊断任务可能1Hz跑一次。这就必须用多速率。

多速率任务,就是不同任务按不同频率执行。在dSPACE里,你可以为每个任务单独设置周期。

任务类型 典型周期 优先级
发动机控制 1ms 最高
变速箱控制 5ms
车身控制 10ms
诊断任务 1000ms

这里有个坑:不同速率的任务之间怎么交换数据?我曾经见过一个项目,高速任务和低速任务共用一个全局变量,结果数据读到一半被覆盖了。嗯,这就是典型的资源竞争问题。

我的建议:多速率任务之间用双缓冲或者消息队列。别图省事直接用全局变量,血的教训。

3.3 任务优先级:谁说了算?

多速率任务多了,总得有个先后顺序。这就是优先级的作用。

在dSPACE的实时系统中,优先级通常用数字表示,数字越小优先级越高。比如优先级1的任务,永远比优先级2的任务先执行。

但优先级不是越高越好。我见过有人把所有任务都设成最高优先级,结果系统一直在处理高优先级任务,低优先级的永远没机会跑。这叫优先级反转,或者叫饿死。

优先级设置原则:

  • 时间关键的任务给高优先级(比如安全相关的控制)
  • 周期短的任务给高优先级(因为来不及等)
  • 非关键、周期长的任务给低优先级

举个例子:一个安全气囊控制器,触发信号来了必须在1ms内响应。这种任务优先级必须最高。而一个仪表盘显示任务,晚个几十毫秒没人管你,优先级设低点就行。

3.4 抢占:高优先级说了算

抢占,就是高优先级任务来了,低优先级任务得让路。

在dSPACE里,默认是抢占式调度。也就是说,如果一个低优先级任务正在执行,突然来了一个高优先级任务,系统会立刻保存低优先级任务的上下文,切换到高优先级任务去执行。

等高优先级任务跑完了,再回来接着跑低优先级任务。

注意:抢占会导致上下文切换开销。如果切换太频繁,系统效率会下降。我曾经在一个项目里,任务周期设得太短,结果系统70%的时间都在做上下文切换,真正干活的时间只有30%。

那怎么避免?两个办法:

  1. 合理设置周期:别把周期设得太短,够用就行
  2. 使用临界区:在关键操作前后关中断,防止被抢占

但临界区也有代价。关中断时间太长,会影响实时性。我一般建议临界区控制在几十微秒以内,别超过100微秒。

3.5 一个实际案例

说个我经历过的项目吧。一个电机控制平台,需要同时做电流环、速度环和位置环。

电流环最快,需要10kHz(100微秒周期)。速度环1kHz(1ms周期)。位置环100Hz(10ms周期)。

我当时的配置是这样的:

  • 电流环任务:优先级1,周期100微秒
  • 速度环任务:优先级2,周期1ms
  • 位置环任务:优先级3,周期10ms

一开始跑得好好的。后来加了通信任务,优先级设成了0(最高)。结果通信任务一跑,电流环就被抢占了,电机开始抖动。

排查了半天才发现,通信任务的优先级设得太高了。其实通信任务对实时性要求没那么高,丢一包数据无所谓,但电流环丢一个周期电机就抖。

最后把通信任务优先级降到4,问题解决。

经验总结:优先级不是越高越好,而是越合适越好。把优先级给真正需要实时响应的任务,别浪费在非关键任务上。

3.6 小结

任务调度这块,说白了就是三个问题:

  • 任务跑多快(单速率还是多速率)
  • 谁先跑(优先级)
  • 能不能打断(抢占)

搞清楚了这三个问题,实时系统的基本框架就搭起来了。剩下的就是细节调优,比如任务间通信、资源保护这些。

嗯,下一章咱们聊聊任务间通信,那又是一个容易踩坑的地方。