RTOS

一、什么是RTOS?

RTOS(Real-Time Operating System,实时操作系统)是一种专门为“必须在规定时间内完成指定任务”而设计的操作系统。它像一个严格的时间管家,确保每个任务在截止时间前被执行,而不是“尽量快”地执行。

1.1 RTOS vs 普通操作系统

对比项 普通操作系统(如Windows、Linux) RTOS(如FreeRTOS、VxWorks)
核心目标 提高平均吞吐量,让多个程序公平使用CPU 保证每个关键任务在截止时间前完成
响应时间 不确定,可能因为后台任务延迟几秒 可预测,通常在微秒级响应中断
调度策略 时间片轮转、优先级(但可能被高负载影响) 基于优先级抢占,高优先级任务立即执行
典型应用 办公软件、网页浏览、游戏 汽车发动机控制、医疗设备、工业机器人

1.2 实时系统分类

类型 定义 举例
硬实时 错过截止时间会导致灾难性后果 安全气囊弹开、火箭姿态控制
软实时 错过截止时间仅影响体验,无致命后果 视频播放卡顿、鼠标移动延迟

二、RTOS系统架构

RTOS采用分层架构设计,从下至上依次为:

  • 硬件层:微控制器(CPU、内存、外设)
  • 硬件抽象层(HAL):CPU/外设接口封装
  • RTOS内核:任务调度器、任务间通信、内存管理、定时器
  • 组件层/中间件:文件系统(FATFS)、网络协议栈(LwIP)、设备驱动框架
  • 应用层:用户任务(读取传感器、控制算法、发送数据等)

三、核心机制

3.1 任务状态迁移

任务在RTOS中有四种基本状态:

  • 运行态:正在使用CPU
  • 就绪态:准备就绪,等待CPU调度
  • 阻塞态:等待事件(延时、信号量、队列)
  • 挂起态:被人工暂停,需要手动恢复

状态迁移关系:

  • 就绪态 → 运行态:调度器选择
  • 运行态 → 就绪态:被抢占/时间片用完
  • 运行态 → 阻塞态:等待事件
  • 阻塞态 → 就绪态:事件到达
  • 运行态 → 挂起态:调用vTaskSuspend
  • 挂起态 → 就绪态:调用vTaskResume

3.2 调度策略对比

调度策略 工作原理 特点 适用场景
优先级抢占式调度 高优先级任务可打断低优先级任务 实时性强,保证紧急任务优先 大多数RTOS默认策略
时间片轮转 同优先级任务轮流运行固定时间片 公平性好,防止任务饥饿 同优先级任务较多的场景
协作式调度 任务主动让出CPU才切换 简单,无抢占开销 任务简单、可控性高的系统

3.3 上下文切换流程

  1. 任务A正在运行
  2. 触发PendSV异常(任务切换)
  3. 硬件自动保存部分寄存器到A的堆栈
  4. 软件手动保存剩余寄存器到A的堆栈
  5. 更新堆栈指针,指向任务B的堆栈
  6. 软件手动恢复任务B的寄存器
  7. 硬件自动恢复任务B的剩余寄存器
  8. 任务B开始运行

四、任务间通信(IPC)

4.1 IPC机制对比表

通信机制 核心作用 典型应用场景 类比
队列 任务间传递数据 传感器数据采集与处理 像一个管道,放消息和取消息
信号量 任务间传递信号 ISR唤醒处理任务 像一个旗帜,表示”某事发生了”
互斥量 保护共享资源 防止全局变量同时访问 像一个钥匙,拿钥匙才能进厕所
事件标志组 任务等待多个条件 等待GPS和网络都就绪 像一个任务清单

4.2 优先级反转与继承

优先级反转场景

  1. 低优先级任务A获得共享资源锁
  2. 高优先级任务C就绪,请求同一资源被阻塞
  3. 中优先级任务B就绪,抢占A运行
  4. 结果:高优先级C被无关的中优先级B阻塞

