FreeRTOS、RT-Thread、Zephyr 怎么选?三大 RTOS 架构差异与适用场景

FreeRTOS、RT-Thread、Zephyr 怎么选?从内核定位、设备模型、厂商生态、设备树、应用层代码和工程维护成本几个角度,对比三大 RTOS 的架构差异与适用场景。

FreeRTOS、RT-Thread、Zephyr 经常被放在一起比较,但这三个项目其实不在同一个层级。

如果只问“哪个 RTOS 更好”,答案很容易跑偏。更准确的问题应该是:你的项目到底需要一个轻量调度内核、一个带国产 MCU 生态的 RTOS,还是一个面向跨平台工程化的完整嵌入式操作系统。

从这个角度看,三者的定位可以先粗略分成这样:

  • FreeRTOS:行业标配级调度内核,外加 AWS 维护的一组 IoT 库。
  • RT-Thread:内核加较完整组件生态,对国内长尾 MCU 和中文社区更友好。
  • Zephyr:Linux Foundation 托管的完整 RTOS,强调统一子系统、设备模型、Devicetree 和跨厂商应用复用。

先说结论

如果项目只是小 MCU、简单任务调度、信号量、队列、定时器,FreeRTOS 仍然是最稳的选择之一。

如果项目主要面向国内 MCU,尤其是 AT32、HC32、N32、APM32、HT32、合宙等长尾芯片,并且团队希望中文资料、BSP 和社区反馈更顺手,RT-Thread 很有优势。

如果项目需要跨芯片、跨板卡、跨厂商复用应用层代码,并且愿意接受 Kconfig、Devicetree、west、驱动模型带来的学习成本,Zephyr 更像是面向未来工程化的路线。

所以这不是“谁淘汰谁”的问题,而是三种工程抽象层级不同。

FreeRTOS:最强的是轻量和确定性

FreeRTOS 的核心优势,是足够小、足够熟、足够普及。

它的主仓库 FreeRTOS-Kernel 重点就是内核、移植层和核心 RTOS 机制。任务调度、信号量、消息队列、事件组、软件定时器、内存分配策略,这些是绝大多数项目真正使用的部分。

FreeRTOS 的好处很直接:

  • MCU 覆盖极广。
  • 学习资料和工程案例最多。
  • 可以很容易塞进芯片厂商 SDK。
  • 适合资源很紧、需求很明确的小系统。
  • 出问题时定位路径短,很多团队已有经验积累。

AWS 收购 FreeRTOS 后,又围绕它维护了 coreMQTT、coreHTTP、OTA、Device Shadow、Jobs、Defender 等 IoT 相关库。FreeRTOS 202406 LTS 也把内核、TCP、MQTT、HTTP、OTA 等组件纳入长期支持路线。

但 FreeRTOS 的边界也很清楚:它本质上不是一个“完整 OS 平台”。GPIO 怎么抽象、UART 怎么读写、I2C 怎么挂设备、不同厂商 HAL 怎么统一,FreeRTOS 自己并不负责。

换句话说,FreeRTOS 给你的主要是内核。驱动层、设备模型、板级抽象和应用框架,要么依赖芯片厂商 SDK,要么由团队自己搭。

这不是缺陷,而是设计选择。它让 FreeRTOS 非常灵活,也让它很容易和 ST、NXP、TI、瑞萨、乐鑫等厂商 SDK 组合。但代价是:换芯片、换板子、换 HAL 时,应用层往往也会被牵连。

RT-Thread:优势在国内 MCU 和组件生态

RT-Thread 比 FreeRTOS 更接近一个完整 RTOS。

它不只是调度器,还提供文件系统、网络协议栈、设备框架、USB、传感器框架、组件包和工具链。对很多国内团队来说,RT-Thread 的中文文档、ENV 工具、社区氛围和国产 MCU BSP 是很实际的优势。

尤其在国内长尾 MCU 上,RT-Thread 的支持面很有价值。很多项目并不使用头部国际厂商芯片,而是会选 AT32、HC32、N32、APM32、HT32、合宙、先楫等国产 MCU。对这类项目,RT-Thread 往往能更快拿到可跑的 BSP 和中文资料。

RT-Thread 适合这些场景:

  • 团队主要使用国产 MCU。
  • 需要中文社区和本土资料。
  • 需要比 FreeRTOS 更完整的组件生态。
  • 项目希望快速接入文件系统、网络、shell、设备框架等能力。
  • 团队不想从零搭一套板级和驱动抽象。

但 RT-Thread 也有自己的限制。

第一,它的很多 BSP 仍然是围绕具体板卡和厂商库组织。虽然有设备框架,但从跨厂商统一硬件描述和应用层无感迁移的角度看,还没有达到 Zephyr 那种系统性。

