十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于VSCode与Zephyr RTOS的STM32F103C8T6开发环境搭建与实战

基于VSCode与Zephyr RTOS的STM32F103C8T6开发环境搭建与实战 在嵌入式开发领域Zephyr RTOS 以其模块化、高度可配置和跨平台特性正成为越来越多开发者的选择。然而对于习惯了传统 IDE如 Keil、IAR的 STM32 开发者尤其是使用 STM32F103C8T6 这类经典“蓝桥杯”最小系统板的用户来说如何将 Zephyr 与现代化的编辑器 VSCode 结合搭建一个流畅的开发、编译、烧录环境是一个充满挑战但又极具价值的过程。本文将以 STM32F103C8T6 最小系统板为目标硬件详细讲解如何在 VSCode 中配置 Zephyr 开发环境运行一个简单的示例项目并最终通过 ST-Link 将程序烧录到板卡中。整个过程不仅涉及工具链的安装更关键的是理解 Zephyr 的构建系统、设备树配置以及调试器连接等核心概念让你能脱离对特定商业 IDE 的依赖拥抱更开放、更高效的嵌入式开发工作流。1. 理解 Zephyr RTOS 与 VSCode 开发模式的优势在开始动手之前需要先厘清我们为什么要选择 Zephyr VSCode 这套组合以及它和传统开发方式的核心差异。1.1 Zephyr RTOS 的核心特点Zephyr 是一个面向资源受限设备的小型、可扩展实时操作系统RTOS由 Linux 基金会托管。它的设计哲学是高度模块化和可配置。与 FreeRTOS 等相比Zephyr 通过 Kconfig 和设备树Device Tree提供了极强的硬件抽象和配置能力。这意味着针对 STM32F103C8T6 的开发你无需直接面对繁琐的寄存器地址和底层驱动而是通过修改配置文件来声明和使用板载资源如 UART、GPIO、I2C。这种“描述硬件”而非“硬编码硬件”的方式极大地提升了代码在不同硬件平台间的可移植性。1.2 VSCode 作为嵌入式开发 IDE 的价值Visual Studio Code 本身是一个轻量级代码编辑器但其强大的扩展生态系统使其能够胜任复杂的嵌入式开发任务。对于 Zephyr 项目VSCode 的优势在于智能感知与导航通过 C/C 扩展可以获得媲美专业 IDE 的代码补全、跳转定义、查找引用等功能这对于浏览 Zephyr 庞大的源码库至关重要。集成终端与任务系统Zephyr 主要使用命令行工具west, cmake, ninja进行构建。VSCode 的集成终端可以无缝运行这些命令而其任务系统Tasks可以将编译、烧录等命令固化实现一键操作。强大的调试支持通过 Cortex-Debug 等扩展可以图形化地配置和启动 GDB 调试会话实现设置断点、查看变量、单步执行等操作调试体验直观。版本控制集成内置的 Git 支持方便管理你的应用代码和项目配置。这套组合的核心工作流是在 VSCode 中编辑代码和配置文件通过集成终端调用 Zephyr 的west构建系统进行编译最后使用west flash命令或配置好的调试器进行程序烧录和调试。2. 开发环境搭建从零准备工具链这是最繁琐但决定成败的一步。我们将基于 Ubuntu 22.04 LTS或 Windows WSL2进行环境搭建因为这是 Zephyr 官方推荐且问题最少的方式。Windows 原生环境也可行但路径和依赖问题更多。2.1 安装系统依赖与 Python 环境Zephyr 的构建工具west基于 Python因此首先需要确保 Python 3.8 和 pip 可用。# 更新系统包列表并安装基础依赖 sudo apt update sudo apt install -y 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 g libssl-dev libncurses-dev2.2 获取 Zephyr 源码并安装 westwest是 Zephyr 的多仓库管理工具用于拉取源码、构建和烧录。# 安装 west pip3 install --user -U west echo export PATH~/.local/bin:$PATH ~/.bashrc source ~/.bashrc # 验证 west 安装 west --version # 创建工作目录并初始化 Zephyr 源码 mkdir -p ~/zephyrproject cd ~/zephyrproject west init west updatewest init会克隆zephyr主仓库west update会拉取所有必要的模块如 hal_stm32, cmsis 等。这是一个较耗时的过程。2.3 安装 Zephyr SDK 和工具链Zephyr SDK 包含了针对多种架构如 ARM的交叉编译工具链gcc、调试器gdb以及用于构建的主机工具。cd ~/zephyrproject # 运行 Zephyr 提供的环境安装脚本 # 此脚本会提示你下载并安装 SDK请选择默认或推荐的安装路径如 /opt/zephyr-sdk-0.16.0 west zephyr-export # 安装 Zephyr SDK (以 0.16.0 版本为例请检查官网获取最新版本链接) wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.0/zephyr-sdk-0.16.0_linux-x86_64.tar.xz wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.0/sha256.sum | shasum --check --ignore-missing tar xvf zephyr-sdk-0.16.0_linux-x86_64.tar.xz -C ~/ cd ~/zephyr-sdk-0.16.0 ./setup.sh -t arm-zephyr-eabi -h -c安装过程中脚本会询问是否添加用户到udev规则以便普通用户能访问调试器如 ST-Link务必选择 yes。2.4 配置 VSCode 及必要扩展在 Ubuntu 上安装 VSCode 后需要安装以下核心扩展C/C (ms-vscode.cpptools)提供代码智能感知、调试支持。CMake Tools (ms-vscode.cmake-tools)增强对 CMake 项目的支持方便配置和构建。Cortex-Debug (marus25.cortex-debug)针对 ARM Cortex-M 系列芯片的专用调试扩展。Zephyr IDE (zephyr-rtos.zephyr-ide)官方扩展提供 Kconfig、设备树语法高亮和片段。安装完成后在 VSCode 中打开我们之前创建的~/zephyrproject文件夹。3. 创建并构建第一个 Zephyr 示例项目环境就绪后我们创建一个最简单的blinkyLED 闪烁示例并针对 STM32F103C8T6 进行构建。3.1 创建应用程序目录Zephyr 的应用代码需要放在zephyrproject目录之外这是为了将你的应用与 Zephyr 源码分离。# 回到用户主目录创建你的应用工作区 cd ~ mkdir -p my_zephyr_apps/blinky_f103 cd my_zephyr_apps/blinky_f1033.2 编写应用源码与配置文件一个最小的 Zephyr 应用需要三个文件src/main.c,CMakeLists.txt,prj.conf。首先创建src/main.c#include zephyr/kernel.h #include zephyr/drivers/gpio.h /* 定义 LED 设备树节点标签。 * 对于 STM32F103C8T6 最小系统板通常板载 LED 连接在 PC13。 * 具体标签需要根据板级定义确认这里使用一个通用标签示例。 * 实际中我们会在后续的设备树覆盖文件中精确定义。 */ #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; // 检查 LED 设备是否就绪 if (!device_is_ready(led.port)) { return; } // 配置 LED 引脚为输出并初始化为低电平点亮 ret gpio_pin_configure_dt(led, GPIO_OUTPUT_ACTIVE); if (ret 0) { return; } while (1) { // 翻转 LED 状态 gpio_pin_toggle_dt(led); // 延时 1000 毫秒 k_msleep(1000); } }接着在应用根目录blinky_f103创建CMakeLists.txt# 设置 Zephyr 所需的最低 CMake 版本 cmake_minimum_required(VERSION 3.20.0) # 查找 Zephyr 包。ZEPHYR_BASE 环境变量或在构建时通过 -DZEPHYR_BASE... 指定 find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) # 将你的应用命名为 app并指定源码目录 project(blinky_f103) # 添加应用的源码文件 target_sources(app PRIVATE src/main.c)最后创建配置文件prj.conf。这个文件用于通过 Kconfig 系统启用或禁用 Zephyr 的内核和驱动特性。# 启用 GPIO 驱动 CONFIG_GPIOy # 启用系统时钟和 tick用于 k_msleep CONFIG_SYS_CLOCK_TICKS_PER_SEC10003.3 为 STM32F103C8T6 准备板级支持STM32F103C8T6 核心板通常不是 Zephyr 官方直接支持的开发板。我们需要使用一个最接近的官方板定义作为基础并通过“板级覆盖”和“设备树覆盖”来适配我们的硬件。Zephyr 中已有stm32f103c8t6的 SoC 级支持。我们可以选择nucleo_f103rb基于 STM32F103RBT6作为基础板因为其芯片系列相同主要区别在于引脚数量和封装。我们通过覆盖文件来调整引脚映射。创建板级目录结构cd ~/my_zephyr_apps/blinky_f103 mkdir -p boards/arm/my_f103_board cd boards/arm/my_f103_board创建板级定义文件my_f103_board.yamlidentifier: my_f103_board name: My STM32F103C8T6 Board type: mcu arch: arm toolchain: - zephyr ram: 20 flash: 64 supported: - arduino_gpio - arduino_i2c - arduino_spi这里定义了板卡标识符、名称、架构、RAM/Flash 大小STM32F103C8T6 是 20KB RAM64KB Flash和支持的接口。创建设备树源文件my_f103_board.dts/dts-v1/; #include st/f1/stm32f103Xb.dtsi #include st/f1/stm32f103c(8-b)tx-pinctrl.dtsi #include dt-bindings/clock/stm32_clock.h #include dt-bindings/gpio/gpio.h #include dt-bindings/pinctrl/stm32-pinctrl.h / { model My STM32F103C8T6 Board; compatible st,my-f103-board; chosen { zephyr,console usart1; zephyr,shell-uart usart1; zephyr,sram sram0; zephyr,flash flash0; }; leds { compatible gpio-leds; led0: led_0 { gpios gpioc 13 GPIO_ACTIVE_LOW; label User LED; }; }; aliases { led0 led0; }; }; usart1 { pinctrl-0 usart1_tx_pa9 usart1_rx_pa10; pinctrl-names default; current-speed 115200; status okay; }; clk_hse { clock-frequency 8000000; /* 外部 8MHz 晶振 */ status okay; }; pll { mul 9; clocks clk_hse; status okay; }; rcc { clocks pll; clock-frequency DT_FREQ_M(72); /* PLL 输出 72MHz */ ahb-prescaler 1; apb1-prescaler 2; apb2-prescaler 1; };这个文件是关键它描述了硬件定义了用户 LED 在PC13并创建了别名led0这与main.c中的DT_ALIAS(led0)对应。配置了 USART1 在PA9(TX) 和PA10(RX)用于控制台输出。配置了时钟树使用外部 8MHz 晶振通过 PLL 倍频到 72MHz 系统时钟。创建 Kconfig 板级配置Kconfig.board和Kconfig.defconfigKconfig.board内容config BOARD_MY_F103_BOARD bool My STM32F103C8T6 Board depends on SOC_STM32F103XBKconfig.defconfig内容if BOARD_MY_F103_BOARD config BOARD default my_f103_board endif # BOARD_MY_F103_BOARD创建 CMake 板级文件CMakeLists.txt# SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.20.0) define_property(GLOBAL PROPERTY ZEPHYR_LIBS) define_property(GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS)3.4 使用 west 构建项目现在回到应用目录使用west命令进行构建并指定我们的自定义板卡。cd ~/my_zephyr_apps/blinky_f103 # 构建指定板卡为自定义的 my_f103_board构建目录为 build west build -b my_f103_board .如果一切顺利你将在build目录下得到zephyr/zephyr.elf,zephyr/zephyr.bin,zephyr/zephyr.hex等输出文件。关键解释-b my_f103_board告诉 west 使用我们自定义的板卡配置。.表示在当前目录即应用目录查找CMakeLists.txt和prj.conf。构建过程会依次执行CMake 配置、Kconfig 菜单生成如果需要、设备树处理、最终编译链接。4. 硬件连接与程序烧录编译成功后需要将生成的二进制文件烧录到 STM32F103C8T6 芯片中。最常用的工具是 ST-Link 调试器。4.1 硬件连接将 ST-Link V2或兼容调试器与 STM32F103C8T6 最小系统板连接ST-Link 引脚STM32F103C8T6 引脚功能SWDIOPA13 (JTMS)数据输入输出SWCLKPA14 (JTCK)时钟GNDGND地3.3V3.3V电源可选如果板子已独立供电注意务必先连接 GND再连接信号线。确保最小系统板的 Boot0 引脚已通过跳线帽或电阻接地Boot00使其从主闪存启动。4.2 使用 west flash 命令烧录Zephyr 的west工具集成了烧录功能。只要调试器连接正确且系统udev规则已配置一条命令即可完成烧录。# 在应用目录下执行 west flashwest flash命令会自动检测连接的调试器和目标芯片。根据板卡定义my_f103_board选择合适的烧录工具通常是openocd或pyocd。将build/zephyr/zephyr.bin或zephyr.hex文件烧录到芯片的 Flash 中。完成后自动复位芯片运行。4.3 在 VSCode 中配置一键烧录任务为了更便捷可以在 VSCode 中配置一个任务实现快捷键烧录。在项目根目录blinky_f103创建.vscode/tasks.json{ version: 2.0.0, tasks: [ { label: West Build, type: shell, command: west, args: [build, -b, my_f103_board, .], group: { kind: build, isDefault: true }, problemMatcher: [$gcc], detail: 使用 west 构建 Zephyr 应用 }, { label: West Flash, type: shell, command: west, args: [flash], group: build, problemMatcher: [], detail: 使用 west 烧录程序到开发板 } ] }配置后你可以通过 VSCode 的 Terminal - Run Task... 菜单选择West Flash来执行烧录。也可以绑定快捷键。4.4 验证结果烧录完成后观察 STM32F103C8T6 最小系统板上的用户 LED通常连接在 PC13。它应该以 1 秒的间隔闪烁。如果没有闪烁请进入下一章的排查步骤。5. 常见问题与深度排查指南初次搭建环境并运行项目很可能会遇到各种问题。以下是按优先级排序的排查路径。5.1 构建阶段问题问题现象可能原因检查方式与解决方案west build失败提示board … not found1. 板卡名称拼写错误。2. 自定义板卡目录未放在正确位置或结构错误。3. 未导出ZEPHYR_BASE环境变量。1. 使用west boards命令列出所有可用板卡确认名称。2. 检查boards/arm/my_f103_board/目录结构及文件是否完整与章节 3.3 对照。3. 确保在构建前执行了source ~/zephyrproject/zephyr/zephyr-env.sh。CMake 配置错误提示找不到工具链Zephyr SDK 未正确安装或路径未设置。1. 检查~/.zephyrrc或zephyr-sdk-0.16.0目录下的environment-setup文件是否被 source。2. 运行which arm-zephyr-eabi-gcc确认工具链可用。3. 重新运行 SDK 的setup.sh脚本。编译错误提示DT_ALIAS(led0) not found设备树中未正确定义led0别名或 GPIO 引脚。1. 检查my_f103_board.dts文件确保leds节点和aliases节点正确定义。2. 检查gpios gpioc 13 GPIO_ACTIVE_LOW;中的 GPIO 控制器gpioc和引脚号13是否与你的硬件原理图一致。3. 使用west build -t menuconfig检查 GPIO 相关配置是否启用。链接错误提示内存不足应用程序大小超过了芯片的 Flash 或 RAM 容量。1. STM32F103C8T6 Flash 为 64KBRAM 为 20KB。检查build/zephyr/zephyr.map文件末尾的占用情况。2. 在prj.conf中禁用不必要的功能如CONFIG_SHELLn,CONFIG_CONSOLEn。3. 优化代码移除不用的模块。5.2 烧录与调试阶段问题问题现象可能原因检查方式与解决方案west flash失败提示No ST-Link detected或OpenOCD failed1. ST-Link 驱动未安装或udev规则未生效。2. ST-Link 与目标板连接错误或接触不良。3. 目标板未供电或供电不足。1. 运行lsusb查看是否有STMicroelectronics ST-LINK设备。若无需安装驱动Linux 下通常是stlink-tools包。2. 重新检查并连接 SWDIO, SWCLK, GND 四根线。3. 确保目标板有电可通过 ST-Link 供电或外部 3.3V。4. 尝试使用openocd命令手动连接openocd -f interface/stlink.cfg -f target/stm32f1x.cfg。烧录成功但 LED 不闪烁1. 设备树中 LED 引脚定义错误如 active-high/low 不对。2. 系统时钟配置错误导致k_msleep实际延时不准。3. 程序未运行可能 Boot0 引脚为高电平进入了系统存储器启动模式。1. 用万用表或逻辑分析仪检查 PC13 引脚是否有电平变化。若无检查设备树 GPIO 配置。2. 在main函数开头添加printk(“Start\n”);并通过串口工具如minicom,picocom查看 PA9/PA10 是否有输出验证系统初始化和时钟。3. 确认 Boot0 引脚已接地。无法进入调试模式VSCode Cortex-Debug1.launch.json配置错误。2. 调试器类型或芯片型号选错。3. 调试接口被占用如west flash后未复位。1. 在.vscode/launch.json中正确配置servertype如openocd、interface如stlink.cfg和device如stm32f1x.cfg。2. 先通过west flash确认硬件连接和烧录正常再尝试调试。3. 关闭可能占用调试接口的其他软件。5.3 环境与配置问题问题现象可能原因检查方式与解决方案VSCode C/C 扩展报错无法找到头文件c_cpp_properties.json未正确配置包含路径。1. 在 VSCode 中按CtrlShiftP运行C/C: Edit Configurations (UI)。2. 在Include Path中添加 Zephyr 内核头文件路径如“${workspaceFolder}/../zephyrproject/zephyr/include/**”和“${workspaceFolder}/build/zephyr/include/generated/**”。3. 在Defines中添加__ZEPHYR__。修改prj.conf或设备树后构建似乎未生效构建缓存导致。CMake 不会因为配置文件的更改而自动重新运行。1. 最彻底的方式删除build目录重新执行west build。2. 推荐方式使用west build -t run或west build -t menuconfig等目标它们会触发必要的重新配置。6. 进阶配置与最佳实践成功运行第一个示例后可以进一步优化开发流程并探索更多功能。6.1 配置 VSCode 实现高效开发智能感知配置创建.vscode/c_cpp_properties.json文件手动指定 Zephyr 的包含路径和宏定义确保代码跳转和补全准确。集成构建与烧录结合tasks.json和快捷键绑定将west build和west flash绑定到CtrlShiftB和F5实现一键编译烧录。图形化调试配置.vscode/launch.json使用 Cortex-Debug 扩展。一个基础的配置示例如下{ version: 0.2.0, configurations: [ { name: Cortex Debug (OpenOCD), cwd: ${workspaceRoot}, executable: ${workspaceRoot}/build/zephyr/zephyr.elf, request: launch, type: cortex-debug, servertype: openocd, serverpath: openocd, configFiles: [ interface/stlink.cfg, target/stm32f1x.cfg ], runToEntryPoint: main, device: STM32F103C8 } ] }配置后按 F5 即可启动调试会话在源码中设置断点、观察变量。6.2 为生产环境优化配置用于学习的prj.conf通常比较简陋。对于实际项目需要考虑以下配置# 硬件驱动 CONFIG_GPIOy CONFIG_SERIALy CONFIG_UART_INTERRUPT_DRIVENy # 内核与调度 CONFIG_MAIN_STACK_SIZE2048 CONFIG_IDLE_STACK_SIZE1024 CONFIG_ISR_STACK_SIZE2048 CONFIG_SYS_CLOCK_TICKS_PER_SEC1000 CONFIG_OPTIMIZE_SIZEy # 优化代码大小 # 日志与调试开发时开启生产时可关闭 CONFIG_LOGy CONFIG_LOG_MODE_IMMEDIATEy # 立即输出日志便于调试 CONFIG_CONSOLEy CONFIG_UART_CONSOLEy # 硬件特定配置 CONFIG_CLOCK_CONTROLy CONFIG_CLOCK_STM32_CUBEy CONFIG_PWMy # 如果需要PWM CONFIG_I2Cy # 如果需要I2C CONFIG_SPIy # 如果需要SPI6.3 管理多个应用与自定义板卡随着项目增多建议应用目录独立每个应用如blinky,sensor_app都像blinky_f103一样是zephyrproject同级目录下的独立文件夹。板卡定义集中管理可以将自定义的boards/arm/my_f103_board目录移动到zephyrproject下的某个位置如zephyrproject/my_boards并通过设置BOARD_ROOT环境变量来让 west 找到它export BOARD_ROOT~/zephyrproject/my_boards。这样所有应用都可以共享这个板卡定义。使用版本控制将你的应用代码和自定义板卡定义纳入 Git 管理。但注意build目录和 Zephyr 源码本身由 west 管理不应提交。6.4 扩展方向在点亮 LED 的基础上可以尝试使用串口打印日志在prj.conf中启用CONFIG_SERIAL和CONFIG_UART_CONSOLE在代码中使用printk输出信息通过 USB 转 TTL 模块连接 PA9/PA10 查看。添加传感器驱动例如通过 I2C 或 SPI 连接一个温湿度传感器在 Zephyr 中启用对应的驱动如CONFIG_SENSOR和CONFIG_BME280并参考示例代码读取数据。使用线程和同步原语创建多个线程k_thread_create使用信号量k_sem或消息队列k_msgq进行通信体验 Zephyr 的实时调度能力。功耗管理配置低功耗模式测量系统在不同睡眠模式下的电流消耗。从在 VSCode 中成功编译并烧录第一个 Zephyr 程序到 STM32F103C8T6标志着你已经打通了基于现代工具链的嵌入式开发流程。这个流程的核心价值在于其可重复性和可扩展性——一旦环境配通后续开发新功能、移植到其他芯片或板卡大部分工作就变成了修改配置文件和编写应用逻辑而非重复搭建环境。遇到问题时务必遵循从环境工具链、驱动、连接硬件、调试器、配置Kconfig、设备树到代码的逻辑进行分层排查。将自定义板卡定义标准化并纳入版本管理是团队协作和项目复用的关键一步。接下来你可以深入探索 Zephyr 的设备驱动模型、电源管理、网络协议栈等高级特性将其应用到更复杂的物联网设备开发中。
返回列表