嵌入式圈子里,Zephyr 这个名字最近越来越频繁地出现在技术播客、社区帖和招聘要求里。如果你正在做物联网设备、可穿戴产品,或者需要统一软件平台的嵌入式项目,大概率已经在选型清单里看到过它。本期“涂鸦博物馆”播客把 Zephyr 作为嘉宾主题,命名里还带上了“PT.1”——这本身就说明话题量级不小:一个 RTOS 要讲清楚,一次对话根本不够。而且从搜索热度来看,“zephyr环境搭建”“workbench for zephyr kconfig”“zephyr vs freertos深度对比”都是开发者真正会去搜的关键词,说明大家已经不再停留在‘听过名字’的阶段,而是开始琢磨它到底能不能用在自家产品里。
我先把判断放在开头:Zephyr 不是一个比 FreeRTOS 更复杂的“RTOS 备选项”,而是一个自带构建系统、设备树、驱动模型和协议栈的嵌入式操作系统平台。它的学习曲线比 FreeRTOS 陡,但换来的回报是跨板卡复用、组件化配置和面向产品的软件架构能力。2026 年做嵌入式项目选型时,如果你还在用“哪个内核占用 RAM 更小”这种维度去看它,很容易错过真正重要的部分。今天这篇文章就顺着 Zephyr 最常被讨论的几条主线展开:先讲它到底是什么,再对比它和 FreeRTOS 的差异,然后从零搭建环境、跑通第一个工程,最后给出实际项目中真正用得上的配置建议和避坑清单。如果你刚接触 Zephyr,或者正准备在一个新项目里评估它,建议把这篇文章收藏起来,边看边操作。
1. Zephyr 到底是什么:先放下“RTOS 对比”的思维定式
不少开发者第一次了解 Zephyr 时,会直接用 FreeRTOS 的思维去理解它:抢占式调度、任务/消息队列/信号量、Tick 配置、堆栈大小……这些概念在 Zephyr 里确实都存在,但它远远不止这些。Zephyr 由 Linux 基金会托管,背后有 Nordic、NXP、ST、Intel 等多家芯片厂商和商业公司在持续投入。它提供的是一整套“面向产品开发”的软件平台,而不是一个“跑在 MCU 上的调度内核”。
从项目结构上就能看出区别。一个典型的 Zephyr 应用工程里有 CMakeLists.txt、prj.conf、src/main.c,看起来和很多嵌入式项目类似,但真正决定工程行为的是 Kconfig 配置和设备树(Devicetree)。Kconfig 负责“软件开关”,比如要不要启用蓝牙、要不要启用日志、任务栈大小是多少;设备树负责“硬件描述”,比如这个板子上有几个 UART、SPI 接在哪个引脚、LED 挂在哪个 GPIO。应用层代码不再直接写死寄存器地址和引脚号,而是通过编译期生成的设备树宏去访问硬件资源。
这意味着,同一个应用代码,换一块开发板后,只要设备树和 Kconfig 配置不同,构建系统就能生成对应平台的镜像。在传统 RTOS 项目里,换 MCU 往往意味着重写板级驱动、重新梳理中断映射和时钟配置;而在 Zephyr 项目里,大量的板级差异被设备树吸收掉了。这就是它被称为“平台”而不是“内核”的原因。
另一个容易让人迷惑的地方是 west。west 是 Zephyr 的多仓库管理工具,它不只是用来拉代码的,还负责整个 workspace 的版本对齐。Zephyr 将内核、hal 库、第三方模块按 manifest 文件组织成多个仓库,west init + west update 之后,整个工具链和模块版本才能保持一致。如果只 clone 一个 zephyr 仓库然后用 CMake 直接构建,大概率会在编译时出现各种模块缺失或版本不匹配的问题。
所以,Zephyr 真正要解决的是嵌入式软件的可复用性和工程化问题。它把硬件描述、软件配置、构建脚本、驱动框架、子系统协议栈都纳入了一套统一体系。学习它,不能只盯着调度器 API,而是要理解 Kconfig、设备树、west 和构建系统这几根支柱。
2. Zephyr 的核心概念:Kconfig、设备树与 west 构建体系
2.1 Kconfig:软件功能开关
Kconfig 的语法源自 Linux 内核,Zephyr 把它改造为模块化的配置系统。简单理解,它就是一组可以打开或关闭的编译期开关。比如你想让蓝牙协议栈参与编译,就在 prj.conf 里写:
CONFIG_BT=y想调整系统主线程栈大小:
CONFIG_MAIN_STACK_SIZE=2048Zephyr 各子系统提供大量 Kconfig 选项,这些选项决定“哪些代码被编译进来”。它的好处是最终镜像可以做到比较精简:用不到的模块根本不会被编进去,不会像某些 RTOS 一样把整套协议栈都驻留在内存里。
2.2 设备树:硬件描述与代码解耦
设备树最早用于嵌入式 Linux,用来描述 CPU、内存、外设、中断控制器,Zephyr 借鉴了这套描述方式。在每个 board 目录下,都有一个 .dts 文件描述这块板子上的硬件资源。比如 STM32 的某个开发板会定义:
usart1: serial@40013800 { compatible = "st,stm32-usart"; reg = <0x40013800 0x400>; interrupts = <37 0>; status = "disabled"; };应用开发时,你不需要手动去读寄存器手册来映射 UART 引脚。只要板级设备树里已经定义好 usart1 并设置了 status = "okay",应用中就可以通过设备树宏直接拿到设备描述结构体。设备树的引入,让“板级支持包”不再是散落在一堆 .h 和 .c 文件里的魔法数字,而是一份结构清晰的硬件清单。
2.3 west:多仓库版本管理
west 是 Zephyr 官方推荐的工具,作用是管理多个 git 仓库。打开 west.yml 可以看到 Zephyr 工程依赖哪些仓库、各自在哪个 revision。换一个 Zephyr 版本,或者把某个 hal 模块锁定到特定 commit,都可以通过 manifest 文件统一管理。对团队协作来说,这比每个人手动 clone 各自的分支要可靠得多。后续在环境搭建部分,我会详细演示 west 的用法。
这三者共同构成了 Zephyr 的构建哲学:代码、配置、硬件描述分离。理解这一点之后,再看任何 Zephyr demo,你就不会只盯着 C 代码本身了。
3. Zephyr vs FreeRTOS:2026 年嵌入式项目选型怎么判断
从搜索热度来看,“zephyr vs freertos”是很多人在选型阶段最关心的问题。这里先说结论:如果你的产品形态是单芯片、单功能的简单控制,FreeRTOS 的轻量和低门槛仍然有优势;如果你要做的是一个会持续迭代、可能跑 BLE/Wi-Fi、需要 OTA、需要支持多板卡的物联网产品,Zephyr 的工程化优势会逐渐显现。
下面从几个关键维度对比:
| 对比维度 | Zephyr | FreeRTOS |
|---|---|---|
| 定位 | 嵌入式操作系统平台 | 实时内核 + 生态组件 |
| 内核功能 | 多线程、信号量、消息队列、内存管理、轮询等 | 多线程、信号量、消息队列、内存管理,内核本身很精简 |
| 硬件描述 | 设备树 + 板级目录 | 通常由 MCU 厂商 SDK 提供 |
| 配置方式 | Kconfig,模块化编译 | 头文件宏 + 厂商配置工具 |
| 驱动模型 | 统一驱动框架,API 抽象完善 | 依赖厂商 SDK,风格不一 |
| 无线协议栈 | 内置 BLE、Wi-Fi、Thread、Zigbee 等子系统 | 需要额外集成 |
| 多板卡复用 | 应用层代码与板级配置分离 | 换平台时需要移植板级层 |
| 学习门槛 | 较高,需要理解 west/设备树/Kconfig | 较低,内核 API 简单直接 |
| 社区与商业支持 | Linux 基金会 + 多家芯片厂商 | Amazon 生态 + 广泛 MCU 支持 |
这个表并不是否定 FreeRTOS。相反,对于很多简单产品,FreeRTOS 仍然是性价比很高的选择。它的 API 直观,资料多,工程师招聘成本低,而且在一些老牌 MCU SDK 里深度集成。但 2026 年选型时,有一个趋势值得注意:越来越多的 MCU 厂商开始把 Zephyr 作为官方支持的一级平台,而不是第三方移植。这意味着,你可以在 Zephyr 的板级目录里直接找到大量开发板的设备树和默认配置,而不是自己从头适配。
从架构层面看,FreeRTOS 更像一个“内核库”,你把它嵌进自己的工程里,自己决定外设驱动、协议栈和构建方式怎么写;而 Zephyr 更像一套“操作系统”,它试图规定你如何构建、如何配置、如何描述硬件,然后在这套规范之上提供完整的子系统。选择 Zephyr,意味着你愿意接受它的工程框架,换取长期可维护性。
项目选型建议可以这样说:如果团队已经有成熟的厂商 SDK 开发流程,且产品短平快,FreeRTOS 完全够用;如果产品生命周期长、硬件方案可能频繁切换、需要无线协议栈和 OTA,那 Zephyr 值得提前投入评估。播客里把它作为一期完整主题来讲,也说明这个评估过程本身并不简单。
4. 环境准备:从零搭一个 Zephyr 开发环境
Zephyr 的环境搭建第一次接触时会觉得繁琐,但核心其实只有四步:安装系统依赖、创建 Python 虚拟环境、用 west 拉取源码、安装 SDK 工具链。这里以 Linux 环境为例演示,Windows 和 macOS 的步骤类似,但依赖包安装方式不同。为了不踩版本坑,建议先按照 Zephyr 官方文档确认当前版本要求,本文重点演示通用思路。
4.1 安装系统依赖
在 Ubuntu/Debian 上,需要先安装编译 Zephyr 依赖的基础工具:
sudo apt update sudo apt install 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这里几个工具的作用需要说明一下:cmake 是构建系统,ninja 是快速构建器,device-tree-compiler 用于编译设备树,python3 相关包是 Zephyr 构建脚本的运行时依赖。如果缺少这些包,后面执行 west 命令时可能出现各种报错。
4.2 创建 Python 虚拟环境并安装 west
Zephyr 的构建脚本依赖多个 Python 包,为了避免污染系统 Python,建议用虚拟环境隔离:
cd ~ python3 -m venv ~/zephyr-env source ~/zephyr-env/bin/activate pip install --upgrade pip pip install west激活虚拟环境后,先确认 west 可用:
west --version如果出现版本号,说明 west 安装成功。后面每次打开新终端时,都要记得 source ~/zephyr-env/bin/activate,或者把这一行写进 shell 配置。
4.3 获取 Zephyr 源码并初始化 workspace
先创建 workspace 目录,再用 west init 初始化:
mkdir ~/zephyr-dev cd ~/zephyr-dev west init -m https://github.com/zephyrproject-rtos/zephyr.git zephyrproject cd zephyrproject west updatewest init 会拉取 manifest 文件,west update 则按照 manifest 的锁定信息拉取所有依赖仓库,包括 Zephyr 内核、HAL、第三方模块。这一步会根据网络情况耗时几分钟,如果网络不稳定,可以设置 git 的 http 缓存或错峰重试。
4.4 安装 Zephyr SDK 与工具链
Zephyr SDK 是一套预编译好的交叉编译工具链,涵盖多个目标架构。下载方式建议访问 Zephyr SDK 的 GitHub Releases 页面,选择与当前 Zephyr 版本匹配的 SDK 包。下载后解压并运行安装脚本:
cd ~/zephyr-dev wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/vX.Y.Z/zephyr-sdk-VERSION_linux-x86_64.tar.xz tar xf zephyr-sdk-*.tar.xz cd zephyr-sdk-* ./setup.sh -t all -h安装完成后,设置两个关键环境变量:
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdkZEPHYR_TOOLCHAIN_VARIANT 表示使用 Zephyr 官方 SDK 作为交叉编译工具链,ZEPHYR_SDK_INSTALL_DIR 指向 SDK 安装目录。如果没有设置这两个变量,构建时通常会报“No toolchain found”之类的错误。
4.5 安装 Python 依赖
Zephyr 构建时还会用到一些 Python 包,需要在虚拟环境里安装:
pip install -r ~/zephyr-dev/zephyrproject/zephyr/scripts/requirements.txt到这里,环境就差不多准备好了。建议先跑一个 hello_world,确认整条链路没问题,再进行后面的开发。
5. 第一个工程:hello_world 跑通构建与运行
环境搭好之后,先用 Zephyr 自带的 hello_world 示例验证工具链。Zephyr 的 samples 目录包含大量官方示例,hello_world 是最小可运行程序。
5.1 查看示例代码
cd ~/zephyr-dev/zephyrproject ls samples/hello_world这个目录下有 src/main.c、prj.conf、CMakeLists.txt 等文件。打开 src/main.c 可以看到核心逻辑非常简单:
#include <zephyr/kernel.h> void main(void) { printk("Hello World! %s\n", CONFIG_BOARD); }printk 是 Zephyr 的串口输出函数,有点像嵌入式版的 printf。CONFIG_BOARD 是构建时由 Kconfig 生成的宏,表示当前编译的板卡名称。
5.2 构建 hello_world
选择一块开发板作为目标,先用 QEMU 模拟的 x86 板卡验证:
cd ~/zephyr-dev/zephyrproject west build -b qemu_x86 samples/hello_worldwest build 会自动创建 build 目录,生成编译配置并启动 ninja 构建。如果环境配置正确,最终会输出生成的固件路径,比如 build/zephyr/zephyr.elf。
如果想换一块真实开发板,只需要更换 -b 参数,比如:
west build -b nucleo_f103rb samples/hello_world5.3 用 QEMU 运行验证
在验证逻辑时,不一定要直接烧录真实板卡,Zephyr 对很多开发板提供了 QEMU 支持。构建完之后直接运行:
west build -t run如果你之前构建的是 qemu_x86,它会启动 QEMU 并在模拟串口上打印类似下面的内容:
*** Booting Zephyr OS build zephyr-v3.x *** Hello World! qemu_x86看到这行输出,说明 Zephyr 的编译工具链、设备树、串口驱动、链接脚本都已经正常工作了。这一步成功,后续所有开发都有了一个可依赖的基础。
6. 从 hello_world 到 blinky:设备树与 GPIO 驱动
hello_world 只证明“能编译、能运行”,但嵌入式开发更关心外设操作。下面用一个 blinky 例子讲解设备树和 GPIO API。许多初学者在这里会卡住,因为 Zephyr 里获取 GPIO 引脚的方式和传统 SDK 差别很大。
6.1 设备树在 Zephyr 里怎么工作
Zephyr 在构建时会把板级设备树文件编译成二进制的 DTB,并通过固定的头文件路径生成设备树宏。应用代码里可以用 DT_ALIAS、DT_NODELABEL 等宏直接引用设备树节点。比如常用的板载 LED 在设备树里通常有 led0 别名,那么代码里可以这样获取引脚描述:
#define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);这里 gpio_dt_spec 结构体包含了引脚所属的 GPIO 控制器和设备树里定义的引脚号,应用代码不再关心它是 PA5 还是 PB1,只需要知道“led0 这个设备跑通了”。
6.2 用 overlay 覆盖 LED 引脚
不同板卡的 LED 可能接在不同的 GPIO 上。Zephyr 支持在应用目录下放一个 overlay 文件来覆盖板级设备树,比如建立一个名为 board 的文件夹,里面放一块开发板的 overlay。下面是一个在 STM32 板卡上把 PA5 配置为 LED 的例子。假设你的工程目录叫 blinky:
// blinky/boards/nucleo_f103rb.overlay / { leds { compatible = "gpio-leds"; led0: led_0 { gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; label = "LD2"; }; }; };这里的 compatible = "gpio-leds" 是 Zephyr 定义的标准类型,gpioa 表示 GPIOA 控制器的引用,5 表示引脚号 5,GPIO_ACTIVE_HIGH 表示高电平点亮。这个 overlay 只对 nucleo_f103rb 生效,不会影响其他板卡。
6.3 编写 blinky 应用代码
在 blinky 工程目录下创建如下文件结构:
blinky/ ├── CMakeLists.txt ├── prj.conf ├── boards/ │ └── nucleo_f103rb.overlay └── src/ └── main.csrc/main.c 完整代码如下:
#include <zephyr/kernel.h> #include <zephyr/drivers/gpio.h> #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); void main(void) { if (!device_is_ready(led.port)) { printk("Error: LED device %s is not ready\n", led.port->name); return; } gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); while (1) { gpio_pin_toggle_dt(&led); k_msleep(500); } }CMakeLists.txt 内容如下:
cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(blinky) target_sources(app PRIVATE src/main.c)prj.conf 内容:
CONFIG_GPIO=y这段代码里的流程是:先检查 GPIO 控制器是否 ready,再把 LED 引脚配置为输出,然后在死循环里每 500ms 翻转一次电平。构建命令仍然用 west:
west build -b nucleo_f103rb blinky --pristine如果不想改设备树,直接用板卡自带的 led0 别名,很多开发板的设备树里已经定义好了 led0。这个工程更像一个 template,让你理解从“硬件描述”到“应用代码”的完整链路。
7. Kconfig 配置:怎么改才会生效
Zephyr 的 Kconfig 系统是很多初学者的困惑点:明明在 prj.conf 里写了 CONFIG_XXX=y,构建后却没有效果。这通常是因为配置项的生效位置不对,或者没有执行干净构建。
7.1 配置优先级
Zephyr 的最终配置由多个来源合并而成,优先级从高到低大致是:
- 应用目录下的 prj.conf
- board 目录下的 _defconfig
- SoC 目录下的 defconfig
- 架构目录下的 defconfig
- Zephyr 内核中 Kconfig 默认值
也就是说,应用级 prj.conf 的优先级最高。修改 prj.conf 后,构建系统会重新生成 .config 并检查依赖关系,但有时候旧的编译缓存会影响新配置。
7.2 修改配置后要记得 --pristine
当你新增或删除了 CONFIG_XXX,最好使用 pristine 构建:
west build --pristine -b qemu_x86 samples/hello_world--pristine 会清空旧的 build 目录并重新生成全部配置。Zephyr 构建系统在设计上比较保守,配置变更不一定会触发全量重编,这会导致“改了配置但没有效果”的错觉。规范做法是:只要动了 prj.conf,就加 --pristine。
7.3 用 menuconfig 查看配置依赖
如果不知道某个配置项叫什么名字,或者想查看默认值,可以用 Zephyr 的 menuconfig:
west build -t menuconfig这会启动一个基于终端的功能配置界面。你可以搜索 CONFIG_BT、CONFIG_LOG、CONFIG_GPIO 等选项,查看它的依赖、默认值和当前值。这个工具比直接翻 Kconfig 源码高效得多。
从工程管理角度看,Kconfig 的核心价值是“可追溯的配置”:每个配置项都有默认值、依赖关系、帮助文档。应用只需要维护自己的 prj.conf,板级差异交给 board defconfig,这就是 Zephyr 能跨板卡复用软件的逻辑基础。
8. 常见问题与排查思路
Zephyr 环境搭建和实际开发中,开发者遇到的大部分问题都集中在工具链、配置缓存、设备树引用这几个方向。下面整理一份可以直接对照排查的表格:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| west 安装后 command not found | 虚拟环境未激活 | 执行 which west 查看路径 | source 虚拟环境,确认 pip 安装成功 |
| west update 很慢或失败 | 网络不稳定,仓库较多 | 查看 git 下载地址 | 换网络或错峰重试,检查磁盘空间 |
| 构建时报 Python module 缺失 | 未安装 requirements.txt | 查看完整报错日志,确认缺哪个模块 | 进入虚拟环境执行 pip install -r requirements.txt |
| 构建报 No toolchain found | 未设置 ZEPHYR_TOOLCHAIN_VARIANT / ZEPHYR_SDK_INSTALL_DIR | echo 查看环境变量 | 正确设置两个环境变量后重新构建 |
| CMake 版本过低 | 系统自带的 CMake 太旧 | 执行 cmake --version 查看 | 升级 CMake 到 Zephyr 要求版本 |
| 修改 prj.conf 后配置不生效 | 构建缓存未刷新 | 检查 build/.config 中对应项 | 用 west build --pristine 重建 |
| 设备树引用报 node not found | alias 或节点名写错 | 检查报错宏名和设备树文件 | 修正 overlay 或改用 DT_NODELABEL |
| 编译通过但串口无输出 | 串口配置错误或调试终端没有打开 | 确认板子的默认 UART 是否设置 ok | 检查设备树或改用西桥的 debug UART |
| 烧录后程序跑飞 | 时钟或电源配置不匹配 | 查看 board 默认配置 | 先跑官方 sample 验证板子本身是否正常 |
排查 Zephyr 问题时,最佳起点是看 build 目录下的 zephyr/.config 和 CMakeCache.txt。前者能确认 Kconfig 配置是否生效,后者能定位工具链路径和编译参数。很多问题并不是代码本身有问题,而是配置状态和预期不一致。
另外提醒一下:在烧录真实板卡之前,建议先用官方的 blink_led 或 hello_world sample 验证一下 board 环境。如果官方示例都无法运行,说明问题大概率在开发板、烧录器或串口终端配置上,而不是你的应用代码问题。
9. 工程落地时的最佳实践
Zephyr 的上手门槛不只是语法,更是工程组织方式。从实际项目角度看,下面几点对团队协作和长期维护很关键。
9.1 用 west manifest 锁定版本
不要在多人协作时让每个人各自拉取 zephyr 仓库的分支,一定要通过 west.yml 锁定版本和 commit。Zephyr 迭代很快,不同版本之间的 API 会有变化。把 manifest 文件纳入 git 管理,团队所有成员始终使用同一套依赖组合。升级时也通过 manifest 的 revision 变更来统一升级,而不是在源码里打补丁。
9.2 prj.conf 与 board 配置分离
所有应用特有的配置,比如日志级别、协议栈开关、线程栈大小,放在应用目录的 prj.conf 中。不要修改 Zephyr 源码里的 board defconfig。如果某块板子有特殊需求,可以在应用目录下按板卡放不同的 overlay 和 conf 文件。这样应用逻辑与硬件差异保持在清晰边界内,后续从一块板子切到另一块板子时非常方便。
9.3 设备树优先使用 alias 和 label
在应用代码里,优先用 DT_ALIAS 引用板级设备,而不是直接使用具体的控制器标签。例如使用 DT_ALIAS(led0) 而不是 DT_NODELABEL(pa5)。这样在换板子时,只需要在 overlay 中调整引脚映射,代码不需要改动。设备树的意义就在于让硬件变更不扩散到业务代码里。
9.4 编译时用 pristine,CI 里完整跑一遍
Zephyr 最稳妥的构建方式是带上 --pristine。虽然这会让增量编译优势减弱,但能够避免配置缓存带来的隐蔽问题。在 CI 流水线中,建议至少对目标板卡跑一次 clean build,并生成编译警告日志。Zephyr 对编译告警比较敏感,很多问题能在编译阶段提前暴露。
9.5 日志与调试信息分级管理
开发阶段可以在 prj.conf 里开启较多日志:
CONFIG_LOG=y CONFIG_LOG_DEFAULT_LEVEL=4发布阶段再降低日志级别或者完全关闭,减少串口输出对实时性的影响。使用 Zephyr 的 log 模块而不是裸 printk,可以在运行时按模块查看日志,便于定位问题。
9.6 评估工具链时用官方 demo 建立基线
接手一个新板卡时,先跑一遍官方 sample 建立行为基线,比如 hello_world、samples/drivers/led_ws2812、samples/net/wifi 等。如果官方 demo 能跑通,后续应用问题才算真正属于应用层。这套方法可以减少一半以上的排查时间。
10. 后续还能深入哪些方向
“涂鸦博物馆”把这期做成 PT.1,说明 Zephyr 的学习注定不是一次性的事。环境搭建和基础工程只是入场券,真正有价值的方向在更上层:BLE 和 Wi-Fi 协议栈的应用开发、USB 设备栈、TF-M 安全启动、OTA 升级、多核异构、Zephyr 的 Devicetree 高级用法,以及基于 Zephyr 的 Product Lifecycle 管理。每一个方向都值得单独展开。
如果这篇文章能帮你把 Zephyr 环境跑通,并且建立一个“Kconfig 管软件、设备树管硬件、west 管版本”的心智模型,那 PT.1 的核心目标就达到了。接下来不妨挑一块手头的开发板,把 hello_world 换成 blinky,再试着用 overlay 换一个 LED 引脚。亲手改一次设备树,比读十篇介绍文章都有用。