实战记录:用Zephyr和nRF52840 DK开发板点亮第一个LED(完整环境配置到烧录)
实战记录用Zephyr和nRF52840 DK开发板点亮第一个LED完整环境配置到烧录看着眼前nRF52840 DK开发板上那颗蓝色LED开始规律闪烁我长舒一口气——这意味着从零开始的Zephyr开发环境搭建终于成功了。作为嵌入式开发的新手第一次接触Zephyr这个轻量级实时操作系统时面对复杂的工具链和依赖关系确实有些手足无措。本文将完整记录如何在Ubuntu系统上从基础环境配置到最终程序烧录的全过程帮助同样想尝试Zephyr开发的伙伴避开那些我踩过的坑。1. 环境准备Ubuntu系统与基础工具1.1 选择合适的Ubuntu版本Zephyr对宿主机的操作系统版本有明确要求。经过多次测试验证Ubuntu 18.04 LTS及以上版本是最稳定的选择。低版本如16.04会遇到各种工具版本不兼容的问题West工具16.04默认仓库中的版本过旧0.6.2无法支持Zephyr 2.2.99Python依赖部分包需要Python 3.6特性而16.04默认Python 3.5CMake版本构建系统需要CMake 3.13.1低版本需手动升级提示虽然文档提到支持18.04但实测20.04和22.04同样适用且自带工具版本更高1.2 系统基础配置更新系统并安装必要工具包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-pip \ python3-setuptools python3-tk python3-wheel \ xz-utils file make gcc gcc-multilib g-multilib \ libsdl2-dev验证CMake版本需≥3.13.1cmake --version # 若版本过低使用Kitware官方源安装新版 wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc | sudo apt-key add - sudo apt-add-repository deb https://apt.kitware.com/ubuntu/ bionic main sudo apt update sudo apt install cmake2. Zephyr开发环境搭建2.1 West工具安装与配置West是Zephyr的元工具负责项目管理pip3 install --user -U west echo export PATH~/.local/bin:$PATH ~/.bashrc source ~/.bashrc验证安装west --version # 应显示0.11.0以上版本2.2 获取Zephyr源码初始化工作区并获取代码west init zephyrproject cd zephyrproject west update这个过程可能较慢因为要从GitHub克隆多个仓库。完成后导出CMake包west zephyr-export安装Python依赖pip3 install --user -r ~/zephyrproject/zephyr/scripts/requirements.txt2.3 安装Zephyr SDK下载并安装工具链wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.2/zephyr-sdk-0.11.2-setup.run chmod x zephyr-sdk-0.11.2-setup.run ./zephyr-sdk-0.11.2-setup.run -- -d ~/zephyr-sdk-0.11.2配置环境变量echo export ZEPHYR_TOOLCHAIN_VARIANTzephyr ~/.bashrc echo export ZEPHYR_SDK_INSTALL_DIR~/zephyr-sdk-0.11.2 ~/.bashrc source ~/.bashrc设置udev规则以访问调试器sudo cp ${ZEPHYR_SDK_INSTALL_DIR}/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d sudo udevadm control --reload3. 硬件连接与驱动配置3.1 安装nRF命令行工具从Nordic官网下载并安装wget https://www.nordicsemi.com/-/media/Software-and-other-downloads/Desktop-software/nRF-command-line-tools/sw/Versions-10-x-x/10-7-0/nRFCommandLineTools1070Linuxamd64.tar.gz tar -xvf nRFCommandLineTools1070Linuxamd64.tar.gz sudo dpkg -i nRF-Command-Line-Tools_10_7_0_Linux-amd64.deb sudo dpkg -i JLink_Linux_V662b_x86_64.deb验证安装nrfjprog --version # 应显示10.7.0版本3.2 开发板连接配置对于虚拟机用户需要确保USB设备正确传递连接开发板到主机在虚拟机设置中将SEGGER J-Link设备连接到虚拟机验证连接lsusb | grep SEGGER # 应显示类似SEGGER J-Link的设备4. 编译与烧录Blinky示例4.1 编译工程进入Zephyr目录编译blinky示例cd ~/zephyrproject/zephyr west build -p auto -b nrf52840dk_nrf52840 samples/basic/blinky成功编译后输出类似[125/125] Linking C executable zephyr/zephyr.elf Memory region Used Size Region Size %age Used FLASH: 13120 B 1 MB 1.25% SRAM: 5224 B 256 KB 1.99% IDT_LIST: 56 B 2 KB 2.73%4.2 烧录程序使用west flash直接烧录west flash成功烧录后开发板上的LED1P0.13会开始以1Hz频率闪烁。如果遇到权限问题可尝试sudo chmod arw /dev/ttyACM0 # 根据实际设备号调整4.3 替代烧录方法如果west flash不可用可以手动烧录生成的hex文件nrfjprog --program build/zephyr/zephyr.hex --sectorerase nrfjprog --reset5. 常见问题排查5.1 West update失败症状west update卡住或报网络错误 解决方案设置Git代理如有分步克隆大仓库cd zephyrproject git clone https://github.com/zephyrproject-rtos/zephyr west update5.2 烧录时报J-Link错误症状west flash报J-Link not found 检查步骤确认开发板已连接且电源正常验证udev规则是否生效ls -l /dev/ttyACM* # 应显示crw-rw-rw-权限重启udev服务sudo service udev restart5.3 编译时CMake错误症状CMake配置阶段失败 可能原因环境变量未正确设置SDK路径错误验证步骤echo $ZEPHYR_TOOLCHAIN_VARIANT # 应显示zephyr echo $ZEPHYR_SDK_INSTALL_DIR # 应显示SDK路径6. 进阶调试技巧6.1 串口输出查看nRF52840 DK板载USB转串口可查看调试输出sudo apt install screen screen /dev/ttyACM0 115200 # 按CtrlA, 然后K退出6.2 修改闪烁频率编辑blinky示例代码// zephyrproject/zephyr/samples/basic/blinky/src/main.c #define SLEEP_TIME_MS 1000 // 修改此值调整频率重新编译烧录即可生效。6.3 多LED控制nRF52840 DK有4个用户LED对应引脚LEDGPIO引脚LED1P0.13LED2P0.14LED3P0.15LED4P0.16修改代码实现复杂闪烁模式const struct device *led_devs[] { DEVICE_DT_GET(DT_ALIAS(led0)), DEVICE_DT_GET(DT_ALIAS(led1)), DEVICE_DT_GET(DT_ALIAS(led2)), DEVICE_DT_GET(DT_ALIAS(led3)) }; void main(void) { for (int i 0; i 4; i) { gpio_pin_configure(led_devs[i], PIN, GPIO_OUTPUT_ACTIVE | FLAGS); } while (1) { for (int i 0; i 4; i) { gpio_pin_toggle(led_devs[i], PIN); k_msleep(200); } } }