解决方案:优先级继承

  • 当C被A阻塞时,A临时继承C的高优先级
  • A快速运行完并释放资源
  • A恢复原优先级
  • C获得资源继续运行
sequenceDiagram
    participant H as 高优先级任务C
    participant M as 中优先级任务B
    participant L as 低优先级任务A
    participant R as 共享资源

    Note over L,R: 步骤1:A获得资源锁
    L->>R: 获取锁(正在使用资源)
    
    Note over H: 步骤2:C就绪,抢占A
    H->>H: 开始运行
    H->>R: 请求资源锁(被A持有)
    R-->>H: 锁不可用,C进入阻塞
    
    Note over M: 步骤3:B就绪,抢占A
    M->>M: 开始运行(B优先级高于A)
    Note over H: 此时C被B间接阻塞
优先级反转发生 Note over L: 步骤4:优先级继承 L->>L: 临时继承C的优先级
快速运行释放锁 L->>R: 释放锁 R-->>H: 锁可用,C就绪 H->>H: 抢占B,获取锁运行

4.3 死锁必要条件

死锁发生的四个必要条件:

条件 说明
互斥条件 资源一次只能被一个任务使用
持有并等待 任务持有资源同时等待其他资源
不可剥夺 资源只能由持有者主动释放
循环等待 存在任务-资源的环形链

避免方法

  • 固定加锁顺序
  • 使用超时等待机制
  • 避免在持有锁时申请其他锁

五、内存与中断管理

5.1 FreeRTOS内存管理算法

算法 特点 适用场景
heap_1 只能申请不能释放 系统启动后不再释放内存
heap_2 最佳匹配,可能产生碎片 频繁申请释放但大小固定
heap_4 合并相邻空闲块,减少碎片 最常用,通用场景

5.2 ISR(Interrupt Service Routine 中断服务程序)设计原则

禁止行为 原因 正确做法
调用阻塞型API 会导致系统响应延迟 只释放信号量或发消息
执行耗时操作 阻塞其他中断和任务 快进快出,唤醒任务处理
使用不可重入函数 可能导致数据错乱 使用线程安全的函数

六、主流RTOS选型

RTOS名称 许可证 典型应用领域 核心优势
FreeRTOS MIT STM32、ESP32等MCU 开源免费、社区活跃,行业标准
RT-Thread Apache 2.0 物联网、消费电子 国产开源,组件丰富(GUI/网络)
Zephyr OS Apache 2.0 新兴物联网 Linux背书,模块化设计
VxWorks 商业 航天航空、军工 高可靠性,通过安全认证
QNX 商业 汽车电子、医疗 微内核架构,高度安全

七、面试高频考点速查表

考点 核心问题 关键回答要点
RTOS vs 裸机 有什么区别? 裸机是顺序循环,RTOS是多任务抢占
任务状态 有哪几种?如何迁移? 运行/就绪/阻塞/挂起
上下文切换 切换时发生了什么? 保存寄存器到堆栈,恢复新任务寄存器
调度算法 RTOS用什么调度? 优先级抢占 + 时间片轮转
优先级反转 是什么?如何解决? 中优先级阻塞高优先级,优先级继承解决
死锁 四个必要条件? 互斥/持有等待/不可剥夺/循环等待
ISR注意事项 ISR中不能做什么? 不能阻塞、不能耗时操作
任务饥饿 系统卡死可能原因? 高优先级任务一直运行不阻塞

八、项目经验

根据modem运行特点,我们内部做了一个专用的嵌入式RTOS,我们的业务逻辑都是在这个嵌入式操作系统上面运行(有些早期的产品是用Linux裁剪)。

Radio Setup的segment设定的build和execute时间优化的过于严格,导致少部分板子出现稳定性问题,概率性的crash。加入时间戳表格信息在校准的xml log中,超过设定时间的报fail并且不继续执行后续的流程不crash在tech侧,通过给部分bands的corner case重新优化build和execute的时间分配来解决。