news 2026/9/29 3:42:05

Zephyr BSP: 34-Flash Debug Runner

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zephyr BSP: 34-Flash Debug Runner

摘要:本文是 Zephyr BSP 系列的第 34 篇,聚焦于west build之后的关键环节——如何把编译出的zephyr.elf烧录到芯片并调试。文章系统梳理了 Build、Flash、Debug 三者的本质区别,深入剖析了 Zephyr 的 Runner 抽象层(Flash/Debug Backend),包括其核心接口、runners.yaml配置文件、west flash的完整调用链,以及board.cmake如何决定默认 Runner。同时对比了 ELF/BIN/HEX 三种镜像的用途(Flash 用 HEX/BIN,Debug 用 ELF),并解释了 Debug Server(如 OpenOCD)在 GDB 与调试探针之间的桥梁作用。最后以 Company SoC 接入 Zephyr 为例,说明如何编写自定义 Runner,并强调 Runner 是 BSP 的"开发工具链接口",与 Driver(运行时硬件控制)和 CMake(构建系统)有本质区别。读完本篇,你将理解 Zephyr 烧录与调试的完整闭环。

Flash / Debug / Runner

前面已经把 **SoC BSP 的"编译世界"**基本串起来了:

20理解 Zephyr ↓21SoC Port Skeleton ↓22CPU/Architecture ↓23Startup ↓24Interrupt Controller ↓25Clock/Reset ↓26Devicetree ↓27Binding ↓28UART Driver ↓29GPIO/SPI/I2C/Timer ↓30Board Support Package ↓31Kconfig ↓32CMake/Build System ↓33Linker/Memory Map

现在进入一个很关键但经常被忽略的部分:

编译出来的 zephyr.elf,到底是谁把它变成芯片里的程序?

也就是:

west build │ ▼ zephyr.elf │ ├── flash │ ▼ SoC Flash │ ├── debug │ ▼ GDB / Debug Probe

这一篇重点理解Flash Runner / Debug Runner。

1. 先理解三个完全不同的东西

Zephyr 中经常把下面三个概念混在一起:

Build Flash Debug

其实它们完全不同。

Build
负责:

C/C++ ↓ compile ↓link↓ zephyr.elf

例如:

west build-bnucleo_f303re

最终得到:

build/ ├── zephyr/ │ ├── zephyr.elf │ ├── zephyr.bin │ ├── zephyr.hex │ └── zephyr.map

Flash

Flash 的任务是:

zephyr.hex ↓ programmer ↓ MCU Flash

例如:

west flash

Debug

Debug 是:

GDB │ ▼ Debug Probe │ ▼ MCU

例如:

west debug

所以:
west build ≠ west flash ≠ west debug

2. west flash 到底做了什么?

用户看到的通常只有:

west flash

但实际上背后是一条比较长的链:

west flash │ ▼ West Runner │ ▼ Runner implementation │ ▼ Programmer / Debug Probe │ ▼ SWD / JTAG │ ▼ SoC │ ▼ Flash

这里真正值得学习的是:
Runner

3. Runner 是什么?

可以把 Runner 理解成:
Zephyr 对"如何把程序下载到目标板"的抽象层。
不同开发板使用不同工具:

ST-LINK J-Link OpenOCD pyOCD nrfjprog bossac dfu-util...

Zephyr 不希望每个 board 都自己写:

flash.sh debug.sh

所以使用:

Runner

统一描述:

flash debug debugserver

4. 为什么叫 Runner?

例如 STM32:

Board │ ▼ ST-LINK │ ▼ STM32CubeProgrammer

Zephyr 可以定义一个 Runner:

stm32cubeprogrammer

于是:

west flash

实际上就是:

west ↓ 找到当前 board 的 runner ↓ 调用 stm32cubeprogrammer runner ↓ STM32CubeProgrammer ↓ ST-LINK ↓ STM32

5. Runner 在哪里定义?

这是学习 Zephyr BSP 的一条非常重要的路径。

可以搜索:

findzephyr/scripts/west_commands/runners-typef

你会看到很多:

runners/ ├── core.py ├── bossac.py ├── dfu.py ├── jlink.py ├── openocd.py ├── pyocd.py ├── stm32cubeprogrammer.py ├── nrfjprog.py └──...

这实际上就是 Zephyr 的:

Flash / Debug Backend 层

6. Runner 的核心接口

