第二章:Zephyr开发环境搭建
说实话,搭建开发环境这件事,看着简单,但坑不少。我见过太多初学者卡在这一步,折腾一整天连个Hello World都跑不起来。今天我就带你一步步搞定它。
2.1 安装west工具
west是Zephyr的官方构建工具,说白了就是个Python包。安装它之前,你得先确保Python 3.8以上版本已经装好了。
核心命令:
pip3 install west
我个人习惯用pip3而不是pip,避免跟Python 2搞混。装完之后验证一下:
west --version
如果看到版本号,恭喜你,第一步完成了。我记得有一次在Ubuntu 20.04上装,死活报权限错误。后来发现是pip的源有问题,换成清华源就好了。
小技巧:建议用虚拟环境装west,避免污染系统Python。命令是:
python3 -m venv zephyr-venv
source zephyr-venv/bin/activate
pip3 install west
2.2 配置toolchain
toolchain就是编译器。Zephyr支持两种方式:ARM GCC和Zephyr SDK。我推荐新手直接用Zephyr SDK,省心。
方式一:Zephyr SDK(推荐)
下载SDK包,然后解压到某个目录。比如我习惯放~/zephyr-sdk-0.16.1:
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz
tar xf zephyr-sdk-0.16.1_linux-x86_64.tar.xz -C ~/
cd ~/zephyr-sdk-0.16.1
./setup.sh
setup.sh脚本会自动安装所有工具链。嗯,这里要注意:如果你的系统是ARM架构的,得下载对应的arm64版本。
方式二:ARM GCC
如果你不想装SDK,也可以用ARM GCC。但说实话,我建议别折腾。曾经有个项目,我用ARM GCC编译出来的固件,烧到nRF52840上跑起来就死机。查了两天,发现是GCC版本不对。换成Zephyr SDK后,问题秒解。
避坑指南:我曾经因为环境变量没配好,折腾了一下午。记得把SDK路径加到~/.zephyrrc文件里:
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-0.16.1
2.3 创建并编译第一个Hello World工程
环境配好了,咱们来跑个Hello World。先初始化一个工作区:
west init ~/zephyr-project
cd ~/zephyr-project
west update
west update会下载所有Zephyr源码和模块。这个过程有点慢,你可以去泡杯咖啡。下载完后,进入示例目录:
cd ~/zephyr-project/zephyr/samples/hello_world
然后编译。以nRF52840 DK为例:
west build -b nrf52840dk_nrf52840 .
你想想看,这条命令背后发生了什么?west会调用CMake生成构建文件,然后调用make或ninja编译。如果一切顺利,你会看到:
Memory region Used Size Region Size %age Used
FLASH: 16384 B 1 MB 1.6%
RAM: 4096 B 256 KB 1.6%
IDT_LIST: 0 B 2 KB 0.0%
看到这个输出,说明编译成功了。我第一次看到这个时,心里还挺激动的——一个嵌入式系统就这么跑起来了。
关键点:west build -b 后面跟的是板子名称。nRF52840 DK的板子名是nrf52840dk_nrf52840。其他板子可以用west boards命令查看。
2.4 理解Zephyr构建系统
Zephyr的构建系统基于CMake和Kconfig。说白了,CMake管文件怎么编译,Kconfig管功能怎么配置。
CMake部分
每个Zephyr工程都有一个CMakeLists.txt。比如Hello World的:
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(hello_world)
target_sources(app PRIVATE src/main.c)
你看,就几行。find_package(Zephyr)会引入Zephyr的构建规则。然后你把源文件加进去就行。
Kconfig部分
Kconfig是Zephyr的配置系统。你可以通过menuconfig来配置:
west build -t menuconfig
这会打开一个图形界面,你可以勾选或取消各种功能。比如你想用BLE,就找到Bluetooth选项勾上。我刚开始用的时候,总觉得这玩意儿麻烦。后来发现,它其实是个好东西——能让你精确控制固件大小。
个人经验:在项目中,我经常用prj.conf文件来配置。比如:
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="MyDevice"
这样比每次跑menuconfig快多了。
2.5 烧录与调试基础
编译完了,怎么烧到板子上?以nRF52840 DK为例,它自带J-Link调试器,插上USB就能用。
烧录
用west flash命令:
west flash
就这么简单。west会自动识别J-Link,把固件烧进去。烧完后,板子会自动复位运行。你会看到串口输出:
*** Booting Zephyr OS build v3.5.0 ***
Hello World! nrf52840dk_nrf52840
看到这行字,说明你的第一个Zephyr程序跑起来了。
调试
调试的话,我习惯用west debug。它会启动GDB,连接到J-Link:
west debug
然后你就可以设断点、单步执行了。比如:
(gdb) break main
(gdb) continue
(gdb) next
为什么会这样?因为west debug背后调用了J-Link GDB Server和arm-none-eabi-gdb。你想想看,这比用printf调试强多了。
避坑指南:我曾经在调试时,发现断点设了但不停。后来发现是优化等级太高了。记得在prj.conf里加一行:
CONFIG_DEBUG=y
这样编译器就不会优化掉你的变量和函数了。
小结
这一章我们走完了从零到Hello World的全过程。你学会了装west、配toolchain、编译、烧录和调试。说实话,这些基础操作看着简单,但它们是后续所有开发的地基。下一章,我们会深入BLE协议栈,开始真正的蓝牙开发。
嗯,如果你在搭建过程中遇到问题,别慌。多半是环境变量没配好,或者版本不对。检查一下ZEPHYR_BASE和ZEPHYR_SDK_INSTALL_DIR这两个变量,八成能解决。