多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Ubuntu下Zephyr RTOS开发环境搭建与实操指南

Ubuntu下Zephyr RTOS开发环境搭建与实操指南 前阵子客户丢给我一块开发板让帮忙评估一下Zephyr RTOS的落地情况。Zephyr这个实时操作系统在物联网圈子里已经不算小众Ubuntu作为嵌入式开发宿主系统也是最常见的组合之一但真正动手从零搭一套可编译、可烧录的完整环境时才发现踩坑点比想象中多得多。这篇文章就是我在Ubuntu下安装Zephyr并完成基础测试的完整记录包括依赖安装、west工具链、SDK配置、hello_world编译运行和常见问题排查给正准备入坑Zephyr的嵌入式开发放一个可以直接照抄的实操参考。1. 安装前的整体思路先搞清楚Zephyr到底需要什么1.1 Zephyr开发环境到底由什么组成Zephyr不是一个简单的文件夹它是一整套相互关联的工具链和源码仓库。核心部分有五个Zephyr源码树本身kernel、drivers、samples、modules这些、west工具、CMake和Ninja构建系统、Zephyr SDK交叉工具链再加上Python环境及若干pip依赖。很多人一上来就git clone官方仓库以为把代码拉下来就能编译实际上Zephyr采用多仓库管理模式内核和各个SoC厂商的HAL、驱动模块都是独立仓库存放的。west工具就是专门干这个的它会根据west.yml这个清单一次把需要的外部模块全部对齐。编译的时候west build会调用CMake生成构建配置再用Ninja去做增量编译而编译器、链接器、QEMU模拟器这些则来自Zephyr SDK。打个不严谨的比方Zephyr代码相当于毛坯房SDK是瓷砖水泥west是施工监理CMake就是施工图纸少了哪一环都盖不起来。我第一次在Ubuntu上装Zephyr时照着官方文档一步步来结果在SDK环境变量上卡了一整天。后来把整个工具链的工作原理过了一遍再遇到报错就从容多了先想清楚是哪个环节出的问题而不是盲目百度报错信息。1.2 为什么选择Ubuntu作为宿主系统现在嵌入式开发的主流宿主系统基本就是Linux而Ubuntu又是其中社区支持最好的发行版。Zephyr官方文档的快速上手章节默认就是Ubuntu LTS环境的命令这意味着网上大多数教程、issue回复、社区方案都基于这套环境遇到问题更容易搜到答案。在Windows上用WSL也可以跑Zephyr但USB设备透传给开发板这个环节会额外增加不少麻烦尤其是CMSIS-DAP、ST-Link这类调试器WSL的usbip配置对新手不太友好。macOS整体可以只是某些驱动和下载工具的支持会滞后。我自己长期用Ubuntu 22.04.5 LTS做主力开发机除了Zephyr其他嵌入式工具链如OpenOCD、pyOCD、JLink也都跑得很稳一份环境通吃所有项目。1.3 版本选择和系统准备Ubuntu 22.04和24.04都可以我建议直接用LTS版本别在非LTS上跟自己较劲。开始之前先确认两件事系统架构和磁盘剩余空间。终端执行uname -a看到x86_64就是标准64位平台绝大多数情况下都不会有问题。磁盘剩余空间至少要有20GB的余量因为west update会把Zephyr主仓库、hal、bootloader、工具模块全部拉下来整体占用经常超过1GB再加上SDK解压和构建中间文件空间不够会非常被动。虚拟机用户记得给Ubuntu分配不低于4GB内存编译器跑满时内存太小会出现莫名其妙的OOM问题。另外安装过程会大量调用apt和pip务必保证网络状态良好软件源可用。如果用的是虚拟机建议拍摄一个初始快照装坏了好随时回滚这个习惯帮我省了很多重装系统的功夫。2. 系统依赖安装与环境准备先把地基打牢2.1 Ubuntu下需要预装的软件包清单Zephyr官方文档列出了完整的依赖清单我合并成一条apt命令sudo apt update sudo apt install --yes \ cmake \ ninja-build \ gperf \ ccache \ dfu-util \ device-tree-compiler \ python3-dev \ python3-pip \ python3-setuptools \ python3-tk \ python3-wheel \ xz-utils \ file \ make \ gcc \ gcc-multilib \ libsdl2-dev这条命令里的软件包各有各的用途挑几个容易忽略的说。cmake是构建系统生成器Ninja是快速的构建工具这俩是编译Zephyr的核心gperf用于生成哈希表在设备树处理时会用到dfu-util是做DFU升级固件的工具烧录时要靠它libsdl2-dev作用在QEMU图形模拟输出上少了它跑图形化的sample可能报SDL相关错误gcc-multilib则是为了让编译链能够生成32位目标代码很多Zephyr平台需要这个功能。如果个别包安装失败不要慌最常见的原因是软件源没有刷新或者源列表有问题先重新执行sudo apt update再单独装一下报错的包试试。2.2 Python虚拟环境的创建与west的安装我强烈建议在安装west之前先创建一个Python虚拟环境。不要图省事直接在系统Python里装west否则后期不同项目对west版本要求不一致时包冲突会让你怀疑人生。创建虚拟环境的步骤很简单mkdir -p ~/zephyrproject cd ~/zephyrproject python3 -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install west激活虚拟环境后命令行的提示符前面会多出一个(.venv)前缀这就是环境生效的标志。之后的west命令都要在这个虚拟环境里执行所以我一般会在~/.bashrc里加一行自动激活echo source ~/zephyrproject/.venv/bin/activate ~/.bashrc这样每次打开终端都自动进入虚拟环境省得忘记激活导致west命令找不到。安装完成后验证一下west --version能输出版本号说明west已经就绪。2.3 确认工具链版本CMake与Python的版本要求Zephyr对基础工具的版本有硬性要求比较关键的是CMake需要3.20以上Python需要3.8以上Ninja需要1.10以上。Ubuntu 22.04自带的CMake是3.22.xPython是3.10.x直接满足要求Ubuntu 24.04版本更高更没问题。可以通过下面这组命令快速核对版貌cmake --version python3 --version ninja --version gperf --version如果CMake版本不够不建议自己从源码编译直接用apt安装系统自带的版本最省心。Zephyr对版本的要求其实比较宽容并不是非最新不可官方支持测试版本范围内能跑就行。3. 工作区初始化与Zephyr源码同步3.1 使用west init创建workspace在虚拟环境激活的状态下开始初始化workspace。cd ~/zephyrproject west init -m https://github.com/zephyrproject-rtos/zephyr .这条命令会在当前目录初始化一个manifest管理的工作区。特别注意最后的那个.表示以当前目录作为workspace根目录所以执行前一定要先进入目标目录。如果省略路径参数west会默认使用当前目录。初始化完成之后目录下会多出一个.west文件夹和一个west.yml清单文件。这时候源码树还没有完全拉全只能算搭好了骨架。3.2 west update拉取全部组件接着执行最关键的一步west updatewest会读取west.yml清单文件把Zephyr主仓库、hal、CMSIS、各种bootloader、SoC厂商支持包全部拉取到本地。这一步下载量比较大实际运行过程中可能会卡住这属于正常现象保持网络通畅耐心等待即可。如果中途断了直接重新执行west updategit具备断点续传能力已拉取的部分不会重复下载。拉取完成之后目录结构大致是这样的zephyr/主仓库包含kernel、drivers、samples、doc等modules/HAL、加密库、文件系统等外部模块bootloader/MCUboot等启动代码.west/west配置和manifest信息3.3 为什么必须用west而不是直接git clone很多新手会问我单独把Zephyr克隆下来不行吗真不行。Zephyr的构建系统在编译时会根据manifest找外部module的头文件和库文件如果这些模块缺失编译到一半就会报各种“cannot find hal_stm32”“cannot find cmsis”之类的错误。west相当于Zephyr世界里的包管理工具它和git的关系大概类似于apt和dpkg的关系git只是最底层的版本管理工具west在git之上做了多仓库协调。它知道每个组件应该放在哪个位置还负责处理仓库之间的依赖关系。更妙的是切换不同Zephyr版本时west能把所有关联仓库对齐到对应版本避免库和内核版本不匹配导致的诡异问题。所以我的建议是所有涉及Zephyr源码的操作都通过west来做包括查看分支、切换版本、更新代码。手动git pull很容易把workspace搞乱。4. Zephyr SDK安装与工具链对接4.1 SDK下载与解压Zephyr SDK是交叉编译工具链的集合里面包含了针对不同CPU架构的GCC编译器、GDB调试器、QEMU模拟器和各种主机工具。下载地址在Zephyr官方GitHub的sdk-ng仓库Releases页面选择文件名包含linux-x86_64的.tar.xz压缩包。以0.16版本的包为例下载命令大致是wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/zephyr-sdk-0.16.8/zephyr-sdk-0.16.8_linux-x86_64.tar.xz解压到一个固定目录我习惯放在主目录下tar xf zephyr-sdk-0.16.8_linux-x86_64.tar.xz mv zephyr-sdk-0.16.8 ~/zephyr-sdk强烈建议解压后先校验下载完整性。在下载页面找到对应的SHA256校验值然后执行sha256sum zephyr-sdk-0.16.8_linux-x86_64.tar.xz如果校验结果和页面一致再解压。我吃过一次亏下载中断后文件损坏解压勉强成功但编译器不可用折腾了两个小时才发现是SDK包的问题。4.2 setup.sh脚本做了什么SDK目录下有一个setup.sh运行它会把SDK的host工具安装到系统可执行路径中cd ~/zephyr-sdk ./setup.sh执行过程中可能会提示输入用户密码这是因为它需要把一些elf工具软链接到系统目录。setup.sh会把sysroots/x86_64-pokysdk-linux/usr/bin下的工具复制或链接到/usr/local/bin等位置让west和cmake能直接找到这些工具。如果你不想安装到系统路径也可以跳过setup.sh仅通过环境变量指定SDK位置。不过我还是建议正常执行这个脚本因为很多构建流程会依赖系统路径中的arm-zephyr-eabi-gdb、qemu-system-*等程序用系统装好的最方便。首次执行记得记录输出的最后几行它会提示你是否需要安装额外的工具链。4.3 环境变量配置与常见错误SDK装好后还需要让Zephyr构建系统知道编译器在哪里。编辑~/.bashrc加入这两行export ZEPHYR_TOOLCHAIN_VARIANTzephyr export ZEPHYR_SDK_INSTALL_DIR$HOME/zephyr-sdk然后执行source ~/.bashrcZEPHYR_TOOLCHAIN_VARIANTzephyr告诉构建系统使用Zephyr官方SDK作为交叉编译工具链而不是系统自带的gcc。这一点特别关键如果不设置cmake会尝试用宿主机的gcc编译Zephyr的内核那是完全跑不通的。ZEPHYR_SDK_INSTALL_DIR指定SDK的安装目录。注意这个变量指向SDK根目录不需要在末尾加上具体的版本号路径west会自动扫描该目录下的工具链子目录。如果这两个变量没配置好最常见的报错是CMake Error at cmake/modules/dts.cmake... Could not find a suitable Zephyr toolchain看到这类错误优先检查环境变量是否正确设置。5. 编译并运行第一个例程hello_world5.1 编译qemu_x86平台示例环境和SDK都就绪后进入workspace目录开始编译Zephyr自带的hello_world示例。cd ~/zephyrproject west build -b qemu_x86 -p samples/basic/hello_world参数说明-b qemu_x86指定目标平台为QEMU模拟的x86 Borad-p是--pristine的简写表示执行一次干净构建清空可能存在的旧构建缓存。首次编译时Zephyr会先生成设备树相关文件和配置文件再编译内核和示例代码。第一次编译耗时比较长三到五分钟都很正常。编译成功后终端末尾会显示构建产物路径Memory: 2626 bytes ... Flashing files...生成的固件在build/zephyr/目录下包括zephyr.elf、zephyr.bin、zephyr.hex三种格式。zephyr.elf包含调试符号是调试器用的zephyr.bin是纯二进制直接烧录用zephyr.hex是Intel HEX格式很多下载工具要求这个格式。5.2 使用QEMU运行与验证编译qemu_x86平台的其中一个优势就是不需要真实硬件就能运行验证。在同一个终端里执行west build -t run这个命令会启动QEMU模拟器然后你会在终端里看到类似下面这样的输出Welcome to the Zephyr Real Time Kernel Hello World! x86看到这行就说明Zephyr内核已经成功跑起来了。退出QEMU的方式是CtrlA X先按CtrlA再按X键不要随手按CtrlC否则可能无法正常退出虚拟机进程。QEMU模式的优势是方便快捷它适合验证内核基本功能但无法模拟真实板卡的IO和外设时序所以跑完QEMU之后强烈建议在真实开发板上再烧一次固件。5.3 针对真实开发板的烧录准备如果你手里有支持的开发板比如常见的STM32系列、nRF系列用west build指定实际板卡的board名称重新编译一次west build -b board-name -p samples/basic/hello_worldboard名称可以通过west boards命令查看完整列表。比如我手头的nRF52840DK对应的名称是nrf52840dk_nrf52840。编译完成后烧录west flashwest会根据板卡的调试器类型自动调用OpenOCD、pyOCD或J-Link工具。烧录之前先把开发板通过USB连接到电脑并确认系统能识别到调试器。6. 常见问题与排查技巧实录6.1 依赖安装失败的经典场景最常遇到的就是apt install时报Unable to locate package。这个多半是软件源没刷新的问题先执行sudo apt update再重新安装。如果还不行检查软件源配置文件看看是不是把不同发行版的源混在一起了。另一个高频错误是You have held broken packages这通常是因为软件包依赖关系已经损坏。先用sudo apt --fix-broken install修复再继续装。我之前在Ubuntu 22.04上装gcc-multilib就碰到过卡在依赖上的情况修复之后问题才解决。安装gcc失败也比较常见特别是同时手动装过其他版本的gcc之后。建议直接用apt安装系统版本的gcc不要从源码编译安装否则会把系统gcc覆盖掉连带引发一堆编译链问题。6.2 west命令找不到或pip权限问题如果你是按照虚拟环境的方式安装west基本不会遇到这个问题。但如果你之前用了sudo pip install west然后打开新终端又执行west --version提示找不到命令不要惊讶。新终端没有激活虚拟环境或者路径没有配置完整。先激活虚拟环境或者检查west所在的路径which west如果是装在用户目录执行export PATH$HOME/.local/bin:$PATH把该路径加到~/.bashrc即可。有一点要特别提醒不要用sudo pip install这会把west装到系统Python的site-packages里一旦系统Python升级或出现权限冲突整个环境的稳定性都会受影响。6.3 SDK下载解压不完整导致编译失败SDK的tar.xz压缩包体积动辄数百MB网速不稳定时很容易下载失败。如果你的提示栏显示下载完成了但解压时出现unexpected EOF或者gzip: invalid compressed data先不要急于重新解压很可能压缩包本身就是坏的。用前面提到的sha256sum对照官方校验和确认无误再解压。如果校验不匹配删除压缩包重新下载。另外解压SDK之后最好执行./setup.sh时多留意输出内容有些版本会明确提示缺失的组件。6.4 编译过程中CMake报错怎么定位编译报错是家常便饭重要的是掌握定位思路。如果报错指向CMakeCache.txt相关基本可以判断构建缓存出了问题最简单的办法就是把build目录整个删掉再重新编译rm -rf build west build -b qemu_x86 -p samples/basic/hello_world如果报错提示host tools not found or too old就去检查cmake和ninja的版本。如果报错信息里出现No board found说明board名称写错了用west boards查一下正确的名称。另外千万注意不要直接进入build目录执行cmakeZephyr的构建必须通过west命令来驱动这是很多新手容易踩的坑。直接cmake大概率会报出一堆看不懂的配置错误。6.5 无法识别USB串口或烧录失败开发板用USB连接电脑后执行lsusb dmesg | tail -20确认调试器的USB设备是否被识别。如果是串口工具访问/dev/ttyUSB0没有权限说明用户不在dialout组里执行sudo usermod -aG dialout $USER然后注销重新登录或者重启一下系统。烧录失败还有一个常见原因是开发板没有进入boot模式很多板子需要按住复位键或者拨动boot跳线开关具体要看板卡引导说明。我踩过最典型的一个坑是烧录工具能识别到调试器但一直报Cannot connect to target。最后发现是调试器固件版本太旧去厂商官网更新了调试器的固件才解决。最后聊几句实在话从零搭建Zephyr环境说难也难说简单也简单。难在你需要对它的工具链体系有一个整体认知简单在于只要按本文顺序一步步操作一般不会有什么意外。我个人实际操作中的体验是不要在SDK环境变量和west这两个点上省时间它们决定了后续所有项目开发的基础。另外刚开始接触Zephyr不用急着追最新版本选一个官方支持周期内的稳定版本就够了把环境跑通之后再去探索多板卡和多模块的方案扩展反而更从容。
返回列表