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运行时。
上图展示了从主机依赖到最终烧录验证的完整工程链路。在后续小节中,我们将逐一拆解每个环节的具体操作、关键参数和常见问题。请务必按照顺序执行,因为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会在此目录下查找对应的工具链配置文件。
操作流程
- 安装主机依赖包:在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
- 下载并安装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包
- 设置环境变量:将以下内容添加到
~/.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
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仓库内)描述了需要拉取的仓库列表。
操作流程
- 安装west:使用pip安装,并确保pip版本较新。
pip3 install --user west
export PATH=~/.local/bin:$PATH
- 初始化工作区:创建一个目录(如
~/zephyrproject),并初始化west。
cd ~
mkdir zephyrproject && cd zephyrproject
west init -m https://github.com/zephyrproject-rtos/zephyr --mr v3.7.0 # 指定版本分支
- 拉取所有模块:执行
west update,该命令会读取zephyr/west.yml并下载所有依赖仓库(如hal_stm32、mcuboot等)。
west update
- 导出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则控制内核功能(如堆栈大小、外设驱动使能)。
操作流程
- 创建工程目录:在
~/zephyrproject下创建应用。
cd ~/zephyrproject
mkdir -p apps/hello_world/src
cd apps/hello_world
- 编写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)
- 编写prj.conf:启用UART控制台输出。
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_PRINTK=y
- 编写src/main.c:
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
void main(void)
{
printk("Hello TVM Micro on Zephyr!\n");
}
- 构建工程:指定目标板为
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中预先配置。
操作流程
- 检查工具链版本:
arm-zephyr-eabi-gcc --version
cmake --version
west --version
- 验证调试器连接:
west build -t runner -d build
该命令会尝试通过OpenOCD连接ST-Link,并输出目标芯片ID。若失败,检查udev规则和硬件连接。
- 使用模板创建工程: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驱动问题 |