尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Windows平台Zephyr RTOS开发环境搭建与编译实战指南

Windows平台Zephyr RTOS开发环境搭建与编译实战指南 1. 项目缘起为什么要在Windows上折腾Zephyr最近在搞一个物联网的小玩意儿需要用到实时操作系统。市面上RTOS不少FreeRTOS、RT-Thread都玩过但这次想试试更“新潮”一点的于是盯上了Zephyr。这玩意儿是Linux基金会旗下的项目主打一个轻量、模块化支持一堆芯片架构社区也挺活跃。但官方文档和社区讨论里默认的开发环境基本都是Linux或者macOS命令行操作丝滑流畅。可我手头的主力机是Windows重装系统太麻烦虚拟机又觉得性能有损耗所以就想能不能在Windows上把这套环境给搭起来直接编译Zephyr这个想法一冒出来我就知道要踩坑了。Zephyr的构建系统严重依赖Unix-like环境比如bash、make、python脚本而Windows的cmd和PowerShell是另一套逻辑。直接硬搞肯定不行得找个“中介”。网上搜了一圈发现大家基本都指向两个方案用Windows Subsystem for Linux或者用Docker。WSL相当于在Windows里跑一个轻量级的Linux子系统原生兼容性好Docker则是容器化环境隔离更干净。我琢磨了一下这次就想在“原生”的Windows环境下尽可能少地引入额外抽象层所以决定先挑战一下纯Windows环境如果实在不行再上WSL。这个过程说白了就是一场与构建工具链、环境变量和路径格式的“搏斗”。2. 环境准备打造Windows下的“类Unix”工坊在Windows上编译Zephyr核心矛盾在于它的工具链和脚本是为Unix环境设计的。我们的目标不是改变Zephyr而是让Windows能“理解”并执行这些命令。这就需要一系列工具的辅助。2.1 核心工具三件套Git、Python与CMake这三样是基石缺一不可。首先得装Git。Zephyr的源代码、还有它依赖的各种模块Module都是通过Git来管理的。去Git官网下载Windows版本安装就行。安装时注意一点在“Adjusting your PATH environment”这一步建议选择“Git from the command line and also from 3rd-party software”。这会把Git的可执行文件目录加到系统PATH里以后在CMD或者PowerShell里就能直接敲git命令了。不然你还得手动去Git的安装目录下找git.exe很麻烦。其次是Python。Zephyr的构建系统、项目配置脚本west命令都是用Python写的。一定要去Python官网下载安装Python 3.8或以上的版本。安装时务必勾选“Add Python 3.x to PATH”这是老生常谈但总有人忘的坑。安装完打开一个新的命令行窗口一定要新开否则环境变量不生效输入python --version和pip --version确认安装成功。接下来我们需要用pip安装Zephyr专用的Python包主要是west。west是Zephyr的多仓库管理工具用来拉取代码、管理依赖、执行构建命令。在命令行里运行pip install west如果遇到网络问题导致pip安装慢或失败可以尝试使用国内的镜像源例如pip install west -i https://pypi.tuna.tsinghua.edu.cn/simple最后是CMake。Zephyr使用CMake作为跨平台的构建系统生成器。去CMake官网下载Windows平台的安装包安装过程很简单。同样在安装向导里记得勾选“Add CMake to the system PATH for all users”或类似选项。安装完成后新开命令行输入cmake --version验证。2.2 关键先生GNU工具链与Windows端口这是最棘手的一步。Zephyr编译需要GNU的编译工具链比如gcc、binutils、gdb等。在Linux上一个apt-get install gcc-arm-none-eabi就搞定了。在Windows上我们需要一个预编译好的、能在Windows命令行下运行的GNU工具链。这里首推Zephyr SDK。这是Zephyr官方维护的、捆绑了所有必要工具链的集成包。它的Windows版本自带了一个修改过的MSYS2环境一个在Windows上提供Unix工具集的软件使得里面的make、bash等工具可以在Windows的CMD里被直接调用。去Zephyr官网的下载页面找到“Zephyr SDK”部分选择Windows的安装包通常是一个.exe文件下载并运行。安装Zephyr SDK时路径不要有中文和空格比如我就装在C:\zephyr-sdk-0.16.5。安装程序会询问是否将工具链添加到环境变量一定要选“是”。它会向系统的PATH里添加类似C:\zephyr-sdk-0.16.5\sysroots\i686-pokysdk-mingw32\usr\bin这样的路径这里面就包含了arm-none-eabi-gcc.exe等关键工具。注意Zephyr SDK的安装器可能会尝试运行一个脚本来设置一些环境变量有时这个脚本在非管理员权限下会执行不完整。安装完成后最好手动检查一下系统环境变量PATH里是否确实包含了SDK的bin目录。如果没有就手动加进去。如果因为网络原因无法下载完整的Zephyr SDK或者你只需要针对特定架构如ARM的工具链也可以考虑使用GNU Arm Embedded Toolchain的独立Windows版本。去ARM官网或开发者网站下载解压到一个路径如C:\gcc-arm然后手动将这个路径下的bin目录例如C:\gcc-arm\bin添加到系统PATH。但这样你还需要单独安装make、dtc设备树编译器等工具更麻烦所以不推荐新手这么做。2.3 环境变量大统ZEPHYR_BASE与PATH工具装好了还得让它们彼此认识。这里有两个关键环境变量。第一个是ZEPHYR_BASE。这个变量告诉系统Zephyr源代码的根目录在哪里。我们待会儿会拉取代码假设你决定把代码放在D:\Projects\zephyrproject那么ZEPHYR_BASE就应该设置为D:\Projects\zephyrproject\zephyr。你可以在系统环境变量里新建一个用户变量名称为ZEPHYR_BASE值为你的路径。第二个是PATH。我们需要确保以下路径按顺序包含在PATH中具体路径根据你的安装位置调整Python的Scripts目录例如C:\Users\YourName\AppData\Local\Programs\Python\Python39\Scripts这里存放着west.exe。Git的cmd目录例如C:\Program Files\Git\cmd。Zephyr SDK的bin目录例如C:\zephyr-sdk-0.16.5\sysroots\i686-pokysdk-mingw32\usr\bin。CMake的bin目录例如C:\Program Files\CMake\bin。设置完成后打开一个新的命令提示符CMD或PowerShell依次输入以下命令验证west --version git --version cmake --version arm-none-eabi-gcc --version make --version如果每个命令都能正确输出版本信息那么恭喜你最磨人的环境准备阶段基本过关了。如果make --version报错很可能是Zephyr SDK的路径没加对回去仔细检查PATH。3. 获取源码与初始化用West驾驭多仓库环境搞定接下来就是把Zephyr这棵“大树”及其“枝杈”模块搬下来。Zephyr项目采用“主仓库模块”的方式管理west工具就是用来同步所有这些代码的。3.1 初始化工作区首先找一个合适的目录比如D:\Projects然后在命令行里进入这个目录执行初始化命令west init zephyrproject这个命令会创建一个名为zephyrproject的文件夹并在里面初始化一个west工作区。west init默认会从Zephyr的官方Git仓库拉取manifest文件一个定义了所有仓库和版本的清单。实操心得国内网络直接克隆GitHub仓库可能会非常慢甚至超时。west init命令支持通过--mr指定一个manifest仓库的镜像地址。你可以先找一个国内的Git镜像站如gitee上是否有Zephyr manifest的镜像或者使用-m参数指定一个本地的manifest仓库URL。如果都没有那就需要一点耐心或者配置Git的代理。3.2 拉取所有源代码初始化完成后进入刚创建的目录并拉取所有在manifest中定义的代码cd zephyrproject west update这个west update命令是关键它会根据west init时获取的manifest文件克隆Zephyr主仓库zephyr以及所有依赖的模块仓库比如HAL库、传感器驱动等到当前目录下。这个过程耗时较长取决于你的网络和manifest定义的模块数量。拉取完成后你的zephyrproject目录结构大致如下zephyrproject/ ├── .west/ │ └── config # west工具的配置文件 ├── zephyr/ # Zephyr RTOS 主仓库 ├── modules/ # 各种外部模块如hal库、驱动 │ ├── hal/ │ ├── crypto/ │ └── ... └── (其他可能的目录)此时之前设置的ZEPHYR_BASE环境变量就应该指向zephyrproject\zephyr这个路径。3.3 导出Zephyr CMake包为了让CMake在构建时能够自动找到Zephyr我们需要运行一个导出脚本。这个脚本会设置一些CMake相关的环境变量。 在zephyrproject目录下执行west zephyr-export这个命令通常很快。它做的事情简单理解就是告诉系统“嘿Zephyr的CMake配置包在这里以后CMake找Zephyr就直接来这儿”。4. 编译实战从示例项目到自定义应用一切就绪终于可以开始编译了。我们从最简单的示例开始逐步深入。4.1 编译第一个示例BlinkyZephyr内置了大量示例位于zephyrproject\zephyr\samples目录下。最经典的莫过于blinky闪烁LED。我们以针对QEMU模拟器模拟ARM Cortex-M3芯片运行为例。首先为编译创建一个独立的构建目录build directory。这是一种最佳实践保持源码目录的纯净。# 进入blinky示例目录 cd zephyrproject\zephyr\samples\basic\blinky # 创建一个build目录 mkdir build cd build接下来使用CMake配置项目并指定目标平台和工具链。这里我们使用Zephyr的cmake封装命令更简洁# 针对QEMU模拟的mps2_an385板卡ARM Cortex-M3进行配置 cmake -GNinja -DBOARDmps2_an385 ..解释一下参数-GNinja: 指定生成Ninja构建文件。Ninja比传统的Make构建速度更快Zephyr推荐使用。-DBOARDmps2_an385: 这是最重要的参数指定了目标硬件板卡。mps2_an385是QEMU支持的一个虚拟板卡。对于真实的开发板比如流行的nrf52840dk_nrf52840Nordic芯片你就需要改成对应的板卡名称。所有支持的板卡列表可以在zephyrproject\zephyr\boards目录下找到。..: 表示CMakeLists.txt文件在上一级目录即blinky目录。配置成功后执行编译ninja如果一切顺利你会在build目录下看到生成的zephyr\zephyr.elf、zephyr\zephyr.bin等文件。要运行这个程序可以使用QEMUninja run这个命令会启动QEMU加载刚刚编译好的固件模拟运行。你应该能在QEMU窗口或控制台输出中看到虚拟LED闪烁的模拟信息。4.2 为真实硬件编译以nRF52840为例模拟器跑通了我们来编译一个能在真实硬件上运行的固件。以Nordic的nRF52840开发板为例。首先确保你的Zephyr SDK包含了对应的工具链ARM Cortex-M4。Zephyr SDK通常是全包含的。编译步骤和上面类似只是BOARD参数要改cd zephyrproject\zephyr\samples\basic\blinky mkdir build_nrf cd build_nrf cmake -GNinja -DBOARDnrf52840dk_nrf52840 .. ninja编译完成后在build_nrf目录下会生成zephyr\zephyr.hex文件。这个文件就可以通过J-Link、ST-Link等调试器或者使用nrfjprogNordic专用工具烧录到nRF52840开发板上了。4.3 创建与编译自定义应用项目总不能一直编译样例。我们需要创建自己的应用程序。Zephyr应用通常放在工作区目录下与zephyr目录平级。假设我们要创建一个叫my_app的项目# 回到zephyrproject根目录 cd D:\Projects\zephyrproject # 创建应用目录和必要的源文件 mkdir my_app cd my_app在my_app目录下创建两个核心文件1. CMakeLists.txt:# 寻找Zephyr的包。这依赖于之前west zephyr-export设置的环境变量。 find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) # 将当前目录声明为Zephyr项目 project(my_app) # 添加你的源文件 target_sources(app PRIVATE src/main.c)2. src/main.c:#include zephyr/kernel.h #include zephyr/drivers/gpio.h /* 假设你的开发板上LED0连接在GPIO的PIN_0上具体请查阅板卡定义 */ #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led GPIO_DT_SPEC_GET(LED0_NODE, gpios); void main(void) { int ret; if (!device_is_ready(led.port)) { return; } ret gpio_pin_configure_dt(led, GPIO_OUTPUT_ACTIVE); if (ret 0) { return; } while (1) { gpio_pin_toggle_dt(led); k_sleep(K_SECONDS(1)); } }然后和编译示例一样为你的应用创建构建目录并编译mkdir build cd build cmake -GNinja -DBOARDnrf52840dk_nrf52840 .. ninja这样你就成功编译了自己的第一个Zephyr应用程序。5. 疑难杂症与深度排坑指南在Windows上编译Zephyr不可能一帆风顺。下面是我踩过的一些坑和解决方案。5.1 路径与命令解释器引发的“血案”问题现象在west update或cmake配置阶段出现诸如/bin/sh: line 1: xxx: command not found或路径解析错误将C:\解析成C:/又出问题。根因分析这是Windows编译Zephyr最常见的问题。Zephyr的构建脚本.sh或.py中调用subprocess通常假设在Unix shell环境下运行它们使用Unix风格的路径分隔符/和命令如rm,cp。在Windows CMD中虽然Git Bash或Zephyr SDK提供了一些Unix工具但命令解释器shell环境可能不统一。特别是当CMake或Python脚本试图调用一个外部shell来执行命令时如果它错误地使用了Windows的cmd.exe而不是bash.exe就会导致找不到Unix命令。排查与解决检查默认Shell确保你的命令行环境是兼容的。最稳妥的方法是使用Git Bash安装Git时附带来执行所有Zephyr相关命令而不是CMD或PowerShell。Git Bash提供了一个更接近Linux的Bash环境。显式指定Shell如果必须在CMD中操作可以尝试在运行west或cmake前设置环境变量指定使用Bash。但这比较麻烦。使用Zephyr SDK提供的环境Zephyr SDK安装后有时会提供一个setup.cmd或类似脚本运行它可能会配置一个合适的环境。查看SDK安装目录下是否有这样的脚本。最根本的解决方案如果上述方法都无效或者你追求环境的纯粹性和稳定性强烈建议放弃纯Windows环境转而使用WSL2。在WSL2例如Ubuntu发行版中你可以获得一个原生的Linux环境完全按照Zephyr官方Linux文档操作几乎不会遇到路径和Shell问题。这其实是大多数资深开发者的选择。在Windows商店安装Ubuntu然后在WSL的Ubuntu终端里安装west、cmake、gcc-arm-none-eabi等工具后续流程就和Linux上一模一样了编译体验会好很多。5.2 Python包依赖与版本冲突问题现象执行west update或cmake时报ModuleNotFoundError缺少pyelftools、ply、packaging等Python包。根因分析Zephyr构建过程依赖一系列Python包。虽然west是一个包但Zephyr本身还需要其他包。这些依赖定义在zephyrproject\zephyr\scripts\requirements.txt等文件中。解决方案 在命令行中进入zephyrproject目录运行pip install -r zephyr\scripts\requirements.txt这行命令会安装Zephyr核心构建所需的所有Python依赖。如果遇到某个包版本冲突可以尝试先升级pippython -m pip install --upgrade pip或者使用虚拟环境venv来隔离Zephyr的Python环境。5.3 工具链版本不匹配或找不到问题现象CMake配置阶段报错提示找不到编译器The C compiler is not able to compile a simple test program或者链接阶段报奇怪的架构错误。排查步骤验证工具链路径首先确认arm-none-eabi-gcc等工具是否在PATH中。在命令行输入arm-none-eabi-gcc --version看能否输出信息。检查CMake工具链文件Zephyr通过CMake工具链文件来定位编译器。当指定-DBOARDxxx时Zephyr会自动选择对应的工具链文件如arm-none-eabi-gcc.cmake。这些文件位于zephyrproject\zephyr\cmake\toolchain。你可以手动检查这个目录下是否有你目标架构的文件。手动指定工具链在极少数情况下自动检测会失败。你可以尝试在CMake命令中显式指定工具链文件的绝对路径cmake -GNinja -DBOARDnrf52840dk_nrf52840 -DCMAKE_TOOLCHAIN_FILEC:/zephyr-sdk-0.16.5/cmake/zephyr/generic.cmake ..注意路径中的斜杠用了/这是CMake要求的格式。同时这个generic.cmake是SDK提供的它会再去调用具体的工具链文件。SDK版本兼容性确保你使用的Zephyr SDK版本与Zephyr源代码版本大致匹配。太旧的SDK可能不支持新Zephyr版本的某些特性。查看Zephyr官网的发布说明了解推荐的SDK版本。5.4 构建目录“污染”导致配置错误问题现象修改了板卡类型或源码后重新执行cmake但生成的配置似乎还是旧的。根因与解决CMake会在构建目录build中缓存之前的配置。直接再次运行cmake可能不会更新所有变量。最干净的做法是删除整个build目录然后重新创建并运行cmake。rmdir /s build # 在CMD中删除build目录 mkdir build cd build cmake -GNinja -DBOARDyour_board ..或者在构建目录内使用ninja clean清理编译产物但有时CMake缓存仍需手动删除CMakeCache.txt文件。6. 进阶配置与效率优化当基础编译流程跑通后可以关注一些提升开发效率的配置。6.1 使用Ninja加速构建如前所述使用-GNinja生成Ninja构建系统比默认的Make更快。你可以在west的配置文件中设置默认生成器避免每次敲-GNinja。在zephyrproject目录下执行west config build.generator ninja这样以后使用west build命令时这是west提供的更高级的构建命令它封装了创建构建目录和调用CMakeNinja的过程就会默认使用Ninja。6.2 利用West Build简化流程west build命令是更便捷的构建方式。它自动处理构建目录的创建和CMake的调用。例如编译blinky示例可以简化为cd zephyrproject\zephyr\samples\basic\blinky west build -b nrf52840dk_nrf52840-b参数指定板卡。编译输出默认在build目录。如果你想指定不同的构建目录可以加-d参数。6.3 配置编译选项与裁剪内核Zephyr内核高度可配置。配置通过Kconfig系统管理。最直观的配置方式是使用菜单界面# 在应用目录或示例目录下先完成初始CMake配置 cd my_app mkdir build cd build cmake -GNinja -DBOARDnrf52840dk_nrf52840 .. # 然后启动配置菜单 ninja menuconfig这会打开一个基于ncurses的文本图形界面你可以在这里浏览和修改成千上万个配置选项比如关闭不需要的功能以减少固件体积调整栈大小启用特定驱动等。修改后保存退出再运行ninja重新编译即可。6.4 调试配置使用J-Link与GDB在Windows上调试嵌入式程序通常需要J-Link调试器和GDB。Zephyr SDK已经包含了arm-none-eabi-gdb。安装J-Link软件从SEGGER官网下载并安装J-Link软件包。它会安装驱动和JLinkGDBServer等工具。编译带调试信息的固件默认的ninja命令生成的elf文件就包含调试信息。启动GDB服务器打开一个命令行运行JLinkGDBServer -device nRF52840_xxAA -if SWD -speed 4000指定你的设备型号、接口和速度。启动GDB并连接在另一个命令行中进入你的构建目录build运行arm-none-eabi-gdb zephyr\zephyr.elf在GDB提示符下连接服务器(gdb) target remote localhost:2331然后就可以使用load命令加载程序b main设置断点c继续运行等标准GDB命令进行调试了。整个过程下来虽然在纯Windows环境下搭建Zephyr编译环境比在Linux或WSL下要繁琐需要仔细处理工具链和环境变量但一旦打通就为在熟悉的Windows桌面环境下进行嵌入式开发提供了一种可能。不过对于长期、复杂的Zephyr项目开发我个人的体会是切换到WSL2环境会省去大量与环境搏斗的精力让你更专注于代码和逻辑本身。这次在Windows上的探索更像是一次对Zephyr构建系统底层依赖的深度理解过程知道了那些在Linux上看似理所当然的命令背后到底需要哪些组件的支持。
返回列表