Runner 通常围绕几个动作:

flash debug debugserver reset

概念上:

class Runner: def flash(self):... def debug(self):... def debugserver(self):...

因此:

west flash

最终会进入某个 Runner 的:

do_run()

然后执行具体工具。
6.1 常见 Runner 横向对比

为了更直观地理解不同 Runner 的差异,下面把 Zephyr 中最常见的 7 种 Runner 放在一起对比:

Runner适用厂商/平台调试探针默认协议典型命令示例
stm32cubeprogrammerST(STM32 系列)ST-LINKSWD / JTAGwest flash --runner stm32cubeprogrammer
jlink通用(SEGGER 生态)J-LinkSWD / JTAGwest flash --runner jlink
openocd通用(多厂商)ST-LINK / J-Link / CMSIS-DAP 等SWD / JTAGwest flash --runner openocd
pyocd通用(ARM Cortex-M)CMSIS-DAP / J-Link 等SWDwest flash --runner pyocd
nrfjprogNordic(nRF 系列)J-Link(板载)SWDwest flash --runner nrfjprog
bossacMicrochip(ATSAMD 等)板载 USB 引导USB(Bootloader)west flash --runner bossac
dfu-util通用(USB DFU 设备)USB 直连USB(DFU)west flash --runner dfu-util

如何选择 Runner?核心原则是:先看开发板板载了哪种调试探针,再选对应的 Runner。例如 STM32 Nucleo 板载 ST-LINK,默认用stm32cubeprogrammer;nRF 开发板板载 J-Link,默认用nrfjprog;如果板子没有板载探针、只支持 USB 引导,则用bossac或dfu-util。大多数情况下board.cmake已经帮你选好默认 Runner,直接west flash即可,只有需要切换工具链时才显式指定--runner。
6.2 Runner 抽象层与底层工具链的关系

下面这张 ASCII 架构图,把 Zephyr Runner 抽象层与底层工具链的关系完整串起来:顶层是用户敲的west flash/west debug命令,中间是 Runner 抽象接口(flash/debug/debugserver),底层则是七种具体工具及其对应的调试探针和目标芯片:

+-------------------------------------------+|west flash / west debug||(用户统一入口,不关心底层工具)|+--------------------+----------------------+|▼ +-------------------------------------------+|Runner 抽象接口(Zephyr)||+-----------------------------------+|||flash()debug()debugserver()|||+-----------------------------------+|+----+------------+------------+-----------+|||+--------------+ +--------+--------+ +--------------+||||||▼ ▼ ▼ ▼ ▼ ▼ +-------------+ +-------------+ +-------------+ +-------------+|STM32CubeProg||J-Link||OpenOCD||pyOCD||Runner||Runner||Runner||Runner|+------+------+ +------+------+ +------+------+ +------+------+||||▼ ▼ ▼ ▼ +-------------+ +-------------+ +-------------+ +-------------+|ST-LINK||J-Link||ST-LINK /||CMSIS-DAP /||探针||探针||J-Link /||J-Link 探针||||||CMSIS-DAP|||+------+------+ +------+------+ +------+------+ +------+------+||||▼ ▼ ▼ ▼ +-------------+ +-------------+ +-------------+ +-------------+|STM32 系列||通用 Cortex||通用 Cortex||通用 Cortex||(ARM)||-M芯片||-M芯片||-M芯片|+-------------+ +-------------+ +-------------+ +-------------+ +-------------+ +-------------+ +-------------+|nrfjprog||bossac||dfu-util||Runner||Runner||Runner|+------+------+ +------+------+ +------+------+|||▼ ▼ ▼ +-------------+ +-------------+ +-------------+|J-Link||USB||USB 直连||(板载)探针||Bootloader||(DFU 协议)|+------+------+ +------+------+ +------+------+|||▼ ▼ ▼ +-------------+ +-------------+ +-------------+|nRF 系列||Microchip||通用 USB DFU||(Nordic)||ATSAMD 等||设备|+-------------+ +-------------+ +-------------+

从这张图可以清晰看到:无论底层是哪种工具、哪种探针、哪种芯片,用户始终只面对west flash/west debug这一个入口。Zephyr 的 Runner 抽象层把"工具差异"和"探针差异"全部屏蔽掉了——这正是 BSP 中"开发工具链接口"的价值所在。

7. west flash 的完整链路

我们把它展开。
用户:

west flash

↓
West:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!