如果你正在尝试把 Zephyr RTOS 跑在 STM32F103C8T6 这种常见的最小系统板上,环境变量配置往往是第一个实际门槛。很多人卡在这一步,不是因为 Zephyr 本身复杂,而是因为环境变量没配对,导致工具链找不到、编译报错、烧录失败。
这篇文章会直接带你走一遍我在实际项目里验证过的配置流程,重点不是讲 Zephyr 多强大,而是让你能在普通 Windows 或 Linux 环境下,把基础环境变量配对,顺利编译并烧录一个示例程序到 STM32F103C8T6 板上。
1. 先搞清楚 Zephyr 环境变量到底管什么
Zephyr 的环境变量核心是告诉系统三件事:工具链在哪、SDK 在哪、当前项目怎么找依赖。很多人一上来就照搬教程设置ZEPHYR_BASE,但经常忽略工具链路径和 CMake 变量,导致编译时找不到编译器或头文件。
1.1 关键变量清单
这几个变量必须设对,缺一不可:
- ZEPHYR_BASE: Zephyr 源码根目录路径,编译时 CMake 靠它定位内核和模块。
- ZEPHYR_TOOLCHAIN_VARIANT: 工具链类型,比如
gnuarmemb(ARM GCC 嵌入式版)或zephyr(如果用 Zephyr SDK)。 - GNUARMEMB_TOOLCHAIN_PATH(如果选 gnuarmemb): ARM GCC 工具链的安装路径。
另外,如果你用 Zephyr SDK,通常不需要手动设工具链路径,但需要确保 SDK 安装正确且版本匹配。
1.2 为什么容易配错
最常见的问题是把ZEPHYR_BASE设成了子目录(比如samples/hello_world),而不是真正的源码根目录。另一个高频错误是工具链路径里带了bin子目录(比如设成C:\gcc-arm\bin而不是C:\gcc-arm),导致 CMake 找不到arm-none-eabi-gcc。
我建议先通过一个小测试验证变量是否生效:打开终端,输入echo %ZEPHYR_BASE%(Windows)或echo $ZEPHYR_BASE(Linux/Mac),看输出是不是正确的完整路径。
2. 准备你的实战环境
在配环境变量之前,先把基础软件装好。下面是我在 Windows 和 Ubuntu 22.04 上实测可用的组合。
2.1 硬件和软件清单
- 开发板: STM32F103C8T6 最小系统板(核心芯片是 Cortex-M3)。
- 调试器: ST-Link V2(便宜常见,烧录和调试都支持)。
- 主机系统: Windows 10/11 或 Ubuntu 22.04 LTS。
- 必备软件:
- Git:用于拉取 Zephyr 源码和模块。
- CMake 3.20.5 或更高版本:Zephyr 的构建系统依赖它。
- Python 3.8 或更高版本:Zephyr 的脚本工具用 Python 写的。
- ARM GCC 工具链:建议用官方
arm-none-eabi-gcc,版本 12.3 或 13.2 都行。
不要急着装 Zephyr SDK,先用 ARM GCC 工具链走通流程,之后再换 SDK 会更简单。
2.2 安装 ARM GCC 工具链
Windows 用户直接下载 ARM GNU Toolchain 官方安装包 ,选 “AArch32 bare-metal target (arm-none-eabi)” 版本,安装到不含空格的路径,比如C:\gcc-arm\13.2\。
Linux 用户可以用包管理器安装:
sudo apt update sudo apt install gcc-arm-none-eabi装完后验证工具链是否可用:
arm-none-eabi-gcc --version如果提示命令找不到,说明安装路径没加入 PATH,或者需要重启终端。
3. 一步步配置环境变量
我推荐手动设置环境变量,而不是依赖安装脚本。手动设置能让你更清楚每个变量的作用,出错了也容易排查。
3.1 Windows 用户配置步骤
- 右键“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”。
- 在“系统变量”部分,新建或编辑以下变量:
| 变量名 | 值示例 | 说明 |
|---|---|---|
ZEPHYR_BASE | C:\zephyrproject\zephyr | 替换为你的 Zephyr 源码实际路径 |
ZEPHYR_TOOLCHAIN_VARIANT | gnuarmemb | 固定值,表示用 ARM GCC |
GNUARMEMB_TOOLCHAIN_PATH | C:\gcc-arm\13.2 | 替换为你的 ARM GCC 安装路径 |
找到系统变量
Path,双击编辑,在末尾添加:%GNUARMEMB_TOOLCHAIN_PATH%\bin%ZEPHYR_BASE%\scripts
全部确认后,重新打开一个命令提示符,让变量生效。
3.2 Linux 用户配置步骤
把以下内容加到~/.bashrc或~/.zshrc(根据你用的 shell):
export ZEPHYR_BASE=~/zephyrproject/zephyr export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb export GNUARMEMB_TOOLCHAIN_PATH=/usr如果 ARM GCC 是手动安装到自定义目录(比如/opt/gcc-arm/13.2),则把GNUARMEMB_TOOLCHAIN_PATH设为该路径。
然后执行source ~/.bashrc或新开终端窗口。
3.3 验证变量是否生效
新开终端,依次运行:
echo $ZEPHYR_BASE echo $ZEPHYR_TOOLCHAIN_VARIANT arm-none-eabi-gcc --version如果都能正确输出,说明基础变量设对了。
4. 拉取 Zephyr 源码并编译示例
变量配好之后,实际跑一个编译流程,用 STM32F103C8T6 的板型配置测试。
4.1 获取源码和模块
# 创建项目目录 mkdir zephyrproject && cd zephyrproject # 克隆 zephyr 源码 git clone https://github.com/zephyrproject-rtos/zephyr cd zephyr # 拉取依赖模块(需要 Python 和 west 工具) pip install west west init .. west update这一步可能会花点时间,取决于网络。如果west update失败,通常是网络问题,重试或换镜像源。
4.2 编译 hello_world 示例
进入示例目录,指定板型为stm32f103c8t6(Zephyr 内置支持这个板型):
cd samples/hello_world west build -b stm32f103c8t6如果编译成功,会在build/zephyr目录下生成zephyr.elf、zephyr.bin等文件。
4.3 常见编译错误和解决
- 找不到编译器: 检查
GNUARMEMB_TOOLCHAIN_PATH是否指向正确路径,且bin子目录下有arm-none-eabi-gcc。 - CMake 报错找不到 Zephyr: 确认
ZEPHYR_BASE指向的是源码根目录,并且执行west update拉全了模块。 - 板型不支持: 确认板型名字拼写正确,比如
stm32f103c8t6全是小写。
5. 烧录到 STM32F103C8T6 并验证
编译通过后,用 ST-Link 烧录到板子上。
5.1 连接硬件
- ST-Link 的 SWDIO 接 STM32 的 PA13(SWDIO)
- ST-Link 的 SWCLK 接 STM32 的 PA14(SWCLK)
- GND 接 GND,3.3V 接 3.3V
接好后,给板子上电,ST-Link 指示灯应该亮起。
5.2 烧录命令
在 hello_world 示例目录下执行:
west flash如果一切正常,west 会自动检测 ST-Link 并烧录zephyr.hex或zephyr.bin文件。
5.3 验证输出
STM32F103C8T6 没有默认串口输出,但你可以接一个 USB 转 TTL 模块:
- PA9(TX)接 TTL 模块的 RX
- PA10(RX)接 TTL 模块的 TX
- GND 接 GND
用串口工具(如 PuTTY、minicom)打开对应串口,波特率设 115200,复位板子,应该能看到 "Hello World! stm32f103c8t6" 输出。
如果没输出,先检查接线,再看烧录时是否有错误提示。
6. 环境变量相关的深度排查
即使按照上面步骤走,有时还是会遇到环境变量导致的问题。这里把我自己排查时的顺序列出来。
6.1 变量未生效的排查顺序
- 确认终端会话是新开的:修改环境变量后,必须新开终端窗口,否则老会话读不到新变量。
- 检查变量值是否被覆盖:比如在
~/.bashrc里设了,但~/.profile或系统级配置里有冲突设置。 - 路径中是否有空格或特殊字符:尽量用纯英文路径,避免
Program Files这种带空格的目录。 - 变量名拼写错误:比如
ZEPHYR_BASE写成ZEPHYR_BASE_PATH。
6.2 编译阶段变量问题
如果编译报错提到工具链或 SDK,按这个顺序查:
- 运行
west build -t run:这个命令会打印详细的 CMake 变量和工具链检测结果,比普通编译输出更全。 - 检查
build/CMakeCache.txt:搜索CMAKE_C_COMPILER、ZEPHYR_TOOLCHAIN_VARIANT等关键词,看实际生效的值是什么。 - 手动指定工具链路径:如果自动检测失败,可以在
west build时加参数:west build -b stm32f103c8t6 -- -DCMAKE_C_COMPILER=/path/to/arm-none-eabi-gcc
6.3 生产环境下的变量管理
如果要在多项目或多机器上使用,建议用环境管理方式:
- Windows:用
setx命令永久设置变量,或写一个setup_env.bat脚本,每次开发前执行。 - Linux:把变量定义放在
~/.zephyrrc文件里,每次启动 shell 时自动 source。
示例~/.zephyrrc:
export ZEPHYR_BASE=~/zephyrproject/zephyr export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb export GNUARMEMB_TOOLCHAIN_PATH=/usr/local/gcc-arm-13.2 export PATH=$GNUARMEMB_TOOLCHAIN_PATH/bin:$PATH然后在~/.bashrc里加一行:
[ -f ~/.zephyrrc ] && source ~/.zephyrrc7. 从环境变量延伸到项目配置
环境变量配稳之后,Zephyr 项目的可移植性就靠配置文件了。这里简单提几个和变量相关的配置点。
7.1 板型配置中的工具链覆盖
每个板型目录下的board.cmake可以覆盖全局工具链设置。例如,如果某个板型必须用特定版本 GCC,可以在板型配置里写:
set(TOOLCHAIN_ROOT /path/to/specific/toolchain)但一般情况下,用全局环境变量就够了。
7.2 应用项目中的变量使用
在你的应用项目里,可以通过CMakeLists.txt读取环境变量:
if(DEFINED ENV{MY_CUSTOM_VAR}) set(MY_CUSTOM_VAR $ENV{MY_CUSTOM_VAR}) endif()这在需要区分开发、测试、生产环境时有用。
7.3 与 CI/CD 集成
在 GitHub Actions 或 GitLab CI 中,环境变量通过 YAML 配置:
env: ZEPHYR_BASE: ${{ github.workspace }}/zephyr ZEPHYR_TOOLCHAIN_VARIANT: gnuarmemb确保 CI 环境中的工具链路径和本地一致。
环境变量看起来简单,但却是 Zephyr 项目能跨平台编译的基础。实际项目中,我建议把变量配置写成文档或脚本,新成员加入时直接执行就能跑通环境,减少手动配置带来的不一致问题。
最稳妥的做法是:先用最小示例验证环境变量和编译流程,再开始正式项目开发。如果遇到问题,先回退到 hello_world 示例确认基础环境没问题,再排查项目特定配置。