4、开发环境搭建:安装Zephyr SDK、配置west、创建基础Zephyr工程

在开始TVM Micro在Zephyr上的部署之前,必须先构建一套完整、可复现的Zephyr开发环境。Zephyr RTOS的构建系统基于CMake和Python,其依赖管理、工具链配置和工程结构与传统嵌入式IDE(如Keil、IAR)有显著差异。本章将围绕三个核心任务展开:安装Zephyr SDK(工具链与主机依赖)、配置west(Zephyr的元工具与工作流管理器)、以及创建并编译一个基础Zephyr工程。我们将以Ubuntu 22.04 LTS(x86_64)作为主机环境,目标板选用STM32F407VET6(Cortex-M4F),该平台具备充足的RAM/Flash资源,适合后续部署TVM Micro运行时。

Zephyr开发环境搭建与工程创建链路 ① 主机依赖 CMake ≥ 3.20 Python ≥ 3.10 dtc / ninja / gperf ② Zephyr SDK 工具链 (arm-zephyr-eabi) 主机工具 (QEMU, openocd) 环境变量 ZEPHYR_SDK_INSTALL_DIR ③ west 配置 pip install west west init && west update west config / 环境变量 ④ 创建工程 west build -b stm32f407ve hello_world 构建验证与产物检查 west build -t menuconfig (配置检查) build/zephyr/zephyr.elf (ELF 产物) west flash (烧录验证) west build -t runner (调试器探测) 核心链路:主机依赖 → SDK工具链 → west工作流 → 工程构建 → 烧录验证

上图展示了从主机依赖到最终烧录验证的完整工程链路。在后续小节中,我们将逐一拆解每个环节的具体操作、关键参数和常见问题。请务必按照顺序执行,因为west的初始化依赖于Python环境和网络访问,而SDK的安装则决定了后续编译时使用的工具链路径。

4.1 安装Zephyr SDK:工具链与主机依赖

核心原理

Zephyr SDK并非仅仅是一个交叉编译器,它是一套完整的开发工具集合,包含针对多种架构的GCC工具链(如arm-zephyr-eabi-gcc)、主机端调试工具(如QEMU、OpenOCD、JLink)、以及Zephyr构建所需的二进制工具(如dtc、ninja)。SDK的版本必须与Zephyr RTOS主分支或你使用的LTS版本匹配。例如,Zephyr v3.7 LTS通常要求SDK 0.16.x或更高版本。SDK安装后,其路径通过环境变量ZEPHYR_SDK_INSTALL_DIR暴露给构建系统,CMake会在此目录下查找对应的工具链配置文件。

操作流程

  1. 安装主机依赖包:在Ubuntu上执行以下命令,确保基础工具齐全。
sudo apt update
sudo apt install --no-install-recommends git cmake ninja-build gperf \
  ccache dfu-util device-tree-compiler wget \
  python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
  make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1
  1. 下载并安装Zephyr SDK:推荐使用官方提供的自解压安装脚本。以SDK 0.16.8为例:
cd ~
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.8/zephyr-sdk-0.16.8_linux-x86_64.tar.xz
tar xf zephyr-sdk-0.16.8_linux-x86_64.tar.xz
cd zephyr-sdk-0.16.8
./setup.sh -t all -h -c   # -t all 安装所有工具链,-h 安装主机工具,-c 安装CMake包
  1. 设置环境变量:将以下内容添加到~/.bashrc或~/.zshrc中。
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-0.16.8
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
export PATH=$PATH:$ZEPHYR_SDK_INSTALL_DIR/arm-zephyr-eabi/bin
经验提醒:如果使用VS Code或CLion,建议在IDE的终端环境中也加载上述环境变量,否则可能出现“找不到编译器”的错误。另外,setup.sh脚本会尝试安装udev规则,用于OpenOCD访问USB调试器,务必允许执行。

案例拆解:SDK版本不匹配导致的编译失败

背景:某开发者在Ubuntu 20.04上使用Zephyr v3.5分支,但安装了SDK 0.15.0。执行west build时,CMake报错Zephyr SDK version 0.15.0 is not supported by Zephyr v3.5.0。分析:Zephyr的cmake/modules/zephyr_default.cmake中定义了最低SDK版本要求。解决方法是升级SDK至0.16.x,或使用west update将Zephyr回退到与SDK匹配的版本。此案例说明,SDK与Zephyr版本必须同步管理,建议在项目根目录的west.yml中固定Zephyr版本和SDK版本。