第二,RT-Thread 对国内长尾 MCU 很友好,但在一些头部芯片和国际厂商主线维护上,Zephyr 的势头已经很强。比如乐鑫、Nordic、NXP、瑞萨等厂商,在 Zephyr 生态中的官方投入越来越明显。

第三,RT-Thread 的设备树路线还没有真正成为 MCU 侧的主流工作方式。它有 ofw 相关框架,但在 Cortex-M 这类 MCU 项目里,还不能像 Zephyr 那样形成贯穿构建系统、驱动匹配、应用层配置的统一机制。

所以 RT-Thread 的定位更像:在 FreeRTOS 之上补齐了很多常用系统组件,并且在国内 MCU 生态里非常实用。但它还不是 Zephyr 那种从构建、配置、驱动、设备模型到应用层都统一规划的工程平台。

Zephyr:不是“另一个 RTOS”,而是一套系统工程

Zephyr 容易被误解为“比 FreeRTOS 更复杂的 RTOS”。这个说法只说对了一半。

它确实更复杂,但复杂的原因不是单纯堆功能,而是它试图把 MCU 项目里长期散落在厂商 SDK、BSP、HAL、手写驱动、配置脚本里的东西,统一进一个操作系统工程。

Zephyr 的关键不只是调度器,而是这些东西:

  • Kconfig:管理功能开关和编译配置。
  • Devicetree:描述板级硬件和外设连接。
  • drivers:统一 GPIO、UART、SPI、I2C、ADC、DMA、clock、reset、pinctrl 等外设接口。
  • subsys:提供网络、蓝牙、USB、文件系统、输入、电源管理、日志、设置存储等子系统。
  • west 和 CMake:管理工程、模块、构建、下载和调试。
  • 板卡 / SoC / shield 抽象:把硬件差异收敛到配置层。

这使得 Zephyr 更像一个“嵌入式 Linux 的 MCU 缩小版”:它继承了 Linux 世界的很多工程思想,但把运行时 probe 那套不适合小 MCU 的机制,改造成了编译期展开。

Zephyr 的 Devicetree 为什么关键

Devicetree 是理解 Zephyr 的关键。

在 Linux 里,DTS 通常会编译成 DTB,由 bootloader 传给内核,内核启动后再解析设备树、匹配驱动、执行 probe。这个运行时模型对 MPU 和大内存系统很合理,但对一颗几十 KB 到几百 KB RAM 的 MCU 来说太重。

Zephyr 的做法不一样。它在构建阶段处理 DTS / overlay,把硬件描述生成 devicetree_generated.h 这类头文件,再通过 DT_ 宏给驱动和应用使用。换句话说,硬件描述和驱动选择在编译期就基本确定,运行时不需要再做一套沉重的设备发现。

这个设计带来几个好处:

  • 硬件描述和应用代码分离。
  • 换板子主要改 DTS / overlay。
  • 驱动通过统一 API 暴露给应用。
  • 未启用的驱动和子系统可以被裁掉。
  • 应用层不必直接关心具体寄存器、引脚和厂商 HAL。

比如一个 LED 或按键,在传统 FreeRTOS + 厂商 HAL 工程里,通常会散落在 CubeMX 配置、GPIO 初始化、回调、中断、去抖、状态机和应用代码里。到了 Zephyr,很多信息可以放进 DTS,应用层只通过 LED、GPIO 或 input 子系统接口处理事件。

这就是 Zephyr 的工程化价值:不是让简单 demo 看起来更短,而是让复杂项目的硬件差异尽量不污染业务代码。

应用层代码为什么会变干净

传统 MCU 工程里,应用代码经常混着这些内容:

  • 硬件初始化。
  • GPIO 引脚号。
  • 中断配置。
  • 去抖逻辑。
  • 定时器和状态机。
  • 串口重定向。
  • 事件队列。
  • 业务处理。

项目一开始不大时,这样写很快。但随着外设变多、板卡变多、产品线变多,应用层会越来越像 BSP 的延伸。

Zephyr 的目标是把这些内容拆开:

  • 硬件连接放到 DTS / overlay。
  • 功能开关放到 Kconfig / prj.conf。
  • 驱动放到 Zephyr 主线或模块。
  • 应用只处理业务事件。

因此,同样是 LED 闪烁、按键短按、长按、双击、三击这类功能,在 Zephyr 里更容易变成“少量业务代码 + 配置文件”。换板卡时,理想状态是改 DTS,不改 main.c

这对单板 demo 未必显得划算,但对多板卡、多芯片、多代产品的团队,价值会越来越明显。

资源占用不能只看第一眼

很多人第一反应是:Zephyr 这么大,资源占用肯定高。

这个判断要拆开看。

Zephyr 的 Flash 通常会因为统一驱动、子系统、设备模型而比裸 FreeRTOS 工程多一些。这部分不是纯“内核开销”,而是你买下了一套可复用基础设施。

