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.sh

4.2 设置 Zephyr 环境变量

环境变量配置是 Zephyr 开发的关键步骤,确保系统能够找到工具链和配置文件。

Windows 环境变量配置:

  1. 打开系统环境变量设置(Win + R,输入sysdm.cpl→ 高级 → 环境变量)
  2. 在用户变量或系统变量中添加以下路径:
ZEPHYR_BASE=C:\zephyrproject\zephyr ZEPHYR_SDK_INSTALL_DIR=C:\zephyr-sdk PATH=%PATH%;C:\zephyr-sdk\bin;C:\zephyrproject\zephyr\scripts
  1. 验证环境变量设置:
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 ~/.bashrc

4.3 获取 Zephyr 源代码

# 创建工作目录 mkdir zephyrproject && cd zephyrproject # 使用 West 工具管理 Zephyr 项目 pip3 install west west init west update

4.4 安装 Python 依赖

# 进入 Zephyr 目录 cd zephyrproject/zephyr # 安装 Python 依赖包 pip3 install -r scripts/requirements.txt

5. STM32F103C8T6 硬件连接与配置

5.1 最小系统板引脚连接

STM32F103C8T6 最小系统板与 ST-Link 调试器的连接方式:

ST-Link 引脚STM32F103C8T6 引脚功能
VCC (3.3V)3.3V电源
GNDGND地线
SWDIOPA13调试数据线
SWCLKPA14调试时钟线
RESETNRST复位信号

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=y

6. 构建与烧录测试

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 watchpoints

6.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 工具未找到" fi

Windows 版本:

@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/.config

9. 高级配置与优化建议

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=2048

9.3 调试配置优化

启用调试功能但控制输出大小:

CONFIG_DEBUG=y CONFIG_LOG=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_LOG_BUFFER_SIZE=1024 CONFIG_LOG_DEFAULT_LEVEL=2

10. 实际项目应用示例

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 提供的丰富功能和组件库。