banner
NEWS LETTER

嵌入式 RTOS 入门:任务、调度、队列、信号量和互斥锁

Scroll down

一、什么是 RTOS

RTOS 是 Real-Time Operating System,实时操作系统。它常用于单片机和资源受限设备中,用来管理多个任务、定时器、同步和通信。

常见 RTOS:

  • FreeRTOS。
  • RT-Thread。
  • Zephyr。
  • ThreadX。

RTOS 不等于 Linux。RTOS 更轻量,更关注实时性;Linux 功能更完整,但实时性需要额外配置才能增强。

二、为什么需要 RTOS

裸机程序通常是一个大循环:

1
2
3
4
5
6
while (1) {
scan_key();
read_sensor();
update_display();
upload_data();
}

项目变复杂后会遇到:

  • 某个任务阻塞影响其它任务。
  • 定时逻辑混乱。
  • 外设事件难管理。
  • 通信和采集耦合严重。

RTOS 可以把不同功能拆成任务。

三、任务

任务可以理解为轻量线程。

示例任务:

1
2
3
4
sensor_task    采集传感器
network_task 网络上传
ui_task 刷新显示
log_task 写日志

每个任务有:

  • 入口函数。
  • 栈空间。
  • 优先级。
  • 状态。

常见状态:

  • running。
  • ready。
  • blocked。
  • suspended。

四、调度

RTOS 根据优先级和任务状态调度。

基本原则:

  • 高优先级任务优先运行。
  • 阻塞任务不会占 CPU。
  • 延时、等待队列、等待信号量都会让任务进入阻塞。

不要在高优先级任务里长时间死循环,否则低优先级任务可能得不到执行。

五、队列

队列用于任务之间传递消息。

示例:

1
sensor_task -> queue -> network_task

传递内容可以是:

  • 传感器数据。
  • 事件类型。
  • 指针。
  • 命令。

队列适合解耦生产者和消费者。

六、信号量

信号量常用于事件通知或资源计数。

二值信号量:

  • 中断通知任务。
  • 任务等待某个事件。

计数信号量:

  • 管理多个相同资源。
  • 统计事件数量。

例如 UART 接收中断释放信号量,串口处理任务被唤醒后读取数据。

七、互斥锁

互斥锁用于保护共享资源。

共享资源包括:

  • 全局变量。
  • 日志输出。
  • I2C 总线。
  • SPI 总线。
  • 文件系统。

示例:

1
2
task A 使用 I2C 前先加锁
task B 使用 I2C 前也要加锁

这样可以避免两个任务同时访问同一条总线。

八、中断和任务

中断里应该尽量短:

  • 读取必要状态。
  • 清除中断标志。
  • 通知任务处理。

不要在中断里做:

  • 长时间循环。
  • printf 大量日志。
  • 阻塞等待。
  • 复杂业务逻辑。

常见设计:

1
ISR -> signal/queue -> task

九、常见问题

9.1 栈溢出

任务栈太小会导致异常。

处理:

  • 增大任务栈。
  • 减少局部大数组。
  • 检查 RTOS 栈水位。

9.2 优先级反转

低优先级任务持有锁,高优先级任务等待锁,中优先级任务一直运行,导致高优先级任务迟迟无法执行。

处理:

  • 使用支持优先级继承的互斥锁。
  • 缩短持锁时间。

9.3 死锁

多个任务互相等待资源。

处理:

  • 统一加锁顺序。
  • 减少嵌套锁。
  • 加超时。

十、总结

RTOS 的核心是任务调度和任务间通信。入门重点不是 API 名字,而是理解:

1
任务拆分 -> 优先级 -> 阻塞等待 -> 队列通信 -> 共享资源保护

能把这些概念用好,嵌入式裸机项目就能逐步走向更清晰的工程结构。

其他文章
目录导航 置顶
  1. 1. 一、什么是 RTOS
  2. 2. 二、为什么需要 RTOS
  3. 3. 三、任务
  4. 4. 四、调度
  5. 5. 五、队列
  6. 6. 六、信号量
  7. 7. 七、互斥锁
  8. 8. 八、中断和任务
  9. 9. 九、常见问题
    1. 9.1. 9.1 栈溢出
    2. 9.2. 9.2 优先级反转
    3. 9.3. 9.3 死锁
  10. 10. 十、总结
请输入关键词进行搜索