
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_SENSORy CONFIG_SENSOR_LOG_LEVEL_INFy系统会自动检查这个驱动依赖哪些硬件资源、是否和当前板卡兼容、是否需要连带开启其他配置项。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 年并不是完全对立的替代关系而是两种不同项目需求下的不同答案。下面从六个维度做对比。对比维度ZephyrFreeRTOS本质定位面向物联网和连接设备的操作系统轻量级实时调度内核内核最小体积几十 KB 级可以裁剪几 KB 级极致轻量硬件抽象层Devicetree 驱动框架统一接口无标准硬件抽象驱动由厂商提供协议栈支持BLE、Wi-Fi、Thread、Zigbee、802.15.4 等原生集成需自行集成第三方协议栈构建系统CMake west支持 Kconfig 配置Makefile / CMake无统一配置体系许可证Apache 2.0MIT内核部分主要适用场景智能家居、可穿戴、工业物联网、车联网简单任务调度、资源受限 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_VARIANTzephyr注意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 的完整 IDEZephyr 自身也提供了终端 UI 方案。进入任意一个 build 目录后运行west build -t guiconfig系统会打开图形化配置界面。你也可以用west build -t menuconfigmenuconfig 是基于终端菜单方式的配置界面操作逻辑与 Linux 内核配置完全一致。对于习惯键盘操作的人这种方式的效率反而更高。在实际项目里我们更常采用的方式是直接维护prj.conf文件。下图是一个典型的 BLE 项目配置# 文件路径prj.conf CONFIG_BTy CONFIG_BT_PERIPHERALy CONFIG_BT_DEVICE_NAMEZephyr_BLE_Device CONFIG_BT_PRIVACYy CONFIG_LOGyKconfig 的价值在于它把所有功能开关收敛到可审查、可版本管理的配置文件中而不是散落在代码各处。这一点在后期的工程维护中价值极大。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 initwest update中途报错某个子仓库拉取失败查看错误提示中的仓库名单独进入对应仓库目录git pull后再执行west update编译时报找不到头文件SDK 环境变量未设置运行echo $ZEPHYR_SDK_INSTALL_DIRsourcezephyr-env.sh重新 export 环境变量板卡名称拼写错误对目标板不熟悉west boards查看支持的板卡从列表中找到准确的板卡名烧录提示无法连接设备板卡未进入烧录模式或驱动问题检查 USB 设备是否被识别按开发板手册进入 DFU/Bootloader 模式设备树中引脚配置无效overlay 文件未生效确认DTC_OVERLAY_FILE设置在CMakeLists.txt中显式指定 overlay 文件编译很慢首次构建拉取 HAL 库并全量编译观察构建日志使用 ccachesudo 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 年的技术选型中多一个清晰的选择项。