Zephyr RTOS环境配置:STM32F103C8T6嵌入式开发实战指南
这次我们来看一个嵌入式开发中非常实用的技术组合:Zephyr RTOS 在 STM32F103C8T6 最小系统板上的环境配置与开发实践。对于想要从传统单片机开发转向现代实时操作系统的开发者来说,Zephyr 提供了一个功能完整且高度可配置的解决方案,而 STM32F103C8T6 这款经典的 Cortex-M3 芯片则是绝佳的入门硬件平台。
Zephyr 项目的核心优势在于其模块化设计和丰富的驱动支持,能够显著提升嵌入式项目的开发效率和代码可维护性。不过,很多开发者在初次接触时会遇到环境配置的挑战,特别是环境变量设置、工具链配置和项目构建流程。本文将重点解决这些问题,通过完整的案例演示如何在 STM32F103C8T6 最小系统板上搭建 Zephyr 开发环境并运行第一个应用程序。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 目标硬件 | STM32F103C8T6 最小系统板(Cortex-M3, 64KB Flash, 20KB RAM) |
| 操作系统支持 | Zephyr RTOS 3.x 版本 |
| 开发环境 | Zephyr SDK、CMake、Ninja、设备树配置 |
| 主要功能 | 多线程管理、设备驱动、电源管理、网络协议栈 |
| 启动方式 | 命令行构建和烧录,支持 OpenOCD 和 ST-Link |
| 适合场景 | IoT 设备原型开发、实时控制系统、嵌入式学习项目 |
2. Zephyr 环境配置的价值与适用场景
Zephyr 作为 Linux 基金会托管的开源实时操作系统,在嵌入式领域逐渐成为传统 RTOS 的有力替代方案。与 FreeRTOS 或 μC/OS 相比,Zephyr 提供了更现代化的构建系统、统一的设备驱动模型和强大的配置系统。
对于 STM32F103C8T6 这样的资源受限设备,Zephyr 能够帮助开发者快速构建具有多任务管理、外设驱动和电源管理功能的复杂应用。特别适合需要网络连接(如蓝牙、Wi-Fi)、文件系统或复杂调度逻辑的项目。
环境变量配置是 Zephyr 开发的第一步,也是最重要的一步。正确的环境配置能够确保工具链正确识别、构建系统正常工作,以及调试工具可用。本文将重点解决 Windows 和 Linux 双平台下的环境配置问题。
3. 环境准备与前置条件
在开始 Zephyr 环境配置前,需要准备以下软硬件环境:
硬件准备:
- STM32F103C8T6 最小系统板(核心板)
- ST-Link V2 调试器(或兼容的调试探头)
- 微型 USB 数据线(用于供电和调试)
- 杜邦线若干(连接调试器与目标板)
软件环境要求:
- 操作系统:Windows 10/11 或 Ubuntu 20.04/LTS 以上
- Python 3.8 或更高版本(Zephyr 依赖 Python 环境)
- Git 版本控制工具
- 合适的代码编辑器(VS Code 推荐)
磁盘空间要求:
- Zephyr SDK 和源代码需要约 2-3GB 磁盘空间
- 构建缓存和输出文件需要额外 1-2GB 空间
4. Zephyr 开发环境安装部署
4.1 安装 Zephyr SDK
Zephyr SDK 是开发环境的核心,包含了交叉编译工具链、构建工具和调试工具。
Windows 平台安装:
# 使用 Chocolatey 包管理器安装依赖 choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' choco install ninja git python # 下载 Zephyr SDK # 访问 https://github.com/zephyrproject-rtos/sdk-ng/releases # 下载最新版本的 Windows 安装包,如 zephyr-sdk-0.16.0_windows-x86_64.exe # 运行安装程序,建议安装到 C:\zephyr-sdk 目录 # 安装过程中选择"Add to PATH"选项Linux 平台安装(Ubuntu/Debian):
# 更新系统包管理器 sudo apt update && sudo apt upgrade # 安装依赖包 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 # 下载并安装 Zephyr SDK wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.0/zephyr-sdk-0.16.0_linux-x86_64.tar.xz tar xvf zephyr-sdk-0.16.0_linux-x86_64.tar.xz cd zephyr-sdk-0.16.0 ./setup.sh4.2 设置 Zephyr 环境变量
环境变量配置是 Zephyr 开发的关键步骤,确保系统能够找到工具链和配置文件。
Windows 环境变量配置:
- 打开系统环境变量设置(Win + R,输入
sysdm.cpl→ 高级 → 环境变量) - 在用户变量或系统变量中添加以下路径:
ZEPHYR_BASE=C:\zephyrproject\zephyr ZEPHYR_SDK_INSTALL_DIR=C:\zephyr-sdk PATH=%PATH%;C:\zephyr-sdk\bin;C:\zephyrproject\zephyr\scripts- 验证环境变量设置:
echo %ZEPHYR_BASE% echo %ZEPHYR_SDK_INSTALL_DIR%Linux 环境变量配置:
将以下内容添加到~/.bashrc或~/.zshrc文件:
export ZEPHYR_BASE=~/zephyrproject/zephyr export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-0.16.0 export PATH=$ZEPHYR_SDK_INSTALL_DIR/bin:$PATH export PATH=$ZEPHYR_BASE/scripts:$PATH使配置生效:
source ~/.bashrc4.3 获取 Zephyr 源代码
# 创建工作目录 mkdir zephyrproject && cd zephyrproject # 使用 West 工具管理 Zephyr 项目 pip3 install west west init west update4.4 安装 Python 依赖
# 进入 Zephyr 目录 cd zephyrproject/zephyr # 安装 Python 依赖包 pip3 install -r scripts/requirements.txt5. STM32F103C8T6 硬件连接与配置
5.1 最小系统板引脚连接
STM32F103C8T6 最小系统板与 ST-Link 调试器的连接方式:
| ST-Link 引脚 | STM32F103C8T6 引脚 | 功能 |
|---|---|---|
| VCC (3.3V) | 3.3V | 电源 |
| GND | GND | 地线 |
| SWDIO | PA13 | 调试数据线 |
| SWCLK | PA14 | 调试时钟线 |
| RESET | NRST | 复位信号 |
5.2 设备树配置验证
Zephyr 使用设备树来描述硬件配置。对于 STM32F103C8T6,需要确认设备树配置正确:
创建项目目录结构:
mkdir -p zephyrproject/applications/stm32f103_demo cd zephyrproject/applications/stm32f103_demo创建src/main.c基础应用代码:
#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/gpio.h> void main(void) { printk("Zephyr RTOS running on STM32F103C8T6!\n"); while (1) { printk("Hello from Zephyr!\n"); k_msleep(1000); } }创建CMakeLists.txt:
cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(stm32f103_demo) target_sources(app PRIVATE src/main.c)创建prj.conf配置文件:
CONFIG_PRINTK=y CONFIG_STDOUT_CONSOLE=y CONFIG_GPIO=y6. 构建与烧录测试
6.1 项目构建
在项目目录下执行构建命令:
# 设置板型为 stm32f103c8t6 west build -b stm32f103c8t6 # 或者明确指定构建目录 west build -b stm32f103c8t6 -d build/stm32f103_demo构建成功后会显示:
[1/1] Linking C executable zephyr/zephyr.elf Memory region Used Size Region Size %age Used FLASH: 12345 B 64 KB 18.83% SRAM: 5678 B 20 KB 27.71%6.2 烧录到目标板
使用 west 命令烧录程序:
# 连接 ST-Link 后执行烧录 west flash # 如果自动检测失败,可以指定 runner west flash --runner stlink烧录过程中会显示进度信息:
*** Flashing stm32f103c8t6 with ST-Link v2 *** Open On-Chip Debugger 0.11.0 Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : clock speed 1000 kHz Info : STLINK V2J39S7 (API v2) VID:PID 0483:3748 Info : Target voltage: 3.240 V Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints6.3 串口调试输出
烧录完成后,通过串口查看程序输出:
# 查看可用串口设备 ls /dev/ttyUSB* # Linux # 或者 mode com* # Windows # 使用串口工具连接(波特率 115200) picocom -b 115200 /dev/ttyUSB0 # Linux # 或者使用 Putty、Tera Term 等工具正常输出应该显示:
*** Booting Zephyr OS build zephyr-v3.2.0 *** Zephyr RTOS running on STM32F103C8T6! Hello from Zephyr! Hello from Zephyr! ...7. 环境变量配置深度解析
7.1 关键环境变量作用
ZEPHYR_BASE:
- 指向 Zephyr RTOS 源代码根目录
- 构建系统通过此变量定位内核源码和设备树文件
- 必须设置为绝对路径
ZEPHYR_SDK_INSTALL_DIR:
- 指向 Zephyr SDK 安装目录
- 包含工具链、OpenOCD、设备支持包
- 影响交叉编译和目标支持能力
PATH 环境变量扩展:
- 添加 SDK 的 bin 目录确保工具链可用
- 添加 Zephyr 脚本目录支持 west 命令扩展
- 需要确保路径顺序正确
7.2 平台特定配置差异
Windows 平台注意事项:
- 路径分隔符使用反斜杠(\)
- 环境变量名称不区分大小写
- 可能需要管理员权限修改系统环境变量
- 建议使用 PowerShell 或 Windows Terminal
Linux 平台注意事项:
- 路径分隔符使用正斜杠(/)
- 环境变量名称区分大小写
- 修改 ~/.bashrc 或 /etc/environment
- 可能需要使用 sudo 权限安装系统依赖
7.3 环境变量验证脚本
创建验证脚本check_env.sh(Linux)或check_env.bat(Windows):
Linux 版本:
#!/bin/bash echo "=== Zephyr 环境变量检查 ===" echo "1. 检查 ZEPHYR_BASE:" if [ -z "$ZEPHYR_BASE" ]; then echo "❌ ZEPHYR_BASE 未设置" else echo "✅ ZEPHYR_BASE=$ZEPHYR_BASE" if [ -d "$ZEPHYR_BASE" ]; then echo "✅ 目录存在" else echo "❌ 目录不存在" fi fi echo "2. 检查 ZEPHYR_SDK_INSTALL_DIR:" if [ -z "$ZEPHYR_SDK_INSTALL_DIR" ]; then echo "❌ ZEPHYR_SDK_INSTALL_DIR 未设置" else echo "✅ ZEPHYR_SDK_INSTALL_DIR=$ZEPHYR_SDK_INSTALL_DIR" if [ -d "$ZEPHYR_SDK_INSTALL_DIR" ]; then echo "✅ 目录存在" else echo "❌ 目录不存在" fi fi echo "3. 检查工具链:" which arm-zephyr-eabi-gcc > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "✅ 交叉编译工具链可用" else echo "❌ 交叉编译工具链未找到" fi echo "4. 检查 west 工具:" which west > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "✅ west 工具可用" west --version else echo "❌ west 工具未找到" fiWindows 版本:
@echo off echo === Zephyr 环境变量检查 === echo 1. 检查 ZEPHYR_BASE: if "%ZEPHYR_BASE%"=="" ( echo ❌ ZEPHYR_BASE 未设置 ) else ( echo ✅ ZEPHYR_BASE=%ZEPHYR_BASE% if exist "%ZEPHYR_BASE%" ( echo ✅ 目录存在 ) else ( echo ❌ 目录不存在 ) ) echo 2. 检查 ZEPHYR_SDK_INSTALL_DIR: if "%ZEPHYR_SDK_INSTALL_DIR%"=="" ( echo ❌ ZEPHYR_SDK_INSTALL_DIR 未设置 ) else ( echo ✅ ZEPHYR_SDK_INSTALL_DIR=%ZEPHYR_SDK_INSTALL_DIR% if exist "%ZEPHYR_SDK_INSTALL_DIR%" ( echo ✅ 目录存在 ) else ( echo ❌ 目录不存在 ) ) echo 3. 检查工具链: where arm-zephyr-eabi-gcc >nul 2>&1 if %errorlevel% equ 0 ( echo ✅ 交叉编译工具链可用 ) else ( echo ❌ 交叉编译工具链未找到 ) echo 4. 检查 west 工具: where west >nul 2>&1 if %errorlevel% equ 0 ( echo ✅ west 工具可用 west --version ) else ( echo ❌ west 工具未找到 )8. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| west build 失败,提示板型不支持 | 板型名称错误或未支持 | west boards | 确认板型名称,检查 boards 目录 |
| 烧录时提示 OpenOCD 连接失败 | ST-Link 驱动问题或连接错误 | lsusb (Linux) 或设备管理器 (Windows) | 重新安装 ST-Link 驱动,检查硬件连接 |
| 环境变量设置后不生效 | 未重新加载 shell 或路径错误 | echo $ZEPHYR_BASE | 重新启动终端或执行 source ~/.bashrc |
| 构建时提示 Python 模块缺失 | requirements.txt 未安装 | pip3 list | 重新安装 requirements.txt 中的依赖 |
| 串口无输出 | 波特率设置错误或引脚配置问题 | 检查设备树串口配置 | 确认波特率为 115200,检查 TX/RX 引脚 |
8.1 驱动安装问题排查
ST-Link 驱动安装:
在 Windows 设备管理器中查看 ST-Link 状态:
- 正确识别:显示为 "STMicroelectronics STLink dongle"
- 驱动问题:显示为未知设备或有黄色感叹号
解决方案:
# 下载 ST-Link 官方驱动 # 或使用 Zadig 工具重新安装驱动USB 权限问题(Linux):
# 将用户添加到 dialout 组 sudo usermod -a -G dialout $USER # 重新登录或重启生效8.2 构建系统问题排查
构建失败时查看详细日志:
# 详细构建输出 west build -v # 清理构建目录重新构建 west build -t clean west build # 查看 CMake 缓存 cat build/zephyr/.config9. 高级配置与优化建议
9.1 自定义板型配置
对于 STM32F103C8T6 最小系统板,可以创建自定义板型定义:
创建boards/arm/stm32f103c8t6_custom目录结构:
stm32f103c8t6_custom/ ├── board.cmake ├── Kconfig.board ├── Kconfig.defconfig └── stm32f103c8t6_custom.dts设备树配置示例:
/dps/ { model = "STM32F103C8T6 Custom Board"; compatible = "st,stm32f103c8t6-custom"; chosen { zephyr,console = &usart1; zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; }; };9.2 内存优化配置
针对 STM32F103C8T6 的 20KB RAM 限制,优化内存使用:
# prj.conf 内存优化配置 CONFIG_HEAP_MEM_POOL_SIZE=1024 CONFIG_MAIN_STACK_SIZE=2048 CONFIG_IDLE_STACK_SIZE=512 CONFIG_ISR_STACK_SIZE=2048 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=20489.3 调试配置优化
启用调试功能但控制输出大小:
CONFIG_DEBUG=y CONFIG_LOG=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_LOG_BUFFER_SIZE=1024 CONFIG_LOG_DEFAULT_LEVEL=210. 实际项目应用示例
10.1 GPIO 控制示例
扩展基础应用,添加 LED 控制功能:
#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/gpio.h> #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); void main(void) { printk("Zephyr GPIO Control Demo\n"); if (!device_is_ready(led.port)) { printk("LED device not ready\n"); return; } int ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); if (ret < 0) { printk("Error configuring LED pin: %d\n", ret); return; } while (1) { gpio_pin_toggle_dt(&led); printk("LED toggled\n"); k_msleep(500); } }对应的设备树配置:
/ { aliases { led0 = &led1; }; leds { compatible = "gpio-leds"; led1: led_0 { gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; label = "User LED"; }; }; };10.2 多线程应用示例
创建简单的多线程应用演示 Zephyr 的调度能力:
#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/gpio.h> #define STACK_SIZE 1024 #define THREAD1_PRIORITY 5 #define THREAD2_PRIORITY 5 K_THREAD_STACK_DEFINE(thread1_stack, STACK_SIZE); K_THREAD_STACK_DEFINE(thread2_stack, STACK_SIZE); struct k_thread thread1; struct k_thread thread2; void thread1_function(void *arg1, void *arg2, void *arg3) { while (1) { printk("Thread 1 running\n"); k_msleep(1000); } } void thread2_function(void *arg1, void *arg2, void *arg3) { while (1) { printk("Thread 2 running\n"); k_msleep(1500); } } void main(void) { printk("Zephyr Multi-threading Demo\n"); k_thread_create(&thread1, thread1_stack, K_THREAD_STACK_SIZEOF(thread1_stack), thread1_function, NULL, NULL, NULL, THREAD1_PRIORITY, 0, K_NO_WAIT); k_thread_create(&thread2, thread2_stack, K_THREAD_STACK_SIZEOF(thread2_stack), thread2_function, NULL, NULL, NULL, THREAD2_PRIORITY, 0, K_NO_WAIT); while (1) { printk("Main thread running\n"); k_msleep(2000); } }通过这个完整的 Zephyr 环境配置教程,开发者可以快速在 STM32F103C8T6 最小系统板上搭建起现代化的嵌入式开发环境。环境变量配置作为基础但关键的步骤,直接影响后续开发的顺利进行。建议在实际项目中根据具体需求调整配置参数,并充分利用 Zephyr 提供的丰富功能和组件库。
