2. Zephyr 基础与开发环境搭建
好,咱们正式开始动手。这一章的目标很明确——把Zephyr的开发环境跑通,然后点亮你的第一个传感器工程。我见过太多人在环境搭建这一步卡住,然后就开始怀疑人生。其实没那么玄乎,跟着我一步步来就行。
2.1 Zephyr SDK安装——别选错版本
Zephyr SDK不是随便下一个就完事的。它包含了交叉编译工具链、调试器、QEMU模拟器等等。我个人习惯用 0.16.x 系列,稳定,坑少。
SDK版本与Zephyr主分支的对应关系
| Zephyr版本 | 推荐SDK版本 | 备注 |
|---|---|---|
| 3.5 LTS | 0.16.5-1 | 长期支持,最稳 |
| 3.6 / 3.7 | 0.16.8 | 新特性多,但偶有小坑 |
| main (开发分支) | 0.16.8+ | 不建议新手用 |
下载地址去Zephyr官网找,别去第三方站点。我记得有一次项目赶工期,从某个镜像站下了个旧版SDK,结果编译出来的固件在板子上跑不起来,查了两天才发现是工具链版本不匹配。嗯,从那以后我只从官网下。
安装步骤很简单,解压到 /opt 或者 ~/zephyr-sdk 都行。然后运行安装脚本:
cd ~/zephyr-sdk-0.16.5-1
./setup.sh
脚本会自动注册工具链路径。装完之后,检查一下环境变量:
echo $ZEPHYR_SDK_INSTALL_DIR
如果输出为空,手动加一下:
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-0.16.5-1
小技巧:把上面这行加到 ~/.bashrc 或 ~/.zshrc 里,省得每次开终端都要重新export。
2.2 west工具链配置——Zephyr的“方向盘”
west 是Zephyr的元构建工具。说白了,它帮你管理多个仓库、拉代码、配置编译。没有它,你手动搞会疯掉。
安装west很简单,用pip:
pip3 install west
然后初始化工作空间。我建议单独建一个目录,比如 ~/zephyr-workspace:
mkdir ~/zephyr-workspace
cd ~/zephyr-workspace
west init
west update
west init 会拉取Zephyr主仓库的manifest文件。west update 则根据manifest把所有子模块(比如hal、drivers、tools)都下载下来。这个过程取决于你的网速,我第一次跑的时候等了快半小时。
注意:国内网络访问GitHub可能不稳定。如果 west update 卡住,可以试试配置代理,或者用Gitee的镜像仓库。我曾经在客户现场没网,只能提前把整个workspace打包带过去。
更新完以后,导出Zephyr路径:
export ZEPHYR_BASE=~/zephyr-workspace/zephyr
同样,建议写进 ~/.bashrc。
2.3 目标板选择与配置——选对板子,少走弯路
Zephyr支持几百种开发板。但咱们做传感器驱动开发,选板子有几个原则:
- I2C/SPI接口丰富——传感器大多走这两种总线
- GPIO够用——中断、片选、复位都需要
- 社区支持好——遇到问题能搜到答案
我个人推荐几块常用的:
| 开发板 | 主控 | 优势 | 适合场景 |
|---|---|---|---|
| nRF52840 DK | Nordic nRF52840 | BLE + 多传感器接口 | 无线传感器节点 |
| STM32F4 Discovery | STM32F407 | 性能强,资料多 | 复杂传感器融合 |
| ESP32-DevKitC | ESP32 | WiFi + 低成本 | 物联网网关 |
| Raspberry Pi Pico | RP2040 | 便宜,双核 | 入门学习 |
咱们课程里统一用 nRF52840 DK 做演示。为什么?因为它的传感器接口最全,而且Zephyr对Nordic的支持最成熟。我在做智能穿戴项目时就用这块板子,踩过的坑都填平了,你跟着走会顺畅很多。
配置目标板,其实就是告诉Zephyr你要编译给谁用。在项目目录下执行:
west build -b nrf52840dk_nrf52840
-b 参数指定board名称。Zephyr里每个板子都有一个唯一的标识符,比如 nrf52840dk_nrf52840。你可以在 zephyr/boards/ 目录下看到所有支持的板子。
查板子名称的小命令:
west boards | grep nrf
这样能快速过滤出Nordic相关的板子。
2.4 Hello Sensor工程——第一个能跑起来的传感器
环境搭好了,板子选好了,咱们写个最简单的传感器工程——读取板载温度传感器。nRF52840 DK上有一颗 nRF52840内部温度传感器,不需要外接硬件,最适合做Hello World。
先创建一个新工程:
mkdir hello_sensor
cd hello_sensor
工程结构很简单,只需要两个文件:
CMakeLists.txt—— 告诉Zephyr怎么编译src/main.c—— 你的代码
CMakeLists.txt:
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(hello_sensor)
target_sources(app PRIVATE src/main.c)
src/main.c:
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
void main(void)
{
const struct device *dev = DEVICE_DT_GET_ANY(nordic_nrf_temp);
if (!device_is_ready(dev)) {
printk("传感器设备未就绪\n");
return;
}
while (1) {
struct sensor_value temp;
sensor_sample_fetch(dev);
sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &temp);
// 温度值以摄氏度为单位,val1是整数部分,val2是小数部分
printk("温度: %d.%d °C\n", temp.val1, temp.val2);
k_sleep(K_MSEC(1000));
}
}
这段代码干了三件事:
- 通过设备树匹配获取温度传感器设备
- 每秒采集一次温度数据
- 打印到串口
编译:
west build -b nrf52840dk_nrf52840 -p always
-p always 表示每次都重新构建,避免缓存问题。我第一次用Zephyr时没加这个参数,改完代码发现没生效,折腾了半天才发现是缓存作祟。
烧录:
west flash
然后打开串口监视器(比如 screen 或 minicom),你应该能看到:
温度: 25.3 °C
温度: 25.4 °C
温度: 25.3 °C
恭喜! 你的第一个Zephyr传感器工程跑起来了。虽然只是读取内部温度,但整个数据采集链路——设备树匹配、驱动调用、数据读取——已经完整走通。后面所有外接传感器的开发,都是在这个框架上做加法。
2.5 本章知识体系
下面这张图帮你理清整个环境搭建和Hello Sensor工程的脉络:
关于设备树: 上面代码里的 DEVICE_DT_GET_ANY(nordic_nrf_temp) 就是通过设备树匹配传感器。设备树是Zephyr里硬件描述的核心机制,后面第5章会专门讲。你现在只需要知道,它帮你自动找到了板子上的温度传感器,不用你手动指定引脚。
常见问题:
- 编译报错“找不到Zephyr”: 检查
ZEPHYR_BASE环境变量是否设置正确。 - 烧录失败: 确认板子连接正常,驱动已安装。nRF52840 DK需要安装J-Link驱动。
- 串口无输出: 检查波特率是否设置为115200,以及串口设备名是否正确(Linux下通常是
/dev/ttyACM0)。
好了,环境搭建和第一个传感器工程就到这里。你现在已经具备了开发Zephyr传感器驱动的基础能力。后面我们会一步步深入,从简单的温度传感器到复杂的多传感器数据融合。每一步我都会把实际项目中踩过的坑、总结的经验分享给你。