2. Zephyr 基础与开发环境搭建

好,咱们正式开始动手。这一章的目标很明确——把Zephyr的开发环境跑通,然后点亮你的第一个传感器工程。我见过太多人在环境搭建这一步卡住,然后就开始怀疑人生。其实没那么玄乎,跟着我一步步来就行。

2.1 Zephyr SDK安装——别选错版本

Zephyr SDK不是随便下一个就完事的。它包含了交叉编译工具链、调试器、QEMU模拟器等等。我个人习惯用 0.16.x 系列,稳定,坑少。

SDK版本与Zephyr主分支的对应关系

Zephyr版本推荐SDK版本备注
3.5 LTS0.16.5-1长期支持,最稳
3.6 / 3.70.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 DKNordic nRF52840BLE + 多传感器接口无线传感器节点
STM32F4 DiscoverySTM32F407性能强,资料多复杂传感器融合
ESP32-DevKitCESP32WiFi + 低成本物联网网关
Raspberry Pi PicoRP2040便宜,双核入门学习

咱们课程里统一用 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));
    }
}

这段代码干了三件事:

  1. 通过设备树匹配获取温度传感器设备
  2. 每秒采集一次温度数据
  3. 打印到串口

编译:

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工程的脉络:

Zephyr开发环境搭建与Hello Sensor工程知识体系 Zephyr开发环境搭建与Hello Sensor工程知识体系 SDK安装 west工具链配置 目标板选择 创建Hello Sensor工程 CMakeLists.txt src/main.c west build → west flash → 串口输出 ✅ 温度数据打印成功

关于设备树: 上面代码里的 DEVICE_DT_GET_ANY(nordic_nrf_temp) 就是通过设备树匹配传感器。设备树是Zephyr里硬件描述的核心机制,后面第5章会专门讲。你现在只需要知道,它帮你自动找到了板子上的温度传感器,不用你手动指定引脚。

常见问题:

  • 编译报错“找不到Zephyr”: 检查 ZEPHYR_BASE 环境变量是否设置正确。
  • 烧录失败: 确认板子连接正常,驱动已安装。nRF52840 DK需要安装J-Link驱动。
  • 串口无输出: 检查波特率是否设置为115200,以及串口设备名是否正确(Linux下通常是 /dev/ttyACM0)。

好了,环境搭建和第一个传感器工程就到这里。你现在已经具备了开发Zephyr传感器驱动的基础能力。后面我们会一步步深入,从简单的温度传感器到复杂的多传感器数据融合。每一步我都会把实际项目中踩过的坑、总结的经验分享给你。