常见误区

  • 误区1:只安装GCC工具链,忽略主机工具。这会导致无法使用west debug或QEMU仿真。
  • 误区2:将SDK安装在包含空格的路径下(如C:\Program Files\...),CMake解析会失败。
  • 误区3:忘记安装device-tree-compiler,导致设备树编译时报dtc: command not found。

4.2 配置west:工作流管理器与多仓库管理

核心原理

west是Zephyr的元工具,它基于Python的pyyaml和colorama库,用于管理Zephyr及其模块(如MCUboot、Hal库)的多仓库结构。west通过west.yml清单文件定义项目依赖,支持分支、标签和提交级别的锁定。其核心命令包括west init(初始化工作区)、west update(拉取所有模块)、west build(构建)、west flash(烧录)。理解west的“manifest”和“workspace”概念至关重要:workspace是包含所有仓库的根目录,而manifest文件(通常位于zephyr仓库内)描述了需要拉取的仓库列表。

操作流程

  1. 安装west:使用pip安装,并确保pip版本较新。
pip3 install --user west
export PATH=~/.local/bin:$PATH
  1. 初始化工作区:创建一个目录(如~/zephyrproject),并初始化west。
cd ~
mkdir zephyrproject && cd zephyrproject
west init -m https://github.com/zephyrproject-rtos/zephyr --mr v3.7.0  # 指定版本分支
  1. 拉取所有模块:执行west update,该命令会读取zephyr/west.yml并下载所有依赖仓库(如hal_stm32、mcuboot等)。
west update
  1. 导出Zephyr CMake包:为了让CMake能够找到Zephyr,需要导出包。
west zephyr-export
风险说明:west update会拉取大量代码(约1-2GB),网络不稳定时容易中断。建议使用west update -o -k保留已下载的仓库,或配置git的http.postBuffer。另外,不要手动修改zephyr仓库内的文件,否则后续west update可能产生冲突。

案例拆解:使用west管理自定义板级支持包(BSP)

场景:团队需要为自研的STM32F407板卡添加BSP。在zephyrproject目录下,创建modules/bsps目录,并在zephyr/west.yml中追加以下内容:

manifest:
  projects:
    - name: my_company_bsps
      path: modules/bsps
      remote: https://github.com/mycompany/bsps.git
      revision: main

然后执行west update,即可将自定义BSP仓库拉取到本地。在构建时,通过west build -b my_stm32f407指定板卡名称,Zephyr的构建系统会自动在modules/bsps中查找boards目录下的定义。此案例展示了west的多仓库扩展能力,是团队协作中常见的做法。

常见误区

  • 误区1:在west init后直接运行west build,忘记执行west update,导致缺少HAL库。
  • 误区2:使用sudo pip install west,导致权限混乱,且与系统Python环境冲突。
  • 误区3:修改west.yml后不执行west update,依赖关系未同步。

4.3 创建基础Zephyr工程:hello_world与板级配置

核心原理

Zephyr工程的结构遵循CMake约定。每个应用至少包含CMakeLists.txt、prj.conf(内核配置)、src/main.c。构建系统通过west build调用CMake,并自动处理设备树(.dts)、配置碎片(.conf)和链接脚本。对于STM32F407,板级定义位于zephyr/boards/arm/stm32f407ve,其中包含board.cmake、Kconfig.board和stm32f407ve.dts。理解设备树是Zephyr开发的关键,它描述了硬件资源(如UART、GPIO、时钟),而prj.conf则控制内核功能(如堆栈大小、外设驱动使能)。

操作流程

  1. 创建工程目录:在~/zephyrproject下创建应用。
cd ~/zephyrproject
mkdir -p apps/hello_world/src
cd apps/hello_world
  1. 编写CMakeLists.txt:
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)
  1. 编写prj.conf:启用UART控制台输出。
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_PRINTK=y
  1. 编写src/main.c:
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

void main(void)
{
    printk("Hello TVM Micro on Zephyr!\n");
}
  1. 构建工程:指定目标板为stm32f407ve。
