前言
最近本人在实现一个轻量化的 RTOS,本文用于说明为什么要用 RTOS、什么时候适合用 RTOS,并对几种常见的软件结构做一个简单对比。
需要先说明一点:RTOS 并不是必须的。对于很多嵌入式项目来说,简单轮询或者“轮询 + 中断”就已经足够;只有当系统复杂度上来后,RTOS 的价值才会真正体现出来。
相关代码请访问我的Github仓库,网址为:yuan-rtos。
我接下来也会出一些文章介绍我写的 RTOS,比如移植啊,怎么实现任务切换等功能。
简单轮询
所谓简单轮询,就是程序只在一个死循环中按顺序执行各项功能,不使用中断,也不使用 OS 等涉及异常控制流的机制。
其优点十分的明显,如下:
- 程序结构简单,容易理解和上手
- 执行流程直观,调试比较方便
- 代码体积通常较小,资源占用少
但是缺点也十分的明显,主要有以下几条:
- 事件响应不及时,实时性较差
- 容易出现 CPU 空转,例如软件延时、忙等
- 难以处理优先级问题,谁先扫描谁后扫描往往决定了处理顺序
- 功能增多后,主循环容易变得臃肿,维护困难
轮询 + 中断
相比简单轮询,加入中断后,系统可以更及时地响应外部事件。通常主循环负责普通逻辑,中断负责处理紧急事件或采集数据。
其优点如下:
- 事件响应更及时,实时性更好
- 可以利用中断优先级处理关键事件
- 比纯轮询更适合处理异步事件
但仍然有一些缺点,主要是以下几条:
- 中断资源有限,不能无限使用
- 中断一多后,程序逻辑容易分散,维护难度上升
- 中断里不能执行过重的任务,否则会影响系统实时性
- CPU 空转问题没有从根本上解决
不过在很多实际项目中,“轮询 + 中断”已经足够完成任务,不一定非要上 RTOS。
RTOS
当系统功能较多、模块之间协作复杂、实时性要求较高时,简单轮询或“轮询 + 中断”往往会逐渐暴露出结构混乱、维护困难等问题。
这时,引入 RTOS 可以帮助我们把程序划分为多个独立任务,由内核统一完成调度、同步和通信。
其有以下的的优点:
- 可以按功能划分多个任务,结构更清晰
- 支持任务优先级,便于处理实时任务
- 任务在等待事件时可以阻塞,让 CPU 去执行其它任务,减少空转
- 提供队列、信号量、互斥量、事件组等机制,便于任务间同步与通信
- 更适合功能复杂、后续需要扩展和维护的项目
但也有以下的缺点:
- 需要额外的代码空间和 RAM
- 多任务切换、同步、通信都会带来一定运行开销
- 开发复杂度更高,需要理解调度、临界区、竞态条件、死锁等问题
- 如果项目本身很简单,使用 RTOS 反而可能增加负担
适用场景如下:
- 功能较多、模块较复杂的嵌入式系统
- 对任务优先级和实时性有明确要求的项目
- 任务之间需要频繁通信与同步的场景
- 需要较好可维护性和可扩展性的长期项目
总结
从简单轮询,到“轮询 + 中断”,再到 RTOS,本质上是软件结构逐步复杂化、工程化的过程。
- 简单轮询:最简单,但实时性和扩展性较差
- 轮询 + 中断:适合大多数中小型项目,兼顾实现难度和实时性
- RTOS:适合复杂系统,能显著改善代码组织和任务协作,但会增加资源和开发成本
因此,是否使用 RTOS,不应盲目跟风,而应根据项目复杂度、实时性需求、资源条件和维护成本来决定。