我们做嵌入式的,这几年应该都听到过同一个词:Zephyr。圈内公认它技术底子好,内核设计、协议栈、设备模型全面,MCU 上跑 Linux 风格的开发体验,放在 RTOS 这个领域里,确实算得上“降维打击”。但吊诡的是,你在国内招聘网站上搜 RTOS 岗位,十有八九要求是 FreeRTOS 或 RT-Thread;打开各种开发板教程,默认也都是 FreeRTOS 移植;聊到国产实时操作系统,大家第一反应是 RT-Thread,而不是 Zephyr。
我也算是从裸机、FreeRTOS、RT-Thread 一路用到 Zephyr 的老兵,这篇文章就想认真聊聊:Zephyr 到底强在哪?为什么这么强的技术栈在国内就是“火不起来”?以及一个更值得思考的问题——我们常说的“本土独立生态”,到底应该怎么建,才不会变成一纸空谈。
这篇文章适合三类人:正在纠结 RTOS 选型的嵌入式工程师、带团队做技术规划的技术管理者,以及任何一个关心国内基础软件生态现状的开发者。我会尽量少讲空话,多讲实际操作里的感受、踩过的坑,以及我对“生态”这两个字的真实理解。
1. 先把话说清楚:Zephyr 的技术底子,到底强在哪里
1.1 内核特性:不是简单的调度器,而是一整套“内核 + 设备模型 + 驱动框架”
很多人在评价一个 RTOS 时,习惯只看它的任务调度算法、IPC 性能、中断延迟这些指标。这个视角不能说错,但用来衡量 Zephyr 就太窄了。Zephyr 的野心从来不是做又一个“小而美”的调度器,而是要做一块 MCU 上的通用操作系统底座。
首先是内核部分,Zephyr 的调度器支持协作式、抢占式、SMP 多核调度,甚至能把两种调度模式同时用在一个系统里,不同优先级的任务可以按需配置,这种灵活性在传统 RTOS 里很少见。内存管理也不只是简单的动态分配和静态池,它是按资源池隔离的,哪个子系统能申请多少内存、优先级高的任务能不能抢占剩余配额,都能够在构建期就做约束。这一点在安全苛求类场景里非常关键,你不需要靠代码自觉去规避内存碎片问题,架构层面就能给你兜底。
设备树(Devicetree)和统一驱动模型是另一个大杀器。用过 Linux 的同学应该很眼熟:硬件连接关系用一张 dts 文件描述,具体驱动的注册由内核去解析、自动匹配。这意味着如果你换了一块板子,只需要改设备树,驱动的厂商层代码几乎不用动。实际项目里我曾经把一套采集固件从 nRF52840 迁移到整机上的另一颗 MCU,半天时间就把原来的传感器、供电控制、通讯驱动全部跑通,这在 FreeRTOS 项目里是想都不敢想的节奏。
ZBus 消息总线、日志系统、shell 子系统、功耗管理框架、在线升级——这些在传统 RTOS 里都是“开发者自己造轮子还要造得歪歪扭扭”的部分,Zephyr 直接把它们做成了官方内置模块,开箱即用,而且模块之间解耦得相当干净。所以与其说 Zephyr 是一个 RTOS,不如说它是一整套“物联网/嵌入式软件平台基础设施”。
1.2 协议栈和生态组件:连接能力几乎是全包了
Zephyr 的网络协议栈非常完整。传统 RTOS 里,Wi-Fi 用一套 SDK、BLE 用另一套 SDK、LTE 又要配第三方协议栈,每个都是割裂的;Zephyr 把 BLE、802.15.4、Thread、Wi-Fi 甚至蜂窝网络协议栈都纳入到了统一的 Net 框架里。尤其是 BLE 部分,它在底层 controller 之上封装了一套类似 Linux BlueZ 的通用接口,上层应用写一遍,不同芯片厂家的 BLE 方案都能兼容。
这对做产品意味着什么?举一个很典型的场景:一个可穿戴项目,前期评估用了 Nordic 芯片,中期因为产能和成本被迫切换到了另一家国产 BLE SoC,客户的技术人员对 Zephyr 并不熟悉。但因为我方在应用层用的全部是 Zephyr 官方 API,底层蓝牙协议栈差异被消化掉了,应用代码几乎没有重写,重点只是适配了设备树和补了几个厂家驱动。这种“软硬件解耦”的能力,对一个产品能赶上上市窗口期非常关键。
你还可以在 Zephyr 里直接启用 MCUboot 做安全启动和 A/B 升级,用官方配套的west构建工具管理“主工程 + 各模块版本”,整个工具链和项目组织结构完全是为现代嵌入式协作模式设计的——Git manifest、模块化依赖、按需裁剪。说它“吊打一众 RTOS”,技术上不夸张。
2. 既然这么强,为什么在国内就是火不起来
2.1 学习曲线确实陡:从 51 到 FreeRTOS 很顺滑,从 FreeRTOS 到 Zephyr 就是另一套玩法了
必须承认,很多朋友接触 RTOS 是从正点原子、野火等开发板教程开始的,51 单片机跑个 FreeRTOS,建两三个任务、用一下消息队列和信号量,感觉“RTOS 也不过如此”。这种学习路径让 FreeRTOS 几乎成了嵌入式工程师心里的“默认 RTOS”,它的 API 简单直接,上手完全不需要前置概念。
Zephyr 则完全不同。你要用 Devicetree 去描述硬件,要明白 Kconfig 系统决定哪些功能会被编译进去,还要理解west构建工具里 module 和 manifest 的依赖关系。这些设计对经历过 Linux/嵌入式 Linux 开发的工程师非常友好,但对只做过简单单片机的学习者来说,就是一座陡峭的山。你先要知道 DTS 语法,再搞懂反正则表达式一样的编译裁剪逻辑,最后才能真正写外设驱动。整个人就像一个从裸机直接跨越到 Linux 驱动开发的难度,中间没有过渡缓冲。
还有一个很现实的问题:Zephyr 的资料深度确实不如 FreeRTOS。官方文档能解决“怎么做”的问题,但“为什么这样做”和“我在实际项目中遇到了什么问题”的博客、教程、录播课,国内加起来也比不上 FreeRTOS 和 RT-Thread 一家的产出。对绝大多数只想快点出成果、以找工作为导向的开发者,这个学习成本是要被现实权衡的。
2.2 芯片厂商的“最后一公里”支持,几乎是空白的
这一点我感触特别深。生态这个东西,技术好不好只是底层,真正决定开发者愿不愿意用的是一个“能不能顺利出活”的问题。而“顺利出活”最直接的依赖,就是芯片原厂/代理商的 FAE 支持。
在国内,如果你用 STM32 配 FreeRTOS,哪怕遇到问题,你随便拉个 FAE 都能给你现场调。用 RT-Thread,瑞萨、ST、恩智浦等厂商在国内都有专门的和合建生态的团队,遇到 BSP 问题能对接上人。但你要是说“我用 Zephyr 跑某某国产新出的 WiFi SoC”,对方大概率沉默几秒,然后跟你讲“这个我们不太熟,你先跑一下我们 SDK 里的裸机例程吧”。就这么一句话,就足以让项目负责人痛下决心换 RTOS。
真实项目里我踩过这个坑:因为缺一颗料,不得不把美国一颗 MCU 换成了一颗国产替代 MCU,替换方案在 FreeRTOS 上已经跑通了,但当我想在 Zephyr 上评估这颗替代料时,发现原厂只提供了自己的私有 SDK,Zephyr 下的 HAL 层和 BSP 根本没人维护。最后我只能被迫在新片子上启动两套开发框架:对外表现是 Zephyr 风格,底层悄悄包了一层原厂 SDK 的驱动。反过来说,这颗芯片要是从一开始就对 Zephyr 有官方支持,我在设计中就根本不需要这么别扭。
这也是标题里那句“我们需要一个本土独立生态”的真正痛点:Zephyr 的骨架国际团队做得再好,芯片适配、密钥认证、测试工具、区域化文档和厂商合作这些“本土的肉”,如果没有国内团队持续经营,它在国内开发者的实际项目里永远隔着一层。
2.3 学习路径与培训/招聘市场严重错配
我再聊一个比较现实的话题:招聘。现在打开招聘软件搜 RTOS,绝大多数岗位写的是“精通 FreeRTOS”“熟悉 RT-Thread”,几乎没有 JD 会强调 Zephyr。即便同样是“熟悉 FreeRTOS”,面试官往往关心的也是你有没有用信号量解决过多任务资源竞争、项目分区和内存安全设计,而不是操作系统本身。
这就形成了一个闭环:企业不缺用 Zephyr 的项目,但招聘时为了保险还是优先看 FreeRTOS/RT-Thread 经验的人;求职者为了得到 offer,也更愿意学这些“招聘 JD 里的技术”;培训机构和教程 UP 主为了点击量,自然就只做热门内容。于是,即便 Zephyr 技术再好,新人在入门阶段就被市场筛选机制带偏了。
作为一个过来人,我其实不太建议大家被这种“市场惯性”完全带跑。技术选型和职业规划是两码事:如果你的公司或项目需要高并发、高安全、跨平台兼容的 MCU 软件架构,Zephyr 的收益是实打实的;但如果你只是为了应付手里的开发板和跳槽面试,FreeRTOS 确实是性价比更高的选择。问题在于,国内几乎没有系统化的 Zephyr 学习路线图,大多数人看到了一大堆新概念,就卡在起点了。
3. 到底什么是“本土独立生态”?我们缺的一直不是另一个内核
3.1 别再喊“自主可控”这四个字了,先聊聊开发者体验
我挺反感某些人一提“国产 RTOS”,就搬出“自主可控”“核心技术”这类大词。做基础软件的都知道,生态的核心不是代码版权,而是开发者愿不愿意用、用了能不能降低综合成本。
如果某天我们真的需要“本土独立生态”,它所解决的问题绝不是“基底代码是哪儿来的”,而是一套东西:有没有本土化的中文文档和配套示例?有没有针对国内主流芯片的 BSP 和驱动包?有没有把企业级测试认证、故障排查、可靠性和高安全性讲透的课程?有没有厂商愿意像服务 FreeRTOS 用户一样服务这个社区?
举个例子:Zephyr 在国外的流行,很大程度上是被 Google、Nordic、NXP 等公司的产品需求和技术博客喂起来的。国内呢?我们有大量物联网模组厂、穿戴设备公司、智能硬件创业团队,大家其实都需要一套现代化 MCU 软件平台。但有趣的是,大家一边抱怨 Zephyr 没有生态,一边遇到实际问题时,还是习惯打开 FreeRTOS 或者自己维护一套 legacy 代码——这种“技术原子化”的状态反而让国内 Zephyr 生态永远长不大。
我做过一个小实验:把一份同样是“用传感器的数据通过 BLE 上报到手机”的需求,分别用 FreeRTOS 和 Zephyr 实现,Zephyr 在复用设备树、驱动框架、官方 BLE 协议栈的情况下,新增业务逻辑的代码量只有 FreeRTOS 方案的 60% 左右,而且可维护性高得多。所以生态形成的路径只有一个:让开发者看到选择新方案带来的“红利”大于迁移成本。如果圈子内整天只讨论“它多强却没人带新手跑通第一个工程”,那所谓本土生态就永远只是写在文章里的理想。
3.2 对比 RT-Thread:灵巧、接地气 vs 骨架大、门槛高
聊本土生态,不可能绕开 RT-Thread。它是我认为国内最接近“独立生态”的一次成功尝试:中文社区活跃、龙芯/国民技术等众多厂商积极适配、像正点原子这样的教学机构也专门出了全套视频。它的成功绝不只是代码本身,而是切中了国内嵌入式开发者的“即时满足感”——装包、建任务、调用 API,跑通 demo 的时间可以压缩到半小时以内。
但 RT-Thread 的问题也摆在那里:内核在非常复杂的高并发多核场景下,调优空间和成熟度跟 Zephyr 有明显差距;它的生态更多集中在外设驱动和中小型物联网产品,想承载类似“大规模传感器网络调度”“强大网络协议栈与 MCU 联动”这种场景,工程师要自己造的东西不少。
所以我一直认为,Zephyr 和 RT-Thread 不是零和博弈。前者像 Linux——骨架优雅、覆盖面广、适合作为整套系统底座;后者像 FreeRTOS 的现代增强版——简单直接、上手快、适合快速出原型和中小团队维护。国内嵌入式领域真正缺的,不是“再做一个 Zephyr/RT-Thread”,而是如何把 Zephyr 这样已经在上游验证过的底座,结合国内芯片和开发者的习惯,做出一层更友好的“本土化中间层”。
3.3 本土独立生态的可行路径:不是重写内核,而是搭建“中间层”
说个我自己的观察:如果一个国产芯片厂家愿意投入人力,为 Zephyr 适配一套完整的 BSP,并提供至少 3 款主流评估板的入门教程和 10 个参考项目,这个芯片进入开发者视野的速度会快得多。今天的 MCU 开发早就不是核心架构的比拼,而是生态和配套的比拼。谁能让开发者“第二天就点灯并跑起 WiFi/BLE 连接 demo”,谁就有机会成为下一个爆款 SoC。
所谓的“独立生态”,我理解下来有三层工作要做:
- 选一个靠谱的上游内核(Zephyr 本身是 Apache 2.0 协议,许可友好,商用自由度非常高),在这个内核之上构建面向国内芯片的驱动适配层、行业中间件、固件安全组件。
- 把文档、教程、社区答疑体系本土化。我不觉得国内开发者都抗拒英文文档,但面对一个生僻的 BLE errata 或 MCU 外设 ARM errata 时,母语能少走非常多的弯路。Zephyr 微信群、issue 区的中文回答,对一个生态早期的帮助比 10 个功能模块还重要。
- 与高校课程、认证培训结合,让新一代工程师在没进入职场前就有“我毕业后可能真的要用它来做东西”的感知,而不是靠跳槽季临时突击。
4. 亲历 Zephyr 项目:那些文档里不会告诉你的坑和技巧
前面聊了很多宏观视角,最后落回到具体实操。这一节我分享自己从 0 到 1 上手 Zephyr 项目的过程,以及踩过的一些比较有代表性的坑。
4.1 从 Demo 到工程化:构建系统、设备树、源码管理的三道坎
很多人拿到一块支持的开发板,跑官方 sample 通常很顺利:安装 west、拉代码、编译、烧录,十分钟搞定。但从 sample 到真正的产品化工程,会立刻撞上三道坎。
第一道坎是 Kconfig 的“全局以来”思维。传统 RTOS 里,你通常在一个头文件里手动配置任务优先级、堆栈大小、外设开关;Zephyr 里一切皆是 Kconfig 选项,而且选项之间还隐藏着依赖关系。我第一次尝试开启 USB 外设时,直接在prj.conf里写死了CONFIG_USB_DEVICE_STACK=y,结果编译失败,原因是底层的底层某个驱动依赖没有勾选,提示信息又十分晦涩。后来的经验是:新加一个子系统时,先搜官方 sample 里的prj.conf,复制它的配置组合,不要自己凭空猜。实际情况下,用menuconfig的界面逐层找选项也比直接看 Kconfig 定义直观得多。
第二道坎是设备树里的 address/size 概念。比如你接了颗 I2C 传感器,不是说在dts里声明一句compatible就完事了。你得意识到,设备树节点里有 reg 地址、interrupt 中断号、还有 pinctrl 引脚的匹配逻辑。有时你在 overlay 里面写错了 pinctrl 序号,系统能正常编译,但上电后传感器就是读不出数据,这类“无错误但行为异常”的问题非常熬人。我的建议是,第一次上手不要跳着学,一定把pinctrl和devicetree的基本概念过一遍,否则后面排查一次硬件兼容问题的时间足够你再学一遍。
第三道坎是项目的源码组织方式。Zephyr 的west把代码拆成很多独立仓库,项目自身也是一个 west module,manifest 里要维护依赖的版本、远程仓库地址、本地路径。这个设计其实是为了应对“多核、多模组、多供应商”的复杂软件供应链,但如果你自己维护一个小项目,第一次看到 manifest 文件里那一堆依赖会因为找不到逻辑而崩溃。后来我学到的做法是:产品级仓库单独建一个manifest文件,锁定所有第三方的版本;应用模块自己只放业务代码和 prj.conf;遇到上游更新时用west update精确控制版本,而不是每次都更新全量代码。
4.2 性能、功耗、稳定性的三个调优心得
跑通功能只是开始,产品级项目最关注的是功耗、实时性和长期稳定性。Zephyr 在这三块的“招式”和传统 RTOS 有本质区别。
功耗管理方面,传统做法是你自己根据外设的忙闲去手动调用 sleep、stop 模式,而且底层每个芯片的电源状态不一样,代码很容易写成一堆 ifdef。Zephyr 提供了一个电源管理框架(PM),它不是简单封装各家的低功耗 API,而是在系统 tick 空闲时通过 devicetree 自动配置各外设的电源状态,你只需要注册一个 PM action listener 来控制应用级的业务逻辑。实测下来,我用 nRF52840 做低功耗蓝牙传感器节点,跑 Zephyr 的 PM 框架之后,待机电流比原来手动 sleep 方式降低了大概 30%,而且代码删了几百行状态机逻辑。
实时性方面,Zephyr 对中断延迟的控制在所有 RTOS 属于第一梯队,但要注意,它的“实时性”是建立在你不乱开 Kernel 选项的前提下的。比如你开了 SMP、又开了比较复杂的 trace 工具,clk 源没有配置精确,很容易出现调度抖动比预期大很多的情况。我自己的经验是:生产环境务必基于 sample 的 minimal 配置在 menuconfig 里按需求增加功能,而不是默认全开之后再向下去除。
稳定性方面,一定要多看twister测试框架。Zephyr 官方自带了很多针对内核和驱动模块的 unit test,你只要用一条west twister命令,就能在目标板或 QEMU 上跑一遍一致性回归。我刚接触时没怎么用这个工具,后来一次升级了内核版本,莫名出现一个偶发 USB 问题,查了很久才发现是某个驱动跟新的 USB 框架不匹配。如果当时先跑一遍 twister 和相关驱动测试,几秒钟就能把这个问题暴露出来。
4.3 如何从零规划一个 Zephyr 学习路径
如果你的目标是真正掌握 Zephyr,而不是仅仅找一个替代 FreeRTOS 的方案,我建议你的学习顺序不要一上来就啃 kernel 源码:
- 先把 west 和 toolchain 装好,跑通三四个官方 sample,快速建立“我能掌控开发流程”的信心。
- 用一块主流开发板,尝试把它的板级配置从头写一遍。不满足于设备树能编译,要弄懂每个节点为什么存在。
- 从外设驱动入手,自己给开发板适配一颗“官方没有支持”的传感器。这个过程是理解设备模型和驱动框架的最佳路径。
- 完整看一遍官方文档中关于 Kernel 服务的那一章,此时你已经见过“用它”的样子,再来看“它是怎么设计的”,效率高很多。
- 启动一个小的产品级项目,哪怕是本地天气站,强迫自己做一次长稳测试、功耗优化和产品化封装。
我在实际带团队时发现,这个路径最合理的停留点在第四步前后。第五步需要现实项目推动,没有项目硬要造一个,往往动力不够。如果你正好有真实产品压着,那么直接进入第五步,遇到问题再反向补第 1~4 步的缺失点,反而效率更高。
5. 坦诚聊聊:本土化的 Zephyr 生态,现实阻碍到底在哪
5.1 时间、费用和人才:生态建设从来不是技术单维的较量
Zephyr 在 GitHub 上有大量的 issue 和 PR,每天几乎都有新的芯片适配、驱动提交。单是 upstream 这些代码就需要投入不少精力和测试时间——国内芯片厂商较多,这才是本土生态最难复制的环节:一个驱动从能用,到经过 CI、集成测试、性能验证、安全评估,得到上游认可,这个过程的成本对任何一家讲求 ROI 的公司来说都是“不小的负担”。
同时,Zephyr 领域的“精通级开发人才”非常稀少。大多数嵌入式工程师都沉浸在 FreeRTOS 的模式里,看得懂、改得动 Zephyr 设备树和 Kconfig 的人本来就不多,还要兼顾某一产品领域的业务逻辑、测试认证和现场问题排查,这样的人在市场上是抢手货。生态建设最缺的从来不是代码,而是既有工程能力、又愿意倒逼下巴去写文档、答疑、录课的人。
我还注意到一个有趣的细节:国内一些嵌入式工程师遇到 Zephyr 问题时,宁可去 Google/Zephyr 官方 Discord 用英文问,也不太敢在国内群里提问。这本来不是坏事,问题是用英文交流的门槛再一次把初学者挡住了。一个真正本土化的生态,需要有人愿意把这些英文问答沉淀成中文索引,并且长期滚动维护。
5.2 我们能做什么?生态不是等来的,是“用出来”的
聊了这么多,可能有人会问:“那我一个普通开发者,能对生态做什么?”说实话,生态建设不一定是厂商和社区领袖的事。只要你愿意在实际项目里多给 Zephyr 一次机会,踩了一个坑后把解决方案写下来——哪怕只是公众号里一篇 300 字的笔记——对这个生态都是实打实的增量。我在自己团队里定的规矩是:任何一个 Zephyr 相关的、排查超过 2 小时的 bug,必须写成一个 5 分钟能读完的 troubleshooting 文档,放在团队的 wiki 里。这个文档数量在一年后达到了 17 篇,很多新同事拿到问题清单就能直接定位问题,团队整体的 Zephyr 开发效率被明显拉高了。
如果你有精力,还可以直接给 Zephyr 上游提代码或者从 board defconfig 修起。别以为只有大厂才能做贡献,很多时候你只是修了一个 DAC 驱动的 Kconfig 依赖,上游维护者看到 PR 就会回复并帮你做 review。这种协作模式在国内的技术圈子里还很稀缺,但一旦跑通,你会感受到“我不是在给外国项目打工,而是在为全世界的嵌入式开发者和我自己铺路”。
6. 一个小建议:把 Zephyr 当作“一种思维”而不是“一个工具”
学了 FreeRTOS 再学 Zephyr,很多人总想找到“两个 OS 对应关系表”,然后用写 FreeRTOS 的方式去写 Zephyr。这是我见过大多数新手失败的原因。
Zephyr 的代表性不在于“支持多少个调度算法”,而在于它的设计哲学:用一套统一的构建体系和配置框架,去管理一个由不同厂商 IP 拼起来的复杂嵌入式系统。你把它学通之后,会发现你对“什么叫可维护的固件架构”的理解会更新一个层次。你再回过去看 FreeRTOS 或者其他国产 RTOS 时,看到的就不只是“API 列表”,而是它在哪些环节做了取舍、哪些环节设计得优秀、哪些环节可以被改成 Zephyr 的模式。
所以在国际社区早已把 Zephyr 推到极高成熟度的今天,我更愿意把 Zephyr 在中国的普及率,看作一道“生态系统经济学”的问题,而不是纯技术问题。它的本土生态不是靠某一家大公司发一个“战略合作”公告就能解决,而是需要一个又一个真实的项目去验证、去沉淀、去喂养。
如果你还没有试过 Zephyr,我强烈建议你从一块几十块钱的开发板开始,跑通第一个 sample,打开menuconfig看看那些成千上万的配置项。只要你能把这套“设备树描述硬件、Kconfig 裁剪软件”的思维带进自己的项目,你就会发现,所谓“独立生态”,最终靠的不是膜拜哪一套代码,而是我们这代人愿意用脚投票,为一套更现代化的开发范式买单。