基于 CMSIS-DAP 的 Cortex-M 在线烧录器(Windows 桌面工具)。
面向嵌入式开发与小批量生产:通过 CMSIS-DAP / DAPLink / MKLink 探针,对 STM32 与 国民技术 N32 系列 MCU 进行 擦除 / 烧录 / 校验 / 复位运行。底层直接复用 pyOCD,不自研 CMSIS-DAP / SWD / DAP 协议。
这是"在线烧录工具",不是脱机烧录器、不是调试器、不是通用 IDE。
- 图形界面(PySide6)分 5 个区域:探针 / 目标芯片 / 固件文件 / 操作 / 日志。
- 芯片参数全部来自
app/targets/*.yaml,不在代码里硬编码。 - 分层架构:
UI → core → backends(pyOCD),UI 不直接 依赖 pyOCD,后端可替换。 - 耗时操作(连接/擦除/烧录/校验)在后台线程执行,界面不假死。
- 统一错误码,错误提示面向工程师(错误 / 原因 / 处理)。
- CMSIS-DAP(v1 HID / v2 Bulk)
- DAPLink
- MKLink 等兼容 CMSIS-DAP 模式的探针
第一版 不支持 ST-Link、J-Link、OpenOCD 多后端。
| 厂商 | 系列 | 型号 |
|---|---|---|
| STMicroelectronics | STM32F1 | STM32F103C8T6 / STM32F103RCT6 |
| STMicroelectronics | STM32F4 | STM32F407VET6 / STM32F407ZGT6 |
| STMicroelectronics | STM32G4 | STM32G431 / STM32G474 |
| STMicroelectronics | STM32H5 | STM32H563ZI / II / VI(Cortex-M33,2MB) |
| Nationstech | N32G435 | N32G435CB / N32G435RB |
新增型号只需在 app/targets/ 增加或修改 YAML,无需改代码。
STM32H5(Cortex-M33)与被排除的 STM32H7 不同,已支持。 第一版仍 不支持 STM32H7 / U5、TrustZone 安全区划分、双核、外部 QSPI/SPI Flash 离线烧录、RDP 自动解除、Option Bytes 自动修改、多探针并行烧录。
.hex(Intel HEX):地址来自文件内部,无需 手填地址。.bin(原始二进制):必须 填写烧录地址(默认0x08000000,可改)。
需要 Python 3.10+(Windows)。
pip install -r requirements.txt依赖:PySide6、pyocd、PyYAML、intelhex。
图形界面:
python -m app.main命令行(最小验证脚本,先跑通链路用):
# 列出探针
python tools/test_pyocd_flash.py --list-probes
# 列出已配置的目标型号
python tools/test_pyocd_flash.py --list-targets
# 烧录 hex
python tools/test_pyocd_flash.py --target stm32f407vet6 --file app.hex
# 烧录 bin(必须给地址)
python tools/test_pyocd_flash.py --target n32g435cb --file app.bin --address 0x08000000用 PyInstaller 打包成单文件、免安装的 DAPFlash.exe(Windows):
pip install pyinstaller
python -m PyInstaller dapflash.spec --noconfirm --clean产物在 dist/DAPFlash.exe,双击即可运行,无需安装 Python。
- 芯片 YAML 已内置进 exe;在 exe 同级新建
targets/放 YAML 可覆盖或扩展芯片(优先级高于内置)。 - CMSIS-Pack 放到 exe 同级的
packs/目录即可被引用。 - 自检(验证探针/芯片加载,结果写
selftest_result.txt):DAPFlash.exe --selftest。 - 打包细节见 dapflash.spec:已处理 pyOCD 探针插件 entry-points、 cmsis-pack-manager 原生扩展、libusb/hid USB 后端的收集。
- 跨机器注意:STM32H5 默认走 pyOCD 托管库(本机
pyocd pack install装过才有)。 换机器使用时,把Keil.STM32H5xx_DFP.pack放到 exe 同级packs/,并在同级targets/stm32h563.yaml里把pack:指向它即可。
第一版不做在线下载 Pack。请手动准备 CMSIS-Pack(.pack)文件:
- 把
.pack放到项目根目录的./packs/下。 - 目标 YAML 里的
pyocd.pack指向它(相对项目根目录,如packs/Keil.STM32F4xx_DFP.pack)。 - 若 Pack 不存在,连接时会提示
PACK_NOT_FOUND。
需要哪些 Pack:
| 系列 | 需要的 Pack | 说明 |
|---|---|---|
| STM32F1 | 无(pyOCD 内置) | 直接可用 |
| STM32F4 | Keil.STM32F4xx_DFP.pack |
放入 ./packs/ |
| STM32G4 | Keil.STM32G4xx_DFP.pack |
放入 ./packs/ |
| STM32H5 | Keil.STM32H5xx_DFP |
pyocd pack install stm32h563zitx(托管库,无需放 ./packs/) |
| N32G435 | N32G43x_DFP.pack(国民技术) |
放入 ./packs/,必需 |
H5 采用 pyOCD 托管库方式(
pyocd pack install),装好后 YAML 里pack: null即可, target 自动解析。这也演示了本工具支持的第二种 Pack 来源(内置 / 托管库 / 本地文件)。
核对 target 名:
pyocd list --targets(内置)或pyocd pack show packs/xxx.pack(Pack 内器件)。 若器件名与 YAML 里的pyocd_target不一致,请据实修改 YAML。详见packs/README.md。
- 插入 CMSIS-DAP 探针 → 点击 刷新探针。
- 选择 厂商 / 系列 / 型号(例如 STM32F407VET6)。
- 浏览 选择
.hex文件(地址自动,无需填写)。 - 点击 一键烧录(连接 → 擦除 → 烧录 → 校验 → 复位运行 → 断开)。
- 同上选择探针与型号。
- 选择
.bin文件,在 烧录地址 填入地址:- Bootloader:
0x08000000 - Application:
0x08005000
- Bootloader:
- 点击 一键烧录。未填写地址将提示
BIN_ADDRESS_MISSING,禁止烧录。
提示均为「错误 / 原因 / 处理」三段式,面向工程师。
| 错误码 | 含义与处理 |
|---|---|
PROBE_NOT_FOUND |
未发现探针。检查 USB / 驱动 / CMSIS-DAP 模式后刷新。 |
CONNECT_FAIL |
SWD 连接失败。检查 SWDIO/SWCLK/GND/复位接线与供电,必要时降频。 |
TARGET_NOT_SUPPORTED |
pyOCD 不认识该 target。核对 YAML 的 pyocd_target,或提供 Pack。 |
PACK_NOT_FOUND |
引用的 .pack 不存在。放入 ./packs/ 或修正 YAML 路径。 |
TARGET_LOCKED |
疑似 RDP / 读保护。第一版不自动解除,请用 STM32CubeProgrammer 等先解保护。 |
BIN_ADDRESS_MISSING |
bin 未填地址。填入 0x08000000 等。 |
ERASE_FAIL |
擦除失败。检查供电/接线/保护状态,必要时降频重试。 |
PROGRAM_FAIL |
烧录失败。检查地址是否在 Flash 范围、供电稳定,必要时先整片擦除。 |
VERIFY_FAIL |
校验不一致。确认地址正确、未写保护,重新擦除+烧录。 |
RESET_FAIL |
复位失败。检查复位方式与 nRST 接线,必要时改软件复位。 |
- 仅在线烧录,不做脱机下载。
- 仅 CMSIS-DAP,不做 ST-Link / J-Link / OpenOCD。
- 仅上表所列 STM32 / N32 型号(可通过 YAML 扩展)。
- 不做 RDP 自动解除、Option Bytes 自动修改、TrustZone、双核、外部 Flash。
- Pack 需手动放置,不做在线下载 / 自动更新。
- Pack 在线查找 / 安装(
pyocd pack find/install)。 - 更多芯片系列与厂商。
- 烧录参数持久化、批量/产线模式。
- 更细的进度与速度统计。
DAPFlash/
├── app/
│ ├── main.py # 入口:python -m app.main
│ ├── ui/ # 5 个面板 + 主窗口(PySide6)
│ ├── core/ # errors / image_loader / target_manager /
│ │ # programmer / flash_task / probe_manager
│ ├── backends/ # base_backend / pyocd_backend(仅此处 import pyOCD)
│ ├── targets/ # 芯片 YAML 配置
│ └── resources/
├── packs/ # 放置 CMSIS-Pack(.pack)
├── tools/test_pyocd_flash.py # 阶段 1 CLI 验证脚本
├── docs/ # 需求规格书等
├── examples/
└── requirements.txt
- UI 不碰 pyOCD:界面只调用
BaseBackend接口与 core 层。 - 后端可替换:
PyOCDBackend实现BaseBackend;将来可加别的后端。 - 异常统一:后端把底层异常转成带错误码的
FlashError。 - 不阻塞主线程:
FlashTask(QObject)在 QThread 中跑Programmer序列, 通过 signal/slot 把进度、日志、错误推回 UI。 - 可中止:pyOCD 单步不可即时打断,中止在作业之间生效(当前阶段结束后停止)。
原始需求规格书见 docs/需求规格书_v0.1.md。