cd ~/zephyrproject/apps/hello_world
west build -b stm32f407ve -d build

构建成功后,产物位于build/zephyr/zephyr.elf和zephyr.bin。使用west flash烧录(需连接ST-Link)。

关键参数说明:-b指定板卡名称,-d指定构建目录。若使用自定义板卡,需将boards目录放在工程根目录或通过west config指定zephyr.base。对于STM32F407,默认调试器为ST-Link,board.cmake中已配置好openocd接口。

案例拆解:解决链接错误“region 'FLASH' overflowed”

现象:在添加了较多调试日志后,编译报错region 'FLASH' overflowed by 1234 bytes。分析:STM32F407VET6的Flash为512KB,而Zephyr默认的链接脚本将整个Flash分配给应用。通过west build -t menuconfig查看CONFIG_FLASH_SIZE,发现其值为0x80000(512KB),但实际可用空间因Bootloader预留而减少。解决:在prj.conf中设置CONFIG_FLASH_LOAD_OFFSET=0x20000(预留128KB给MCUboot),并调整CONFIG_FLASH_LOAD_SIZE。此案例说明,理解链接脚本和内存布局对于资源受限的MCU至关重要。

常见误区

  • 误区1:直接复制其他板卡的prj.conf,导致外设配置冲突(如UART引脚复用错误)。
  • 误区2:忘记在CMakeLists.txt中添加find_package(Zephyr),导致CMake无法定位Zephyr构建系统。
  • 误区3:使用west build时未指定-d,导致构建产物混乱,难以管理多个配置。

4.4 环境验证与工程模板管理

核心原理

验证环境是否就绪,不仅需要编译通过,还需要确认调试器连接、串口输出和时钟配置正确。Zephyr提供了west build -t runner来探测调试器,以及west debug启动GDB会话。此外,使用west build -t menuconfig可以图形化查看内核配置,确保所需模块(如CONFIG_GPIO、CONFIG_I2C)已启用。对于TVM Micro部署,后续还需要启用CONFIG_CPP、CONFIG_NEWLIB_LIBC等选项,这些都可以在prj.conf中预先配置。

操作流程

  1. 检查工具链版本:
arm-zephyr-eabi-gcc --version
cmake --version
west --version
  1. 验证调试器连接:
west build -t runner -d build

该命令会尝试通过OpenOCD连接ST-Link,并输出目标芯片ID。若失败,检查udev规则和硬件连接。

  1. 使用模板创建工程:Zephyr提供了west create命令,但更常用的是复制官方示例。
cp -r $ZEPHYR_BASE/samples/hello_world ~/zephyrproject/apps/my_hello
cd ~/zephyrproject/apps/my_hello
west build -b stm32f407ve

案例拆解:串口无输出的排查流程

现象:烧录后,串口终端无任何打印。排查步骤:① 检查prj.conf中CONFIG_UART_CONSOLE是否启用;② 查看设备树stm32f407ve.dts中usart1的引脚定义(PA9/PA10),确认与硬件连接一致;③ 使用west build -t menuconfig检查CONFIG_SERIAL_HAS_DRIVER;④ 测量板卡上UART_TX引脚电平,确认是否有数据跳变。最终发现是板卡上的RS232电平转换芯片供电异常,导致TTL信号无法输出。此案例强调,软件配置正确后,硬件链路仍是排查重点。

常见误区

  • 误区1:认为west flash一定成功,忽略调试器固件版本过旧的问题。
  • 误区2:在Windows环境下使用WSL,但未配置USB passthrough,导致无法识别ST-Link。
  • 误区3:修改设备树后不重新生成devicetree_generated.h,直接编译导致宏定义缺失。
检查项 命令/文件 预期结果 常见失败原因
SDK路径 echo $ZEPHYR_SDK_INSTALL_DIR 显示SDK根目录 环境变量未导出
west版本 west --version ≥0.14.0 pip安装失败
工具链编译 arm-zephyr-eabi-gcc -v 显示版本信息 PATH未包含bin目录
构建产物 build/zephyr/zephyr.elf 文件存在且非空 链接脚本错误
调试器探测 west build -t runner 输出“Target voltage: 3.3V” ST-Link驱动问题