比如 input 子系统、LED 驱动、GPIO 驱动、定时器、日志、设备对象等,都会占空间。但后续再加旋钮、编码器、更多按键、更多输入设备时,很多基础设施可以复用,不是每个功能都重新手写一套。

RAM 也类似。FreeRTOS 工程里常见的 heap 预留、任务栈预留、队列缓冲可能会让报表看起来更大;Zephyr 更强调静态对象和链接期裁剪。具体谁更省,要看配置、功能、编译选项和实际场景,不能只拿空工程对比。

更实用的判断方式是:

  • 如果功能很少、板卡固定、资源极紧,FreeRTOS 可能更省。
  • 如果外设多、板卡多、驱动复用多,Zephyr 的“基础设施成本”会被摊薄。
  • 如果团队没有时间学习 Zephyr,复杂性本身就是成本。

三者怎么选

可以按项目形态来选。

选择 FreeRTOS

适合:

  • 项目资源很紧。
  • 只需要调度、队列、信号量、定时器。
  • 硬件平台固定。
  • 已经有成熟厂商 SDK。
  • 团队对 FreeRTOS 很熟。
  • 不需要跨厂商统一设备模型。

典型判断:你需要的是一个可靠内核,而不是一整套 OS 工程框架。

选择 RT-Thread

适合:

  • 使用国产 MCU 较多。
  • 需要中文社区和中文资料。
  • 希望快速拿到 BSP、组件包和常用系统能力。
  • 项目规模比纯 FreeRTOS 大,但还不想全面进入 Zephyr 学习曲线。
  • 团队希望在本土生态里解决问题。

典型判断:你需要的是“FreeRTOS 之上更多组件 + 国产 MCU 友好生态”。

选择 Zephyr

适合:

  • 项目要跨多块板、多颗芯片、多家厂商。
  • 希望应用层尽量不绑死具体硬件。
  • 重视长期维护和主线升级。
  • 需要蓝牙、网络、USB、文件系统、输入、电源管理等统一子系统。
  • 团队愿意学习 Kconfig、Devicetree、west 和 Zephyr 驱动模型。
  • 未来希望和 Linux 工程思想接轨。

典型判断:你需要的是一套完整的嵌入式系统工程平台,而不仅是 RTOS 内核。

什么时候不该用 Zephyr

Zephyr 不是银弹。

这些情况下不建议上来就选 Zephyr:

  • 项目只有一个固定板卡,功能很简单。
  • 团队没有时间学习 Kconfig 和 Devicetree。
  • 芯片或板卡在 Zephyr 主线支持很弱。
  • 项目强依赖某个厂商 SDK 的私有闭源能力。
  • 产品已经稳定量产,迁移收益不明显。
  • 团队调试和构建环境还没有准备好。

Zephyr 的学习成本是真实存在的。它的错误信息、构建系统、Devicetree 绑定、Kconfig 依赖、module 管理,对传统裸机 / FreeRTOS 开发者来说都需要适应。

所以更合理的路线是:先选一块 Zephyr 主线支持好的开发板,用一个小功能跑通 LED、UART、GPIO、input、I2C / SPI,再决定是否迁移真实项目。

AI 时代为什么更要读好代码

现在很多人会说:有 AI 了,底层框架没必要学那么深,直接让模型写代码就行。

这个想法很危险。

AI 能把候选代码摆在你面前,但把代码合进去、烧进固件、交给客户设备运行的人,仍然是工程师。AI 不会为设备召回负责,人会。

嵌入式项目里,真正稀缺的不是“多写几百行代码”的能力,而是判断力:

  • 这段代码为什么这么写?
  • 这层抽象值不值得?
  • 这个驱动接口能不能长期维护?
  • 这个配置变更会不会影响别的板卡?
  • 这段 AI 生成代码能不能进入量产固件?

Zephyr 的价值之一,就是提供了一套工业级嵌入式系统架构样本。即使最后项目不选 Zephyr,读懂它的子系统、设备模型、Devicetree、Kconfig 和驱动组织方式,也会提升你判断嵌入式架构好坏的能力。

总结

FreeRTOS、RT-Thread、Zephyr 不是同类产品的简单三选一。

FreeRTOS 是轻量、成熟、普及的 RTOS 内核,适合固定硬件和清晰任务调度场景。RT-Thread 是更完整的 RTOS 生态,尤其适合国内 MCU、中文社区和快速组件集成。Zephyr 则是更系统化的嵌入式操作系统工程,适合跨厂商、跨板卡、长期维护和应用层复用。

如果只做一个小设备,FreeRTOS 可能就是最省事的答案。如果做国内 MCU 产品线,RT-Thread 的生态会很实际。如果你面对的是多平台、多板卡、多外设和长期演进,Zephyr 值得认真投入。

真正的差距,不是 API 多几个少几个,而是工程抽象层级:FreeRTOS 解决调度,RT-Thread 补齐组件,Zephyr 试图重构 MCU 软件工程的组织方式。

参考链接:

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计