嵌入式开发 Zephyr RTOS 入门:现代嵌入式操作系统实战指南
Zephyr RTOS 入门:现代嵌入式操作系统实战指南
用了好几年 FreeRTOS,你有没有遇到过这些问题:驱动全靠手写、换个芯片就得重写一大坨代码、社区维护的驱动质量参差不齐?
如果你正在寻找一个更现代化的嵌入式操作系统,Zephyr RTOS 绝对值得一试。它是 Linux 基金会旗下的开源实时操作系统,拥有统一的设备树描述、丰富的驱动框架、完善的构建系统,而且社区活跃度非常高——截至 2026 年已经有超过 700 家企业贡献代码。
今天这篇文章,我带你从零搭建 Zephyr 开发环境,在 nRF52840 上跑通第一个项目,顺便聊聊它和 FreeRTOS 到底该怎么选。
为什么选 Zephyr?先跟 FreeRTOS 比一比
| 特性 | Zephyr RTOS | FreeRTOS |
|---|---|---|
| 许可证 | Apache 2.0 | MIT |
| 设备树支持 | ✅ 原生支持 | ❌ 无 |
| 驱动框架 | 统一 API,按子系统分类 | 各厂商自行实现 |
| 构建系统 | CMake + west(类 Linux Kconfig) | 各 IDE 自行集成 |
| 网络协议栈 | 内置 TCP/IP、BLE、Thread、LoRa | 需第三方(如 FreeRTOS+TCP) |
| 支持芯片数 | 800+ 款 | 依赖厂商 BSP |
| 安全认证 | IEC 61508 / IEC 62304 认证版本 | 无官方安全认证 |
| 社区活跃度 | Linux 基金会管理,企业级维护 | AWS 维护,社区驱动 |
简单说:FreeRTOS 轻量、上手快,适合简单项目;Zephyr 功能全面、架构现代,适合需要丰富外设支持和长期维护的产品级项目。
硬件清单
| 物料 | 型号 | 参考价格 |
|---|---|---|
| 开发板 | nRF52840-DK(或兼容板) | ¥200-350 |
| USB 线 | Micro-USB / Type-C(看开发板) | ¥10 |
| 杜邦线 | 公对母若干 | ¥5 |
| LED | 普通 5mm 红色 | ¥0.5 |
| 电阻 | 220Ω | ¥0.1 |
💡 没有 nRF52840-DK 也没关系,ESP32、STM32、RP2040 等主流开发板 Zephyr 都支持,后面会讲怎么换板子。
第一步:搭建开发环境
Zephyr 的开发环境比 FreeRTOS 稍微复杂一点,但跟着步骤走,20 分钟搞定。
1.1 安装系统依赖(Ubuntu 24.04)
sudo apt update && sudo apt upgrade -y
sudo apt install --no-install-recommends \
git cmake ninja-build gperf ccache dfu-util \
device-tree-compiler wget python3-dev python3-venv \
python3-tk xz-utils file make gcc gcc-multilib \
g++-multilib libsdl2-dev libmagic1
验证版本:
cmake --version # 需要 >= 3.20.5
python3 --version # 需要 >= 3.12
dtc --version # 需要 >= 1.4.6
1.2 创建虚拟环境并安装 west
# 创建工作目录
mkdir -p ~/zephyrproject
cd ~/zephyrproject
# 创建 Python 虚拟环境
python3 -m venv .venv
source .venv/bin/activate
# 安装 west(Zephyr 的工作区管理器)
pip install west
⚠️ 每次打开新终端都要先
source .venv/bin/activate,否则 west 命令找不到。
1.3 拉取 Zephyr 源码
# 初始化工作区(只克隆 manifest 仓库)
west init -m https://github.com/zephyrproject-rtos/zephyr .
# 拉取所有模块(HAL、库等,大约 3-5 GB)
west update
# 导出 CMake 包
west zephyr-export
# 安装 Zephyr Python 依赖
west packages pip --install
west update 这一步比较慢,取决于网络。如果在国内,建议挂代理或者配置镜像。
1.4 安装 Zephyr SDK
# 安装所有架构的工具链(约 2 GB)
west sdk install
如果你只想装 ARM 工具链(省空间),可以:
west sdk install --install-dir ~/zephyr-sdk -t arm-zephyr-eabi
第二步:编译第一个示例——Blink
Zephyr 自带了一大堆示例代码,我们先跑最经典的 blinky。
cd ~/zephyrproject/zephyr
# 编译 blinky 示例,目标板 nRF52840-DK
west build -b nrf52840dk/nrf52840 samples/basic/blinky
# 烧录到开发板
west flash
就这两条命令。没有复杂的 IDE 配置,没有 Makefile 魔改。
编译完成后,板子上的 LED 应该开始以 1 秒间隔闪烁。
换其他开发板?
# ESP32-DevKitC
west build -b esp32_devkitc_wroom/esp32/procpu samples/basic/blinky
# STM32 Nucleo-F401RE
west build -b nucleo_f401re samples/basic/blinky
# Raspberry Pi Pico
west build -b rpi_pico/rp2040 samples/basic/blinky
# 查看所有支持的板子
west boards | grep -i "你的芯片型号"
第三步:理解 Zephyr 的核心概念
跑通 Blink 只是开始。要真正用 Zephyr 做项目,你得理解下面这几个核心概念。
3.1 设备树(Device Tree)
这是 Zephyr 最核心的设计理念之一。硬件描述和代码逻辑完全分离——你在 .dts 文件里描述硬件连接,在 C 代码里调用统一 API。
举个例子,要让一个 GPIO 控制 LED:
/* 在板级 .dts 文件中 */
/ {
leds {
compatible = "gpio-leds";
led0: led_0 {
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
label = "User LED";
};
};
};
C 代码里这样调用:
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#define LED0_NODE DT_NODELABEL(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
int main(void)
{
gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
while (1) {
gpio_pin_toggle_dt(&led);
k_msleep(1000);
}
return 0;
}
好处:换开发板只需要改设备树文件,C 代码完全不用动。这就是 Zephyr 能支持 800+ 款芯片的秘密。
3.2 Kconfig 配置系统
类似 Linux 内核的 make menuconfig,Zephyr 用 Kconfig 管理编译选项。
# 打开 menuconfig 界面
west build -b nrf52840dk/nrf52840 samples/basic/blinky -t menuconfig
或者在项目的 prj.conf 里直接写:
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3
3.3 线程与调度
Zephyr 的线程模型和 FreeRTOS 类似,但 API 风格更统一:
#include <zephyr/kernel.h>
/* 定义线程栈 */
#define STACK_SIZE 1024
#define PRIORITY 5
K_THREAD_STACK_DEFINE(sensor_stack, STACK_SIZE);
struct k_thread sensor_thread;
void sensor_task(void *p1, void *p2, void *p3)
{
while (1) {
// 读取传感器数据
printk("Sensor reading...\n");
k_msleep(2000);
}
}
int main(void)
{
/* 创建线程 */
k_thread_create(&sensor_thread, sensor_stack, STACK_SIZE,
sensor_task, NULL, NULL, NULL,
PRIORITY, 0, K_NO_WAIT);
k_thread_name_set(&sensor_thread, "sensor");
return 0;
}
Zephyr 还支持信号量、互斥锁、消息队列、事件等完整的同步机制,API 命名都是 k_xxx 风格,比 FreeRTOS 的 xSemaphoreCreateMutex 好记多了。
第四步:创建一个完整项目
实际项目不会直接用 samples 目录。正确的项目结构是这样的:
my-zephyr-app/
├── src/
│ └── main.c
├── CMakeLists.txt
├── prj.conf
├── boards/
│ └── nrf52840dk_nrf52840.conf # 板级配置覆盖
└── west.yml # 可选:自定义 west manifest
CMakeLists.txt
cmake_minimum_required(VERSION 3.20.5)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(my_zephyr_app)
target_sources(app PRIVATE src/main.c)
prj.conf
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_LOG=y
CONFIG_HEAP_MEM_POOL_SIZE=1024
编译和烧录
cd ~/my-zephyr-app
source ~/zephyrproject/.venv/bin/activate
west build -b nrf52840dk/nrf52840
west flash
常见问题排查
问题 1:west build 报 “command not found”
虚拟环境没激活。执行:
source ~/zephyrproject/.venv/bin/activate
问题 2:west flash 找不到 J-Link
nRF52840-DK 自带 J-Link 调试器,但需要 udev 规则:
# 下载 Segger udev 规则
wget https://www.segger.com/downloads/jlink/99-jlink.rules
sudo cp 99-jlink.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
问题 3:编译报 “no such file or directory” 指向某个 HAL
west update 没拉全。重新执行:
cd ~/zephyrproject
west update
如果某个模块一直拉不下来,可以单独更新:
west update hal_nordic
问题 4:设备树报错 “node has a reg or ranges property, but no unit name”
设备树语法错误。检查节点名是否包含地址,比如 gpio@50000000 而不是 gpio。
问题 5:国内 west update 太慢
配置代理:
export https_proxy=http://127.0.0.1:7890
export http_proxy=http://127.0.0.1:7890
或者用 shallow clone 减少下载量:
west init --mr v4.0.0 -m https://github.com/zephyrproject-rtos/zephyr .
Zephyr 适合什么场景?
| 场景 | 推荐度 | 说明 |
|---|---|---|
| 简单 LED 控制 | ⭐⭐ | 杀鸡用牛刀,Arduino 就够了 |
| BLE 产品级开发 | ⭐⭐⭐⭐⭐ | Zephyr 的 BLE 协议栈非常成熟 |
| 多协议物联网网关 | ⭐⭐⭐⭐⭐ | Thread + BLE + WiFi 一站式 |
| 工业安全认证产品 | ⭐⭐⭐⭐⭐ | 有 IEC 61508 认证版本 |
| 快速原型验证 | ⭐⭐⭐ | 环境搭建比 Arduino/ESP-IDF 慢 |
| 学习嵌入式 OS | ⭐⭐⭐⭐ | 架构优秀,值得学习 |
总结
Zephyr RTOS 的学习曲线比 FreeRTOS 陡一些,但回报也更大:
- 设备树 让硬件和软件彻底解耦,换芯片不用重写驱动
- 统一的 API 框架 让代码在不同平台间高度可移植
- 丰富的子系统 网络、BLE、文件系统、USB 开箱即用
- Linux 基金会背书 企业级维护,不用担心项目烂尾
如果你正在做一个需要长期维护的嵌入式产品,或者需要同时支持多种无线协议,Zephyr 是目前最好的开源选择之一。
下一篇我们聊聊 Zephyr 的设备树高级用法——自定义板级支持和 overlay 配置,敬请期待。
有问题欢迎在评论区讨论,也关注我们的 MakerOnsite 公众号获取更多嵌入式实战教程。