2. 开发环境搭建:Zephyr SDK安装、west工具配置、创建第一个传感器工程、编译与烧录流程
好,咱们正式开始动手了。这一章我带你走一遍环境搭建的全流程。说实话,很多初学者卡就卡在这一步——不是工具装不上,就是版本对不上。我当年刚接触Zephyr时,光装环境就折腾了两天。嗯,咱们争取一小时内搞定。
2.1 Zephyr SDK安装——别选错版本
Zephyr SDK不是普通的编译器,它包含了交叉编译工具链、调试器、QEMU模拟器等一整套东西。说白了,你装好它,就能在PC上编译出给ARM、RISC-V等嵌入式平台跑的代码。
下载地址:Zephyr官方GitHub Release页面。我个人习惯用0.16.x版本,稳定,坑少。
安装步骤(Linux环境,我推荐Ubuntu 22.04):
- 下载SDK安装包:
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.5/zephyr-sdk-0.16.5_linux-x86_64.tar.xz - 解压:
tar xf zephyr-sdk-0.16.5_linux-x86_64.tar.xz - 运行安装脚本:
cd zephyr-sdk-0.16.5 && ./setup.sh - 设置udev规则(烧录调试用):
sudo cp sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d/ - 重新加载udev:
sudo udevadm control --reload
/opt/zephyr-sdk 下,然后设置环境变量 export ZEPHYR_SDK_INSTALL_DIR=/opt/zephyr-sdk。这样多个项目都能共用。
2.2 west工具配置——Zephyr的瑞士军刀
west是Zephyr的元构建工具。它管理源码、配置项目、编译烧录全包了。你想想看,没有它,你要手动管理几十个Git仓库——那画面太美我不敢看。
安装west:
pip3 install west
装完后验证一下:west --version。如果报错,八成是pip路径没加到PATH里。我遇到过这问题,加个 export PATH=$HOME/.local/bin:$PATH 到 .bashrc 就行。
初始化Zephyr工作区:
mkdir zephyr_project
cd zephyr_project
west init
west update
west init 会拉取Zephyr主仓库,west update 会同步所有模块。这个过程取决于网速,我建议用代理或者换国内镜像源。
🔧 换国内镜像(以清华源为例):
west init -m https://mirrors.tuna.tsinghua.edu.cn/git/zephyr/main.git
west update
导出Zephyr环境变量:
cd zephyr
pip3 install -r scripts/requirements.txt
source zephyr-env.sh
每次打开新终端都要source一次?我建议你把它加到 .bashrc 里:
echo "source ~/zephyr_project/zephyr/zephyr-env.sh" >> ~/.bashrc
2.3 创建第一个传感器工程——从模板开始
好,环境搭好了,咱们来建个工程。我选BME280温湿度传感器作为例子,因为它是I2C接口,很典型。
创建工程:
west create -b nucleo_f411re bme280_demo
cd bme280_demo
-b 指定开发板,这里用STM32 Nucleo-F411RE。你手头有其他板子?换成对应的board name就行。
工程结构长这样:
bme280_demo/
├── CMakeLists.txt
├── prj.conf
├── src/
│ └── main.c
└── boards/
└── nucleo_f411re.overlay
咱们重点看 prj.conf 和 main.c。
配置prj.conf:
# 启用I2C
CONFIG_I2C=y
# 启用传感器子系统
CONFIG_SENSOR=y
# 启用BME280驱动
CONFIG_BME280=y
# 启用日志
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3
为什么这么配?我解释一下:BME280驱动依赖I2C和传感器子系统,所以这三行缺一不可。日志嘛,调试时很有用,我习惯默认开着。
编写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(bosch_bme280);
if (!device_is_ready(dev)) {
printk("BME280 not found!\n");
return;
}
printk("BME280 found, starting sampling...\n");
while (1) {
struct sensor_value temp, humidity, pressure;
sensor_sample_fetch(dev);
sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);
sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity);
sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);
printk("Temp: %d.%d C, Humidity: %d.%d%%, Pressure: %d.%d kPa\n",
temp.val1, temp.val2,
humidity.val1, humidity.val2,
pressure.val1, pressure.val2);
k_sleep(K_SECONDS(2));
}
}
这段代码的逻辑很直白:找设备、检查就绪、循环采样。注意 DEVICE_DT_GET_ANY 这个宏——它会自动从设备树里匹配BME280。你不需要手动指定I2C地址,Zephyr帮你干了。
device_is_ready 检查,结果在某个板子上程序直接跑飞。后来养成习惯——任何外设驱动,必须先检查就绪状态。
2.4 编译与烧录——见证奇迹的时刻
代码写好了,咱们编译一下。
编译命令:
west build -b nucleo_f411re .
第一次编译会下载工具链和依赖,稍等几分钟。如果一切顺利,你会看到:
-- Build files have been written to: /home/user/bme280_demo/build
[100%] Built target zephyr_final
常见编译错误及解决:
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
CMake Error: Zephyr not found |
环境变量未设置 | 执行 source zephyr-env.sh |
undefined reference to `sensor_channel_get' |
prj.conf未启用SENSOR | 添加 CONFIG_SENSOR=y |
No board named 'nucleo_f411re' |
board name拼写错误 | 用 west boards | grep nucleo 查正确名称 |
烧录到开发板:
west flash
Nucleo板自带ST-Link,插上USB就能识别。烧录成功后,按复位键,串口会输出:
BME280 found, starting sampling...
Temp: 25.3 C, Humidity: 48.2%, Pressure: 101.3 kPa
Temp: 25.3 C, Humidity: 48.1%, Pressure: 101.3 kPa
看到数据了吗?嗯,这就是你的第一个Zephyr传感器工程。
2.5 本章小结
咱们这一章干了三件事:装SDK、配west、建工程。你可能会觉得步骤有点多,但相信我——这套流程走一遍,后面所有传感器工程都是复制粘贴的节奏。
下一章,咱们深入传感器驱动框架,看看Zephyr是怎么把不同厂家的传感器统一成一套API的。到时候你会发现,换一个传感器,代码改动量不超过10行。
好,先到这。有问题随时翻翻Zephyr官方文档,或者直接看 zephyr/drivers/sensor/bme280/ 下的源码——那才是最权威的教材。