第1章:实时系统基础
大家好,我是你们这门课的老朋友。今天咱们聊聊实时系统的基础。说实话,我做了十几年半实物仿真,见过太多因为实时性没搞明白而翻车的项目。嗯,咱们从最根本的东西说起。
1.1 实时系统的定义
什么叫实时系统?很多人一听「实时」就以为是「快」。其实不是。实时系统的核心是——在规定的时间内完成规定的任务。快不快是次要的,关键是你能不能卡住那个时间点。
我举个例子。你开车踩刹车,ABS系统必须在几毫秒内响应。晚一毫秒,可能就追尾了。这就是实时系统。它不要求你算得有多快,但要求你算得准时。
实时系统的三个核心特征:
- 确定性:任务的执行时间可预测,不能忽快忽慢
- 及时性:必须在截止时间前完成
- 可靠性:系统不能因为超时而崩溃
说白了,实时系统就是「说到做到」的系统。你说1毫秒响应,那就必须1毫秒响应。差一点,就是事故。
1.2 硬实时 vs 软实时
这里有个关键分类。实时系统分两种:硬实时和软实时。怎么区分?看错过截止时间的后果。
| 特性 | 硬实时 | 软实时 |
|---|---|---|
| 错过截止时间 | 系统崩溃或灾难 | 性能下降,但系统继续运行 |
| 典型应用 | 航空电子、汽车安全气囊、医疗起搏器 | 视频播放、网络游戏、数据采集 |
| 调度策略 | 严格保证,静态调度为主 | 尽力而为,动态调度可接受 |
| 设计成本 | 高,需要大量验证 | 相对较低 |
我在做HIL仿真时遇到过一件事。有个客户做电机控制器测试,用的是软实时系统。结果有一次仿真,任务超时了5毫秒,系统没崩溃,但仿真数据全乱了。客户花了三天才找到原因。你想想看,如果是硬实时系统,超时的瞬间就该报警停机,哪用这么折腾?
避坑指南:我曾经见过有人把软实时系统用在安全关键场合。结果呢?一次超时导致测试台架直接烧了。记住:不要用软实时系统做硬实时的事。这是原则问题。
1.3 常见RTOS选型
选RTOS是个技术活。我个人的习惯是,先看项目需求,再看硬件平台,最后才看RTOS特性。别一上来就追新,稳定才是王道。
下面是我用过的几款主流RTOS,给大家做个参考:
| RTOS | 特点 | 适用场景 | 许可证 |
|---|---|---|---|
| FreeRTOS | 轻量、开源、社区活跃 | 物联网、嵌入式小系统 | MIT |
| VxWorks | 硬实时、高可靠、商业支持 | 航空航天、军工、工业控制 | 商业 |
| RT-Thread | 国产、组件丰富、生态好 | 消费电子、智能家居 | Apache 2.0 |
| QNX | 微内核、强隔离、安全认证 | 汽车、医疗、自动驾驶 | 商业 |
| μC/OS-III | 可裁剪、实时性好、文档齐全 | 工业控制、教学 | 商业/免费 |
我个人的建议是:
- 如果你做的是消费级产品,FreeRTOS 够用了,省钱省力
- 如果是安全关键系统,别省那点钱,上 VxWorks 或 QNX
- 国产项目可以考虑 RT-Thread,生态确实在变好
小技巧:选RTOS时,别只看特性列表。我建议你先写一个最小原型,跑一下你的关键任务。很多RTOS看着好,实际跑起来调度延迟可能比你想象的大。实践出真知。
1.4 实时任务调度策略
调度策略是实时系统的灵魂。说白了,就是决定「哪个任务先跑」的规则。这里我重点讲两个经典算法:RMS 和 EDF。
1.4.1 速率单调调度(RMS)
RMS 是静态优先级调度。它的规则很简单:周期越短的任务,优先级越高。为什么?你想想看,周期短的任务更紧急,当然要优先处理。
RMS 的优点:实现简单,开销小。缺点:CPU利用率有上限,理论最大利用率是 n(2^(1/n) - 1)。当任务数 n 趋于无穷时,利用率上限约为 69.3%。
// RMS调度示例:两个任务
// 任务A:周期 10ms,执行时间 3ms
// 任务B:周期 20ms,执行时间 5ms
// 优先级分配:A的周期短,优先级高
// 调度序列:
// 0-3ms: 任务A运行
// 3-8ms: 任务B运行
// 8-10ms: 空闲
// 10-13ms: 任务A运行(第二个周期)
// ...
我在项目中遇到过一个问题。用RMS调度5个任务,CPU利用率算出来只有65%,按理说没问题。但实际跑起来,有一个任务老是超时。查了半天,发现是任务之间有共享资源,优先级反转了。嗯,RMS虽然简单,但别忘了处理资源竞争。
1.4.2 最早截止时间优先(EDF)
EDF 是动态优先级调度。它的规则是:截止时间越早的任务,优先级越高。每个时刻,系统都会重新计算所有任务的截止时间,然后选最紧急的那个跑。
EDF 的优点:CPU利用率理论上可以达到100%。缺点:实现复杂,系统开销大,而且过载时性能会急剧下降。
// EDF调度示例:两个任务
// 任务A:周期 10ms,执行时间 3ms,截止时间=周期
// 任务B:周期 20ms,执行时间 5ms,截止时间=周期
// 调度序列(假设同时释放):
// 0-3ms: 任务A运行(截止时间10ms)
// 3-8ms: 任务B运行(截止时间20ms)
// 8-10ms: 空闲
// 10-13ms: 任务A运行(截止时间20ms)
// 13-18ms: 任务B运行(截止时间40ms)
// ...
RMS vs EDF 对比:
- RMS 适合任务数量固定、周期已知的场景
- EDF 适合任务动态变化、需要高利用率的场景
- RMS 实现简单,但利用率受限
- EDF 利用率高,但过载时不可预测
我个人习惯是:如果任务数少于5个,用RMS就够了。任务多了,或者任务周期变化大,我会考虑EDF。但记住,EDF过载时很可怕——所有任务都可能超时。我曾经在一个HIL项目里吃过这个亏,后来加了过载保护才稳住。
1.5 本章知识体系
下面这张图,是我梳理的本章核心逻辑。你看一眼,心里就有数了。
这张图把本章的核心逻辑串起来了。从实时系统的定义出发,分三条线:分类、选型、调度。你记住这三条线,后面学起来就顺了。
好了,第一章就到这里。内容不多,但都是基础中的基础。下一章咱们聊聊实时系统的硬件基础,包括中断、定时器、DMA这些硬核东西。到时候见。