Zephyr RTOS在STM32F103C8T6上的完整开发指南 📅 2026/7/17 8:23:55 1. 先搞清楚 Zephyr 在 STM32F103C8T6 上能解决什么问题如果你手头有 STM32F103C8T6 这种几十块钱的最小系统板想找个现代、开源、社区活跃的 RTOS 来替代裸机编程或 FreeRTOSZephyr 是个值得一试的选择。它最大的优势不是功能多强大而是整个项目结构清晰、工具链统一、支持芯片广泛适合从学习到产品原型的平滑过渡。和常见的 RTOS 相比Zephyr 把很多底层差异比如时钟配置、外设驱动、电源管理都封装成了设备树DTS和 Kconfig 配置你不需要像在 HAL 库那样逐个寄存器去翻手册也不像某些 RTOS 需要手动移植。对于 STM32F103C8T6 这种经典芯片Zephyr 已经内置了完整的支持包括引脚定义、时钟树、常见外设驱动你只要会写配置就能快速把板子跑起来。但 Zephyr 的学习曲线比裸机或简单 RTOS 要陡峭一点主要是环境搭建和项目创建流程和传统 Keil/IAR 不一样。很多人第一次接触时容易卡在工具链安装、环境变量设置或项目编译这一步。下面我会用最典型的 STM32F103C8T6 最小系统板把从零开始创建 Zephyr 项目、编译、烧录、验证的完整流程拆解清楚。2. 环境准备别急着装工具先理清依赖关系Zephyr 官方推荐使用 Python 脚本来管理依赖但实际落地时最稳妥的方式是手动分步安装。下面是我在 Windows 10/11 和 Ubuntu 20.04 上反复验证过的顺序。2.1 基础工具链安装Zephyr 编译需要以下核心工具必须按顺序安装Python 3.8不要用系统自带的 Python2.x 或老版本建议直接装 Python 3.9 或 3.10。安装时务必勾选“Add Python to PATH”。Git版本不低于 2.20用于拉取 Zephyr 源码和模块。CMake版本要求 3.20.5这是 Zephyr 构建系统的核心。GNU Arm Embedded ToolchainZephyr 官方推荐用arm-none-eabi-gcc版本建议 10.3-2021.10。安装后需要把bin目录加入 PATH。验证基础工具是否就位# 打开终端或 CMD依次执行 python --version # 应显示 Python 3.x git --version # 应显示 git 版本 cmake --version # 应显示 cmake 版本 ≥3.20.5 arm-none-eabi-gcc --version # 应显示 GCC 版本信息如果任何一条命令报“找不到”说明 PATH 没设对或没安装成功。2.2 Zephyr SDK 和依赖包安装官方推荐用west工具管理项目但先不急着拉代码而是手动安装 Python 依赖# 安装 west 工具 pip install west # 安装其他依赖Windows 下可能需要以管理员身份运行 pip install -r https://raw.githubusercontent.com/zephyrproject-rtos/zephyr/main/scripts/requirements.txt这一步经常出问题的地方是权限和网络。如果 pip 安装超时或报错可以换国内源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple west2.3 获取 Zephyr 源码和模块Zephyr 的源码和硬件支持模块是分开的需要用west初始化# 创建一个工作目录比如 zephyrproject mkdir zephyrproject cd zephyrproject # 初始化并拉取源码这一步耗时较长依赖网络稳定性 west init -m https://github.com/zephyrproject-rtos/zephyr --mr main west updatewest update会下载所有模块包括 STM32 支持包如果中途失败可以多次执行直到完整拉取。2.4 设置环境变量Zephyr 需要两个关键环境变量ZEPHYR_BASE指向 zephyr 源码目录例如C:\zephyrproject\zephyr或/home/user/zephyrproject/zephyr。将$ZEPHYR_BASE\scripts加入 PATH以便使用zephyr脚本。在 Windows 下可以通过系统属性设置在 Linux/macOS 下可以写入~/.bashrc或~/.zshrcexport ZEPHYR_BASE/path/to/zephyrproject/zephyr export PATH$ZEPHYR_BASE/scripts:$PATH设置后重新打开终端执行zephyr看是否有帮助信息输出。3. 创建第一个项目从 Blinky 开始验证环境环境搭好后不要直接写复杂应用先用最简单的 BlinkyLED 闪烁测试整个工具链。3.1 创建项目目录结构Zephyr 推荐每个应用独立一个目录里面包含src、boards等子目录。但最简单的方式是直接复制官方示例# 进入 zephyrproject 目录 cd zephyrproject # 复制 blinky 示例到我的项目目录 cp -r zephyr/samples/basic/blinky my_blinky cd my_blinky3.2 配置板型和支持包STM32F103C8T6 最小系统板在 Zephyr 中对应的板型是stm32f103c8t6如果没有可能是stm32f1_disco或类似名称。先检查支持的板型列表# 查看所有支持的板型 west boards | grep stm32f103如果找不到可能需要确认west update是否完整拉取了模块。STM32F103C8T6 通常包含在stm32f1_disco或stm32f103c8t6板型中。3.3 修改项目配置Zephyr 使用 CMake 和 Kconfig 管理配置。在项目根目录创建board.conf文件指定板型# 创建配置文件 echo CONFIG_BOARD_STM32F103C8T6y board.conf如果板型名称不同需要根据west boards的输出调整。3.4 修改源码适配硬件STM32F103C8T6 最小系统板通常有一个 LED 接在 PC13或 PA1、PA5具体看板子设计。查看原理图确认 LED 引脚然后修改src/main.c#include zephyr/kernel.h #include zephyr/device.h #include zephyr/drivers/gpio.h /* 根据实际硬件修改 LED 引脚 */ #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led GPIO_DT_SPEC_GET(LED0_NODE, gpios); void main(void) { int ret; if (!device_is_ready(led.dev)) { return; } ret gpio_pin_configure_dt(led, GPIO_OUTPUT_ACTIVE); if (ret 0) { return; } while (1) { ret gpio_pin_toggle_dt(led); if (ret 0) { return; } k_msleep(1000); // 1秒闪烁 } }同时需要修改设备树配置。在项目目录创建dts/bindings/gpio/led.yaml如果不存在或直接修改*.overlay文件// 在项目目录创建 board.overlay / { aliases { led0bo led; }; leds { compatible gpio-leds; led: led_0 { gpios gpioc 13 GPIO_ACTIVE_HIGH; // 根据实际引脚修改 label User LED; }; }; };3.5 编译项目使用 west 工具编译# 指定板型和编译目录 west build -b stm32f103c8t6 -p always-b指定板型-p always表示每次都清理构建目录避免缓存问题编译成功会显示生成zephyr.elf、zephyr.bin等文件。如果编译失败常见问题有板型名称错误用west boards确认准确名称设备树配置错误检查引脚是否支持语法是否正确工具链路径问题确认arm-none-eabi-gcc在 PATH 中4. 烧录和调试选择适合最小系统板的方式STM32F103C8T6 最小系统板通常通过 SWD 接口烧录常用工具是 ST-Link。4.1 安装烧录工具Windows 环境安装 ST-Link 驱动从 ST 官网下载STSW-LINK009并安装或者使用开源工具 OpenOCDLinux 环境安装 OpenOCDsudo apt install openocd或者安装 STLink 工具sudo apt install stlink-tools4.2 连接硬件STM32F103C8T6 的 SWD 接口SWDIOPA13SWCLKPA14GND接地3.3V供电用 ST-Link 连接时注意电压匹配有些最小系统板需要外部供电。4.3 烧录固件使用 west 烧录# 使用 ST-Link 烧录 west flash --runner stlink # 或者使用 OpenOCD west flash --runner openocd如果烧录失败按这个顺序排查硬件连接检查 SWD 线是否接反、接触不良驱动安装在设备管理器中查看 ST-Link 是否识别电源问题最小系统板需要单独供电ST-Link 的 3.3V 可能供电不足复位电路有些板子需要手动复位才能进入烧录模式4.4 验证结果烧录成功后LED 应该开始闪烁。如果没有反应检查引脚配置用万用表测量 LED 引脚是否有电平变化检查时钟配置Zephyr 可能默认使用外部晶振但最小系统板可能只有内部晶振查看串口输出添加串口调试信息确认程序是否运行#include zephyr/kernel.h #include zephyr/device.h #include zephyr/drivers/gpio.h #include zephyr/sys/printk.h void main(void) { printk(Zephyr Blinky started\n); // ... 其余代码 }编译烧录后用串口工具115200波特率查看输出。5. 项目结构解析理解 Zephyr 的工程化管理Zephyr 项目不是简单的.c文件集合而是一套完整的构建系统。理解这个结构对后续开发很重要。5.1 标准项目目录结构my_blinky/ ├── CMakeLists.txt # 项目构建配置 ├── prj.conf # 可选的配置 ├── src/ │ └── main.c # 主程序 ├── dts/ │ └── board.overlay # 设备树覆盖配置 ├── boards/ │ └── stm32f103c8t6.overlay # 板级特定配置 └── build/ # 编译输出自动生成5.2 关键配置文件说明CMakeLists.txt最少需要以下内容# CMake 最低版本要求 cmake_minimum_required(VERSION 3.20.0) # 查找 Zephyr 包 find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(my_blinky) # 添加源码文件 target_sources(app PRIVATE src/main.c)Kconfig 配置可以通过prj.conf或board.conf设置# 启用 GPIO 驱动 CONFIG_GPIOy # 启用串口调试 CONFIG_SERIALy CONFIG_UART_CONSOLEy # 堆栈大小调整根据需求 CONFIG_MAIN_STACK_SIZE20485.3 设备树配置详解设备树是 Zephyr 管理硬件差异的核心。对于 STM32F103C8T6需要关注// 时钟配置内部或外部晶振 clk_hse { clock-frequency 8000000; // 8MHz 外部晶振 status okay; }; // 串口配置用于调试输出 usart1 { current-speed 115200; status okay; }; // GPIO 配置LED 和按键 gpioa { // PA0 作为按键输入 button0: button_0 { gpios gpioa 0 GPIO_ACTIVE_LOW; label User Button; }; };6. 常见问题排查从编译失败到运行异常Zephyr 环境搭建过程中常见的问题和解决方案。6.1 编译阶段问题问题1west 命令找不到原因PATH 未设置或 Zephyr 环境未激活解决确认ZEPHYR_BASE环境变量重新打开终端问题2编译报错 No board found原因板型名称错误或支持包未下载解决用west boards查看可用板型确认west update完整执行问题3设备树语法错误原因DTS 文件格式错误或引脚配置不支持解决检查设备树语法确认引脚在芯片中存在且未被占用6.2 烧录阶段问题问题4ST-Link 连接失败原因驱动问题、硬件连接问题、芯片保护解决检查设备管理器中的 ST-Link 状态尝试给芯片断电再上电使用 STM32 ST-Link Utility 解除读保护问题5烧录成功但程序不运行原因时钟配置错误、堆栈溢出、中断冲突解决检查芯片是否使用内部晶振但配置了外部晶振增加主堆栈大小CONFIG_MAIN_STACK_SIZE简化程序逐步添加功能排查6.3 运行阶段问题问题6LED 不闪烁但程序运行原因引脚配置错误、LED 极性反接解决用万用表测量引脚电平尝试反转 GPIO_ACTIVE_HIGH/LOW检查原理图确认 LED 连接方式问题7程序运行不稳定原因时钟配置错误、电源不稳定、堆栈不足解决确认时钟配置与实际硬件匹配检查电源电压和滤波电容增加堆栈大小添加看门狗7. 进阶配置从演示项目到实际应用Blinky 跑通后可以逐步添加实际应用需要的功能。7.1 添加外设驱动以 I2C 读取传感器为例#include zephyr/device.h #include zephyr/drivers/i2c.h static const struct device *i2c_dev DEVICE_DT_GET(DT_NODELABEL(i2c1)); void read_sensor(void) { if (!device_is_ready(i2c_dev)) { printk(I2C device not ready\n); return; } uint8_t buffer[2]; int ret i2c_burst_read(i2c_dev, 0x40, 0x00, buffer, sizeof(buffer)); if (ret 0) { printk(Sensor data: %02X %02X\n, buffer[0], buffer[1]); } }需要在设备树中启用 I2Ci2c1 { status okay; clock-frequency 100000; // 100kHz };7.2 配置电源管理对于电池应用可以启用低功耗模式#include zephyr/pm/pm.h #include zephyr/pm/policy.h // 在空闲时进入低功耗模式 void configure_power_management(void) { // 设置系统空闲时进入睡眠模式 pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); }在配置中启用电源管理CONFIG_PMy CONFIG_PM_DEVICEy CONFIG_PM_POLICY_CUSTOMy7.3 添加调试和日志功能Zephyr 提供了完整的日志系统#include zephyr/logging/log.h LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); void main(void) { LOG_INF(Application started); LOG_DBG(Debug information: %d, some_value); LOG_ERR(Error occurred: %d, error_code); }配置日志输出CONFIG_LOGy CONFIG_LOG_MODE_IMMEDIATEy # 立即模式适合调试 CONFIG_LOG_DEFAULT_LEVEL4 # 调试级别8. 生产就绪考量从原型到产品的关键步骤当演示项目稳定运行后需要考虑产品化的问题。8.1 内存和性能优化STM32F103C8T6 只有 20KB RAM 和 64KB Flash需要精细配置# 优化配置 CONFIG_HEAP_MEM_POOL_SIZE1024 # 减少堆大小 CONFIG_MAIN_STACK_SIZE1024 # 优化栈大小 CONFIG_LOG_BUFFER_SIZE512 # 减小日志缓冲区 CONFIG_NO_OPTIMIZATIONSn # 启用优化 CONFIG_SIZE_OPTIMIZATIONSy # 尺寸优化8.2 固件升级方案Zephyr 支持 MCUboot 进行安全固件升级# 启用 MCUboot CONFIG_BOOTLOADER_MCUBOOTy CONFIG_IMG_MANAGERy CONFIG_MCUBOOT_IMG_MANAGERy需要根据具体需求配置升级策略和存储介质。8.3 测试和验证建立自动化测试流程# 单元测试 west twister -p stm32f103c8t6 -T tests/ # 静态分析 west build -t check对于资源受限的 STM32F103C8T6重点测试内存使用、执行时间和外设稳定性。通过这个完整的流程你应该能够在 STM32F103C8T6 最小系统板上顺利运行 Zephyr并理解如何从简单的演示项目过渡到实际应用。Zephyr 的学习曲线虽然较陡但一旦掌握其工程化方法开发效率会显著高于传统的裸机或简单 RTOS 编程。