Zephyr - 特别篇|Higgsfield 原创系列(2026):为什么它正在成为嵌入式开发者的“第二个 Linux”
2026 年再讨论嵌入式 RTOS,很多人会默认“选 FreeRTOS 准没错”。这个判断放在五年前基本成立,但放在今天已经不够准确了。原因很简单:当你的产品开始需要联网、需要 OTA、需要复杂的电源管理、需要多协议栈共存时,FreeRTOS 能做的和你真正想做的事情之间,会拉开一条巨大的鸿沟。
Zephyr 在这条鸿沟上搭了一座桥。它不是一个传统的、以最小资源占用为唯一目标的 RTOS,而是一整套面向连接设备和物联网场景的操作系统级解决方案。这篇文章不是帮你“再认识一个 RTOS”,而是用实际开发链路告诉你:Zephyr 到底解决了什么问题,它在 2026 年嵌入式项目选型中应该摆在什么位置,以及你从零开始搭建 Zephyr 环境、配置 Kconfig、写一个能跑起来的工程,要经过哪些步骤。
无论你是做 MCU 应用开发、物联网网关、可穿戴设备,还是正在考虑把现有 FreeRTOS 项目迁移到 Zephyr,读完这篇文章后,你对“该不该用 Zephyr”这个问题会有一个清晰的技术判断。
1. 这篇文章真正要解决的问题
很多工程师第一次接触 Zephyr 时,第一个反应是:这个系统怎么这么“重”?又是 Kconfig、又是 Devicetree、又是 west 工具链,一个 Hello World 都要配置半天。相比之下,FreeRTOS 只需要加两个 C 文件就能跑起来。
但如果你正在做的事情超出了“点亮 LED”或“跑一个任务调度”的范畴,体验会完全不同。
举一个典型场景:你要做一个带有 BLE、Wi-Fi、FOTA 升级和低功耗管理的智能家居设备。用传统 FreeRTOS 方案,你需要自己选协议栈(是 NimBLE 还是 Zephyr 自带的)、自己对接 OTA 分区表、自己处理不同硬件版本的板级差异、自己设计功耗控制框架。这些工作不是不能做,而是大量时间会花在“搭框架”而不是“做产品”上。
Zephyr 换了一种思路:把内核、驱动、协议栈、电源管理、构建系统全部纳入一个统一框架。你不再需要反复拼装不同开源项目,而是通过配置系统按需裁剪。这正是它和 FreeRTOS 在 2026 年最本质的区别:FreeRTOS 是“一个调度器”,Zephyr 是“一个系统”。
所以这篇文章的核心目标有三个:
第一,帮你建立 Zephyr 的正确心智模型。它不是“复杂版的 FreeRTOS”,而是“面向 MCU 的类 Linux 工程体系”。
第二,给你一份可落地的环境搭建和工程运行指南,包括 west 工具链、Kconfig 配置、Devicetree 基本用法。
第三,用表格和场景对比 Zephyr 和 FreeRTOS 的差异,让选型这件事有依据,而不仅仅是凭感觉。
2. Zephyr 基础概念:Kconfig、Devicetree 与 west 工具链
在动手之前,先把 Zephyr 的三个核心概念说清楚。这三个概念理解了,后面所有配置和编译过程都不会觉得别扭。
2.1 Kconfig:不再靠宏定义开关功能
Kconfig 最早来自 Linux 内核配置体系,Zephyr 把它完整带到了 MCU 领域。它的作用是在编译之前,决定“这个固件包含哪些功能模块”。
传统 RTOS 的做法是在代码里写一堆#ifdef XXX_ENABLE。功能少的时候没问题,功能上百个之后,宏管理的复杂度会非常高。Kconfig 把这个过程集中到统一的配置入口,所有可选项都有清晰的依赖关系。
比如你想启用某种传感器驱动,只需要在配置文件中加上:
CONFIG_BOARD_GPIO_SENSOR=y CONFIG_SENSOR_LOG_LEVEL_INF=y系统会自动检查这个驱动依赖哪些硬件资源、是否和当前板卡兼容、是否需要连带开启其他配置项。
2.2 Devicetree:硬件描述与代码逻辑分离
Devicetree(设备树)也是从 Linux 引入的概念。它的作用,是用一套统一的数据格式描述硬件拓扑:CPU 内核、内存地址、外设寄存器、中断号、引脚复用。
这样做的好处在于:当你的产品换了同系列但引脚不同的 MCU 时,不需要改 C 代码,只要改设备树文件里的引脚描述即可。这在传统 STM32 裸机开发中几乎不敢想象。
// 文件路径:boards/board_name/board_name.dts / { model = "Example Board"; compatible = "example,board"; leds { compatible = "gpio-leds"; red_led: led_0 { gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; label = "Red LED"; }; }; };2.3 west:一切命令的统一入口
west 是 Zephyr 的项目管理工具,类似 Linux 下的 repo,但它做的事情更多:拉取代码、管理多仓库版本、编译、烧录、调试,全部通过 west 完成。
初次接触 Zephyr 的人最容易被 west 绕晕。其实只需要记住两件事:
第一,west 的所有子命令都与项目构建流程相关,比如west build、west flash、west debug。
第二,west 管理的是一个 workspace,也就是以 zephyr 主仓库为中心的一组相关仓库。整个 Zephyr 生态不是单一代码库,而是由 zephyr、hal_stm32、hal_nordic、mcuboot 等多个仓库组成的集合。
3. Zephyr 与 FreeRTOS 深度对比:2026 年嵌入式项目选型参考
这一章节直接给结论:Zephyr 和 FreeRTOS 在 2026 年并不是完全对立的替代关系,而是两种不同项目需求下的不同答案。下面从六个维度做对比。
| 对比维度 | Zephyr | FreeRTOS |
|---|---|---|
| 本质定位 | 面向物联网和连接设备的操作系统 | 轻量级实时调度内核 |
| 内核最小体积 | 几十 KB 级,可以裁剪 | 几 KB 级,极致轻量 |
| 硬件抽象层 | Devicetree + 驱动框架,统一接口 | 无标准硬件抽象,驱动由厂商提供 |
| 协议栈支持 | BLE、Wi-Fi、Thread、Zigbee、802.15.4 等原生集成 | 需自行集成第三方协议栈 |
| 构建系统 | CMake + west,支持 Kconfig 配置 | Makefile / CMake,无统一配置体系 |
| 许可证 | Apache 2.0 | MIT(内核部分) |
| 主要适用场景 | 智能家居、可穿戴、工业物联网、车联网 | 简单任务调度、资源受限 MCU、教学 |
| 社区生态 | Linux 基金会主导,厂商参与度高 | 生态成熟,资料海量 |
从这张表可以提炼出三个关键判断。
第一,如果项目只有一个传感器采集任务和一个上报任务,MCU 资源极度紧张,FreeRTOS 仍然是最好的选择。它轻、快、稳定,而且团队里几乎人人都会用。
第二,如果项目需要同时跑 BLE 和 Wi-Fi,还要考虑 OTA 和功耗管理,Zephyr 的集成度优势非常明显。你不会想把 NimBLE、LwIP、MCUboot 一个个手动拼起来。
第三,Zephyr 的学习曲线更陡,但学到的知识可迁移性强。因为它背后的 Devicetree、Kconfig、CMake 体系,和 Linux 开发经验是相通的。换句话说,学会 Zephyr,你掌握的其实是一套更接近现代嵌入式工程化的思维。
4. Zephyr 环境搭建与基础配置
明确一下环境假设:本文以 Ubuntu 22.04 或 Windows 10/11 + WSL2 为主要开发环境。如果你只装了 Windows 原生环境,建议优先装一个 WSL2,因为 Zephyr 的官方工具链脚本对类 Unix 环境支持最好。这不是说 Windows 完全不可行,而是从工程效率角度,WSL2 会让后续操作顺畅很多。
4.1 安装必要依赖
无论什么环境,先确保 Python 版本在 3.8 以上,并准备好 pip 和 cmake。下面以 Ubuntu 环境为例:
sudo apt update sudo apt install --no-install-recommends git cmake ninja-build gperf \ ccache dfu-util device-tree-compiler wget \ python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \ make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1这里用到dfu-util是因为很多 Zephyr 支持的开发板通过 DFU 模式烧录;device-tree-compiler用来编译设备树;ninja-build是 Zephyr 默认的构建后端,比 Make 快很多。
4.2 安装 west 并初始化工作目录
Zephyr 不推荐直接把源码 clone 到任意文件夹,而是用 west 创建一个规范的 workspace。建议给代码单独建一个目录,例如zephyrproject。
pip install west mkdir ~/zephyrproject && cd ~/zephyrproject west init west updatewest init会拉取默认的 manifest 文件,west update则会根据 manifest 把 zephyr、hal 库、第三方模块全部下载到本地。这个操作需要联网,首次拉取数据量在 1GB 以上,耐心等待即可。
4.3 安装编译工具链
Zephyr 官方推荐使用 Zephyr SDK。SDK 里包含了针对不同架构的交叉编译器、调试器和 QEMU 支持。
cd ~ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/latest/download/zephyr-sdk-<VERSION>_linux-x86_64.tar.xz tar xf zephyr-sdk-<VERSION>_linux-x86_64.tar.xz cd zephyr-sdk-<VERSION> ./setup.sh安装完成后,把工具链路径导出到环境变量中:
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-<VERSION> export ZEPHYR_TOOLCHAIN_VARIANT=zephyr注意:<VERSION>请替换为你实际下载的 SDK 版本号,不要照抄。如果你使用的开发板是 STM32 系列,也可以直接用 ARM GCC 工具链,但用 Zephyr SDK 能少踩很多版本匹配的坑。
4.4 环境变量验证
安装完成后,验证环境是否基本就绪。进入 zephyr 仓库目录并查看版本信息:
cd ~/zephyrproject/zephyr source zephyr-env.sh west --version如果能看到 west 版本号和 Zephyr 版本提示,环境就基本搭建完成了。
5. 使用 Workbench for Zephyr 与 Kconfig 图形化配置
Zephyr 的 Kconfig 体系在命令行下确实能完成所有配置,但配置项太多时,记忆成本很高。这就是“Workbench for Zephyr”这类工具能发挥作用的地方。
5.1 什么是 Workbench for Zephyr
简单说,Workbench for Zephyr 是基于 VS Code 的图形化开发环境。它将工程管理、Kconfig 配置、编译、烧录、调试集成到一个界面中,降低纯命令行操作的认知负担。对于刚接触 Zephyr 的开发者,它可以让你先通过图形界面理解配置体系,再逐步过渡到命令行。
在 2026 年的实际开发中,团队里往往是懂内核的人用命令行,应用层开发者在 Workbench 中完成日常构建和调试。
5.2 Kconfig 图形化配置入口
即使不使用 Workbench 的完整 IDE,Zephyr 自身也提供了终端 UI 方案。进入任意一个 build 目录后运行:
west build -t guiconfig系统会打开图形化配置界面。你也可以用:
west build -t menuconfigmenuconfig 是基于终端菜单方式的配置界面,操作逻辑与 Linux 内核配置完全一致。对于习惯键盘操作的人,这种方式的效率反而更高。
在实际项目里,我们更常采用的方式是直接维护prj.conf文件。下图是一个典型的 BLE 项目配置:
# 文件路径:prj.conf CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="Zephyr_BLE_Device" CONFIG_BT_PRIVACY=y CONFIG_LOG=yKconfig 的价值在于:它把所有功能开关收敛到可审查、可版本管理的配置文件中,而不是散落在代码各处。这一点在后期的工程维护中价值极大。
6. Zephyr 完整示例:最小工程编译与运行
现在进入真正的实操环节。我们从一个最基础的 Hello World 工程开始,再到一个带 GPIO 控制的 Blinky 工程,完整跑通编译、烧录、验证的整个流程。
6.1 Hello World 示例
Zephyr 官方自带大量示例,Hello World 位于zephyr/samples/hello_world。先查看目录结构:
cd ~/zephyrproject/zephyr/samples/hello_world ls -l核心文件有三个:
prj.conf:工程配置文件,本示例中保持为空即可。src/main.c:程序入口。CMakeLists.txt:构建脚本。
main.c的内容如下:
// 文件路径:samples/hello_world/src/main.c #include <zephyr/kernel.h> #include <zephyr/sys/printk.h> void main(void) { printk("Hello World! %s\n", CONFIG_BOARD); }注意这里的头文件写法。<zephyr/kernel.h>是 Zephyr 2.6 以后推荐的标准头文件路径,老代码里常见的<zephyr.h>如今也会被兼容,但新项目建议统一使用带zephyr/前缀的路径。
6.2 编译命令
在 hello_world 目录下执行:
west build -b qemu_cortex_m3这里-b指定目标板卡。qemu_cortex_m3是模拟的 Cortex-M3 开发板,不需要真实硬件就能验证编译和运行流程。如果你手上有具体的开发板,例如nucleo_f103rb或nrf52840dk_nrf52840,直接替换板卡名即可。
第一次编译会初始化构建目录并下载相关依赖,可能需要几分钟。
6.3 运行与验证
因为目标平台是 QEMU 模拟板,编译完成后可以直接用 QEMU 运行:
west build -t run如果一切正常,终端会输出类似下面的结果:
*** Booting Zephyr OS build zephyr-v3.x-xxxx *** Hello World! qemu_cortex_m3看到这行输出,说明 Zephyr 的最小系统已经成功运行。
6.4 Blinky 示例:GPIO 与设备树结合
接下来做一个小而完整的硬件示例。以nrf52840dk_nrf52840开发板为例,演示如何通过设备树配置 LED 引脚。
官方 Blinky 示例路径是samples/basic/blinky,其main.c核心逻辑如下:
// 文件路径:samples/basic/blinky/src/main.c #include <zephyr/kernel.h> #include <zephyr/drivers/gpio.h> #include <zephyr/devicetree.h> #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); int main(void) { if (!device_is_ready(led.port)) { return -1; } gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); while (1) { gpio_pin_toggle_dt(&led); k_msleep(500); } return 0; }这段代码很短,但包含两个重要知识点:
第一,DT_ALIAS(led0)通过设备树别名获取 LED 节点的引用,实际引脚在nrf52840dk_nrf52840.dts中定义。
第二,gpio_pin_configure_dt和gpio_pin_toggle_dt是 Zephyr 的新版 GPIO API,它们自动适配设备树里的引脚配置,开发者不需要手写寄存器操作。
编译命令:
west build -b nrf52840dk_nrf52840 samples/basic/blinky west flash烧录成功后,开发板上的 LED 会以 0.5 秒间隔闪烁。
7. Devicetree 机制:Zephyr 硬件抽象的精髓
如果说 Kconfig 解决了“软件功能怎么选”,Devicetree 解决的就是“硬件资源怎么描述”。这一章用通俗的语言拆解 Devicetree,因为它是许多 Zephyr 初学者最不容易跨过的坎。
7.1 没有 Devicetree 时的开发方式
传统 MCU 开发中,开发者通常依赖厂商提供的 HAL 库。比如 STM32 项目里,要让某个引脚输出高电平,需要打开.ioc文件,在可视化界面里配置引脚模式,然后重新生成初始化代码。一旦换了引脚或 MCU 型号,需要重新生成工程。
这种方式的缺点在于:硬件配置过程和业务代码是强绑定的,板级资源变更会直接引发代码级修改。
7.2 Devicetree 的解决思路
Devicetree 将硬件描述固化成文本文件,与 C 代码分离。当硬件引脚变化时,只改 dts 文件,不需要改 main.c。
看一个实际的 LED 定义:
/ { aliases { led0 = &red_led; }; leds { compatible = "gpio-leds"; red_led: led_0 { gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; label = "Red LED"; }; }; };这段描述告诉系统两件事:LED 连接在 GPIO0 的第 13 号引脚,低电平有效。对应的 C 代码只需要通过DT_ALIAS(led0)获取引用,系统会自动完成寄存器映射。
7.3 使用 Overlay 文件做板级适配
实际项目更常见的情况是:开发板本身有默认的设备树,但你的产品硬件改了引脚。这时候不要直接修改厂商板级 dts 文件,而是使用 overlay 文件覆盖。
在工程根目录下创建app.overlay:
// 文件路径:app.overlay / { aliases { led0 = &custom_led; }; }; &gpio1 { status = "okay"; }; custom_led: led_custom { compatible = "gpio-leds"; gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; label = "Custom LED"; };然后在CMakeLists.txt中指定:
set(DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/app.overlay")这样,同一套业务代码可以支持不同引脚定义的不同硬件版本。在产品线需要做到“一套固件多种硬件”时,这个能力非常有价值。
8. Zephyr 常见问题与排查方法
从环境搭建到实际编译,开发者最常遇到的坑集中在工具链匹配、依赖下载速度和设备树配置三个方面。下面整理成表格,方便日常检索。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
west init拉取失败 | 网络不通或 manifest 仓库被墙 | 检查网络,重试 | 配置代理或镜像源,重试west init |
west update中途报错 | 某个子仓库拉取失败 | 查看错误提示中的仓库名 | 单独进入对应仓库目录git pull后再执行west update |
| 编译时报找不到头文件 | SDK 环境变量未设置 | 运行echo $ZEPHYR_SDK_INSTALL_DIR | sourcezephyr-env.sh,重新 export 环境变量 |
| 板卡名称拼写错误 | 对目标板不熟悉 | west boards查看支持的板卡 | 从列表中找到准确的板卡名 |
| 烧录提示无法连接设备 | 板卡未进入烧录模式或驱动问题 | 检查 USB 设备是否被识别 | 按开发板手册进入 DFU/Bootloader 模式 |
| 设备树中引脚配置无效 | overlay 文件未生效 | 确认DTC_OVERLAY_FILE设置 | 在CMakeLists.txt中显式指定 overlay 文件 |
| 编译很慢 | 首次构建拉取 HAL 库并全量编译 | 观察构建日志 | 使用 ccache,sudo apt install ccache |
这里单独强调一个高频问题:在 Windows 原生环境下,west update比较容易因为路径过长或软链接问题失败。使用 WSL2 后,这一系列问题基本消失。这也是为什么前文建议直接从 WSL2 开始。
9. 最佳实践与工程建议
Zephyr 的项目实践,有一些经验值得在工作开始前就固化到流程中。
9.1 使用版本管理锁定 Zephyr 版本
Zephyr 的迭代速度很快,不同版本之间的 API 变动不小。团队项目一定要把west的 manifest 文件纳入 Git 管理,并在文档中明确声明使用的 Zephyr 版本。否则“昨天还能编译,今天突然报错”的问题会频繁出现。
9.2 项目目录与源码目录分离
不要在 Zephyr 官方源码目录里直接改代码。更规范的做法是新建自己的 application 目录,把src、prj.conf、CMakeLists.txt、boards、dts等文件组织在项目仓库中。
my_app/ ├── CMakeLists.txt ├── prj.conf ├── src/ │ └── main.c └── boards/ └── my_board.overlay这样不仅便于 Git 版本管理,也让多个产品复用同一套 Zephyr SDK 成为可能。
9.3 配置文件与环境变量脚本化
环境变量(ZEPHYR_SDK_INSTALL_DIR、ZEPHYR_BASE等)最好不要每次手动 export,而是写入~/.zephyrrc或项目入口脚本。这样换一台电脑、新同事入职时,只需要执行一条 source 命令就能完成环境初始化。
9.4 先跑官方 samples,再修改,最后造轮子
Zephyr 的官方 samples 覆盖了内核、驱动、BLE、传感器、显示等几乎全部模块。遇到新外设时,优先找对应 sample,在其基础上改动,远比从零开始研究 HAL 手册效率高。
9.5 理解安全启动和 OTA 的设计
如果你的产品需要 FOTA 升级,Zephyr 生态里默认使用 MCUboot 作为 bootloader。这意味着从产品设计初期就要考虑分区表、密钥管理、签名校验等问题。这部分内容不是简单的功能叠加,而是系统级设计,建议在项目规划阶段就纳入技术选型。
9.6 团队学习路线的建议
对于从 FreeRTOS 迁移而来的团队,不建议一上来就追求复杂的多协议栈工程。更务实的路径是:先跑通 Hello World,再用 Blinky 理解设备树,接着做 GPIO 按键中断,然后逐步引入传感器驱动、通信协议、日志系统。每一步都验证通过后,再进入整体产品集成。
10. 选型判断:你的下一个项目到底该用谁
最后回到最开始的问题:2026 年做嵌入式项目,到底选 Zephyr 还是 FreeRTOS?
如果是做一个简单的温湿度传感器节点,一颗 8 位或低端 Cortex-M0 就能完成,整机资源紧张、固件体积要求苛刻,FreeRTOS 依然合适。因为这种项目几乎不需要考虑复杂的协议栈、低功耗管理和 OTA 流程,轻量就是最大的优势。
如果产品需要长久维护、需要保持多硬件版本兼容、需要不断加入新的连接协议或云平台能力,Zephyr 是更符合“系统工程”思路的选择。它前期投入的学习成本,会换来后续开发中更少的“野生封装”和“重复造轮子”。
还有一类项目需要特别提醒:如果你正在为公司内部的多个产品线做统一软件平台,Zephyr 的价值会成倍放大。因为它统一的构建方式、设备树描述和驱动接口,让不同产品线之间复用固件工程成为可能,而不是每个产品都变成一座独立的“技术孤岛”。
Zephyr 不是“另一个 RTOS”,它代表的是嵌入式开发向系统化、工程化演进的方向。选型没有绝对的对错,只有是否匹配你的项目阶段和团队能力。希望这篇 Zephyr 特别篇,能让你在 2026 年的技术选型中多一个清晰的选择项。