Skip to content

先搞懂它是什么

  • RTOS(实时操作系统):让多个“任务”看起来在同时运行的操作系统,嵌入式里最流行的是 FreeRTOS。
  • 任务(Task):一段独立执行的功能代码(如“采集传感器”“处理按键”“发送网络数据”各是一个任务),每个任务有自己的栈。
  • 调度器(Scheduler):决定“这一刻 CPU 归谁用”的裁判,按优先级和时间片切换任务。
  • 为什么必学:课程和面试几乎必考“任务状态机、优先级、信号量 vs 互斥锁”,也是从“裸机循环”走向复杂工程的必修课。

层层拆解原理

1. 任务状态机

状态含义是否占用 CPU
Running正在执行
Ready就绪排队,等调度器
Blocked等待事件/延时/队列否(不空转)
Suspended被挂起,需手动恢复

Blocked 是省电的关键:任务等待时让出 CPU,而不是空转“忙等”。

2. 抢占式调度:高优先级优先

FreeRTOS 默认抢占式:高优先级任务就绪时,立即打断正在运行的低优先级任务。因此:

  • 优先级数字越大越优先(与部分其他 RTOS 相反,注意区分)。
  • 同优先级任务之间靠时间片轮转(每个任务运行一个 tick 再换下一个)。
  • 调度只在“任务切换点”发生:任务阻塞/退出、时间片到、更高优先级就绪(中断里触发调度)。

3. 任务间通信与同步

任务之间不能直接“共享全局变量了事”,需要同步机制:

机制本质典型用途
队列(Queue)数据管道,生产者放、消费者取串口收数据传给处理任务
信号量(Semaphore)计数器,Give/Take事件通知、资源计数
互斥锁(Mutex)同一时刻只能一个任务持有保护共享资源(如同一 Flash)
事件组/任务通知位标志/直接通知多条件触发、轻量唤醒

信号量 vs 互斥锁(高频考点)

  • 信号量是“计数器 + 通知”,不关心谁持有谁释放,适合“事件发生”通知。
  • 互斥锁自带所有权(谁拿谁放),并支持优先级继承,用于保护临界资源。
  • 用错场景:拿互斥锁当信号量用(或反过来)会造成死锁或逻辑错误。

4. 临界区与优先级反转

  • 临界区(Critical Section):访问共享资源的代码段,需要关中断或持锁保护,防止任务切换导致数据不一致。
  • 优先级反转:低优先级任务持锁,高优先级任务等锁,结果高优先级反被低优先级“拖住”;FreeRTOS 的互斥锁用优先级继承缓解(低优先级临时提升到高优先级,尽快释放锁)。
  • 死锁:两个任务各自持锁又互相等对方,谁也不放。预防:统一加锁顺序、加超时、避免嵌套持锁。

结合 SDK 看实现

  • 相关例程页:FreeRTOS 操作系统、系统与软件

SDK 例程的骨架就是典型 RTOS 程序:main() 里创建任务,最后启动调度器,之后永远不再返回:

c
xTaskCreate(app_start_task, "app_start", 1024, NULL,
            configMAX_PRIORITIES - 2, &app_start_handle);
/* 启动调度器,任务开始运行;正常不会返回 */
vTaskStartScheduler();

任务内用队列/信号量与别人通信、用 vTaskDelay 让出 CPU,就是“任务化”的基本写法。

常见考点 / 面试题

FreeRTOS 里优先级数字越大越优先还是越小越优先?

数字越大优先级越高(与部分 RTOS 相反);同优先级用时间片轮转。

Blocked 状态和空转延时有什么区别?

Blocked 任务让出 CPU,调度器把 CPU 给别的任务,系统可休眠省电;空转 while 忙等会一直占用 CPU,浪费算力。

信号量和互斥锁的区别?

信号量是计数/通知机制,无所有权概念;互斥锁有所有权、支持优先级继承,专门保护临界资源,防优先级反转。

什么是优先级反转?FreeRTOS 怎么缓解?

低优先级任务持锁导致高优先级任务等待,形成“高被低拖住”。FreeRTOS 互斥锁通过优先级继承:把持锁任务临时提升到等待者的优先级,尽快释放锁。

临界区为什么要关中断?

访问共享变量时若发生任务切换/中断,数据可能被写坏。关中断/进入临界区保证这段代码原子执行,互斥锁保护的共享资源同理。

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23