Files
STM32F4-Base/docs/测试说明/测试工具/ST-LINK_CLI_复位使用说明.md
T
super_agent_bot 72b4b0943c docs: clear task and layer shorthand IDs
Replace task/batch shorthand IDs and residual layer labels in
human-facing docs with semantic phrases. Add the new cleanup
policy to docs/编号规范.md and update the entry docs.

Machine keys (TC/CODE-RULE/MENU-STATE/TRAP/FR), hardware
designators/pins/MAC, protocol/version numbers and frozen
historical evidence are intentionally kept.

Docs only; no code behavior change. Verified with
check_doc_links.py --all and git diff --check.
2026-11-02 03:33:51 +08:00

232 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ST-LINK_CLI 复位使用说明(v3.5.0.0 本机实测版)
> 依据:本机 ST-LINK Utility 4.5.0.0 自带 `ST-LINK_CLI.exe`(CLI 版本 v3.5.0.0,`-h` 全文已实测核对)+ ST 官方文档语义。
> 探针路径:经 `DTU_STLINK_CLI` 环境变量解析(本机设为标准安装位 `C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ST-LINK_CLI.exe`;未设时回退 PATH,`stlink_flash.py` 均可用)
> 2026-09-19 已上板实测(ST-LINK/V2,FW V2J37S7,SN `0B250D12A218303030303032`;STM32F407ZGTx 目标,SWD)。
> 2026-09-20 复测(V0.1 板):烧写静默失败根因闭环(见 §2 ⑤ 与 §7)、完整启动闭环(见 §5)。
> ⚠️ **本机接线:3 根线(SWDIO / SWCLK / GND),nRST 未接** → 能力边界见 §0,实测记录见 §5。
> 文中标注 ⓞ 的为"官方帮助/文档说法"与"本机实测"不一致处的更正。
---
## 0. 本机接线与能力边界(先读)
当前板(V0.1;09/19 上板实测时为 V2 板,接线相同)↔ ST-LINK/V2 只接了 **3 根线**:
| 线 | 目标端 | 探针端 | 状态 |
|---|---|---|---|
| SWDIO | SWD 数据 | SWDIO | ✅ 已接 |
| SWCLK | SWD 时钟 | SWCLK | ✅ 已接 |
| GND | 地 | GND | ✅ 已接 |
| **nRST** | 芯片复位脚 | **RESET** | ❌ **未接** |
由此得到本机能力矩阵:
| 能力 | 本机(3 线) | 说明 |
|---|---|---|
| 软件系统复位(`-Rst`,SYSRESETREQ) | ✅ | **本机"重启板子"的唯一方式** |
| 停核/运行/单步/断点(`-Halt`/`-Run`/`-Step`/`-SetBP`) | ✅ | 调试用 |
| 内存/Flash 读写、擦除、校验(`-r*`/`-w*`/`-P`/`-V`/`-ME`/`-SE`/`-CmpFile`) | ✅ | |
| 不扰连接 / 低功耗唤醒 / 读电压 / 枚举探针(`HOTPLUG`/`LPM`/`-TVolt`/`-List`) | ✅ | |
| nRST 引脚操作(`-HardRst`、`RM=Hrst`) | ❌ | **双重障碍**:① nRST 未接线(无信号可驱动)② v3.5.0.0 CLI 拒识 `RM=`(ⓞ,见 §2③) |
| 复位态连接(`UR`) | ❌ | 需要 nRST 接线才能"按住复位连接" |
要点:
- **日常"命令重启板子" = `-c SWD -Rst -Run`(软件系统复位)**。对 STM32F4,SYSRESETREQ 会复位内核 + 几乎所有外设,与 nRST 硬复位的固件级效果等价(差别仅在 nRST 引脚本身不动、调试域保留)——3 线接线场景下这就是复位能力的上限,完全够用。
- **需要 nRST 引脚级操作时**(复位电路/上电时序验证、跑飞后的复位态连接救援)必须补第 4 根线:目标 nRST → 探针 RESET 脚。补线之后注意:本机 v3.5.0.0 CLI 仍不认 `RM=`(ⓞ),届时要走 ST-LINK Utility GUI、升级 ST-LINK Utility(新版 CLI)、或换 J-Link。
- `stlink_flash.py hard` 已内置回退:本机永远回退到软件复位(exit 仍为 0),**不会把脚本跑断**;将来补线 + 升级 CLI 后自动升级为真 nRST 脉冲,无需改脚本。
## 1. 三种"复位"(核心概念)
| 种类 | 触发源 | 复位范围 | CLI 表达 | 本机可用 |
|---|---|---|---|---|
| **硬件复位(nRST)** | 探针驱动目标 nRST 引脚 | 整片冷启动,最接近"重新上电" | `-HardRst [LOW/HIGH/PULSE=<ms>]`(配 `RM=Hrst`) | ❌ nRST 未接线(且 CLI 不支持 `RM=`) |
| **软件系统复位(SYSRESETREQ)** | 调试器写系统复位寄存器 | 内核 + 绝大多数外设(调试域保留) | `-Rst`(默认模式即可) | ✅ **本机唯一复位方式** |
| **内核复位(AirCore/VC)** | 内核复位信号 | 仅内核;**外设保持运行** | `-c ... RM=Crst`(连接时选择) | ⓞ v3.5.0.0 CLI 拒识 `RM=`,本机不可用 |
## 2. 六个核心复位用法
### ① 复位并运行(重启板子,最常用)✅ 本机可用
```bat
ST-LINK_CLI -c SWD -Rst -Run
```
时序:连接(默认连接即停核)→ 系统复位 → 运行 → 板子从 Flash 引导重新跑固件。
这就是"命令控制板子重启",本机 3 线接线完全够用。
### ② 复位并停核(调试/检查用)✅ 本机可用
ⓞ **实测更正**:v3.5.0.0 CLI 下 `-Rst` 之后核是**运行**状态(`-SCore` 回读 "Core is Running."),并不停核。要停核必须显式加 `-Halt`:
```bat
ST-LINK_CLI -c SWD -Rst -Halt
```
实测:停核成功,SP=0x2001E8B8(与向量表首字一致),**PC=0x08004664**——复位后核先运行了一段启动代码再被停住(软件系统复位不保持调试 halt,停点由 `-Halt` 下发时刻决定,不保证是复位向量)。
ⓞ 本机无 nRST 线 + CLI 不支持 `RM=`,**"精确停在复位向量"在本机不可实现**;停核读取命令必须与复位写在**同一命令行**:
```bat
ST-LINK_CLI -c SWD -Rst -Halt -SCore -CoreReg :: 复位停核后读核状态 + 寄存器
ST-LINK_CLI -c SWD -Rst -Halt -R32 0x08000000 4 :: 停核后读向量表前 4 个字
```
ⓞ **一次性连接语义(实测)**:ST-LINK_CLI 是"连接→执行→断开"的一次式进程,**会话结束(断开)时核自动恢复运行**。因此 `stlink_flash.py halt` 单独调用只适合"复位后读状态"场景,断开后板子会继续运行;需要**持续性 halt**(GDB 调试/长时间断点)请走 GDBServer/IDE 路径。
### ③ 硬件复位:nRST 脉冲 ❌ 本机不可用(nRST 未接线)
```bat
:: 仅备查:需 nRST 接线 + 支持 RM= 的 CLI/GUI/J-Link
ST-LINK_CLI -c SWD RM=Hrst -HardRst PULSE=100
```
`PULSE=100` 意为 nRST 拉低 100ms 再释放(整片冷启动,等价于按复位键/重新上电)。
本机不可用的原因(双重障碍):
1. **nRST 线未接**(3 线接线)——探针没有可驱动目标复位脚的信号;
2. ⓞ v3.5.0.0 CLI 拒识 `RM=`:`RM=Hrst/Srst/Crst` 在 4 种语法排列下全部报错
`[RM=Hrst]: Unknown debug protocol or option!`(exit=1)——帮助文本与实现不符。
将来若补 nRST 线:ST-LINK GUI 可先做引脚级操作;要 CLI 化则升级 ST-LINK Utility 或换 J-Link。
### ④ nRST 电平保持序列 ❌ 本机不可用(nRST 未接线)
```bat
:: 仅备查:按住复位→释放,用于复位电路验证/上电过程观察
ST-LINK_CLI -c SWD RM=Hrst -HardRst LOW -HardRst HIGH
```
(`-HardRst LOW` 按住、`-HardRst HIGH` 释放;需 nRST 接线 + 支持 `RM=` 的工具。)
### ⑤ 烧写 + 复位 + 运行(完整固件更新)✅ 本机可用
```bat
ST-LINK_CLI -c SWD -P "MDK-ARM\STM32F407-Demo\STM32F407-Demo.hex" -Rst -Run
```
- ⓞ **`.hex` 直接支持已实测**:1MB Intel HEX 编程耗时 **6.5s**,`Programming Complete`(远快于 UV4/CMSIS-DAP 路径);`.bin` 同理(`fromelf --bin` 可转,ARMCC 自带 `C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe`);`.axf` 直读未测,无需。
- 加 `-V` 编程后校验、`-Q` 静默。
- 与 `stlink_flash.py flash` 同源(都走 ST-LINK_CLI)。原 `download.bat`(`UV4 -f` 走 CMSIS-DAP)与 `reset.bat` **均已删除**(2026-10-10),烧录/复位/回读统一由 `stlink-flash` skill 承载。
- ⓞ **静默失败模式(2026-09-20 实测,代价最大的坑)**:省略结尾 `-Rst -Run` 的裸 `-c SWD -P <文件>` 仍报 `Memory programmed in 1s 906ms / Programming Complete`,但芯片 flash **不变**(回读向量表 = 旧镜像)——目标核处于死循环/异常状态时,"Normal 连接、不复位"的会话写入不落地;同文件改用完整 `-P <文件> -Rst -Run` 即正常落地(6.5s / 1MB)。**铁律:任何编程命令必须以 `-Rst -Run` 收尾;任何烧录之后必须 `-CmpFile` 全片回读校验**(详见 §7)。
### ⑥ 不扰目标连接(HOTPLUG,运行中板子的只读检查)✅ 本机可用
```bat
ST-LINK_CLI -c SWD HOTPLUG -SCore :: 核状态(Running/Halted、PC)
ST-LINK_CLI -c SWD HOTPLUG -R32 0x08000000 4 :: 读运行中芯片的 Flash
ST-LINK_CLI -c SWD HOTPLUG -TVolt :: 读 VDD
ST-LINK_CLI -c SWD HOTPLUG -Dump 20000000 1000000 dump.bin :: 转储 SRAM
```
`HOTPLUG` = 连接时**不 halt、不 reset**——对正在跑的板子做无副作用检查。
## 3. `-c` 连接参数全表
```
-c [ID=<id>/SN=<sn>] [JTAG/SWD [SWCLK=<f>]] [UR/HOTPLUG] [LPM] [RM=Hrst/Srst/Crst]
```
| 参数 | 含义 | 本机状态 |
|---|---|---|
| `SWD` / `JTAG` | 调试接口(本工程用 SWD;SWD 只需 2 根信号线,JTAG 需 4 根) | ✅ 默认选 SWD |
| `SWCLK=<f>` | SWD 时钟。⚠️ 帮助文字标"KHz"但官方示例写 `SWCLK=5`(若按 KHz 则慢到不可用),两处自相矛盾 | ⓞ 先不传,用探针默认(本机实测自动协商到 4000K);连接慢/失败再小步试验 |
| `UR` | 在复位状态下连接(nRST 拉低期间完成连接) | ❌ 需 nRST 接线(本机未接) |
| `HOTPLUG` | 连接时不 halt、不 reset | ✅ |
| `LPM` | 低功耗模式下进入调试(先唤醒目标) | ✅ |
| `RM=Hrst/Srst/Crst` | 本次会话的复位机制:nRST 引脚 / 软件系统复位 / 仅内核 | ⓞ v3.5.0.0 全部拒识,勿用 |
| `ID=<0..9>` / `SN=<串号>` | 多探针选择(默认 ID=0) | ✅ 一机多板时用于指定 |
示例(多板场景):`-c SN=0B250D12A218303030303032 SWD LPM`
## 4. 核状态 / 内存 / Flash 辅助命令(复位前后验证链)
| 命令 | 作用 |
|---|---|
| `-SCore` | 核状态:Running/Halted + 程序计数器(复位后核对"停在哪") |
| `-CoreReg` | 读核心寄存器组(SP/PC/xPSR 等) |
| `-Halt` / `-Run [addr]` | 停核 / 运行(可从指定地址开始) |
| `-Step` | 单步 |
| `-SetBP <address>` / `-ClrBP` | 设/清断点 |
| `-r8/-r16/-r32 <地址> <数量>` | 读内存(地址、数量均为**十六进制**) |
| `-w8/-w32/-w64 <地址> <数据>` | 写内存 |
| `-Dump <地址> <大小> <文件>` | 内存转储到文件 |
| `-CmpFile <文件> [地址]` | 全片 Flash 与文件逐字节比对(2026-09-20 实测:`No difference found` = 真写入;v3.5.0.0 无 `-Cksum` 命令)。⚠ **连接即复位目标**(2026-10-10 实测:比对瞬间板子重打一遍开机日志)→ 自动化里必须排在日志采集之后 |
| `-P <文件> [地址] [ske] [skpv]` | 编程(ske=跳擦除 skpv=跳校验) |
| `-V [after_programming]` | 校验 |
| `-ME` / `-SE <扇区>` | 全片擦除 / 扇区擦除(⚠️ RDP≠0 时 `-ME` 会被拒) |
| `-TVolt` | 目标 VDD 电压(⚠️ 需 VDD 感应脚接至目标;本机台架 3 线连接(SWDIO/SWCLK/GND)此脚未接,读数无效,供电判据以万用表实测为准) |
| `-Q` / `-Log` / `-NoPrompt` | 静默 / 生成跟踪日志 / 免交互确认 |
| `-List` | 枚举所有已连接探针(固件版本 + 串号) |
退出码:`0`=成功;`2`=未检测到探针(本机实测);其他非零=失败。
## 5. 本工程实战组合
**A. 只重启不烧录**(固件没变,重新验证启动/串口行为;配合 serial_tool)
```powershell
& '.venv\Scripts\python.exe' .dsh/skills/serial-assistant/scripts/serial_tool.py open
& '.venv\Scripts\python.exe' .dsh/skills/serial-assistant/scripts/serial_tool.py clear
& '.venv\Scripts\python.exe' .dsh\skills\stlink-flash\scripts\stlink_flash.py reset # = ST-LINK_CLI -c SWD -Rst -Run -Q
# 等待开机完成后直接读日志文件校验标记:
Get-Content .dsh\skills\serial-assistant\scripts\state\serial.log -Tail 100
```
顺序关键:**先开串口清日志,再复位**,否则错过开机头几行(与 `run_boot_test.py` 的"采集先于烧录"原则一致)。
ⓞ 实测补充三条:
1. **改过 `.serialtest/config.json` 端口后必须重启 daemon**:daemon 在启动时缓存配置,改端口后 `close` + 杀旧进程再 `open`,否则一直按旧端口报 `port not found`;
2. **(已修,2026-10-10)旧版 `wait-idle` 在复位突发期会报 `daemon unresponsive after auto-start: timed out`**:CLI 把**超时**误判成"daemon 不可达",顺手拉起一个绑不上 HTTP 口的实例再把命令撞一次超时(数据其实已落盘)。现 CLI 超时按 `--max-ms` 自动推导、超时只快速失败不再误拉起实例;
3. **日志校验**:`.dsh/skills/serial-assistant/scripts/state/serial.log` 用 Read/Grep 直接查最直观;`serial_tool.py log --grep <标记>` 现已可作判定依据(2026-10-10 修:旧实现先 `--tail`(默认 50)后 grep,开机标记必然查不到——这就是当年"实测 0 命中、语义存疑"的真根因)。
**B. 完整烧写 + 运行**:`stlink-flash` skill 的 `stlink_flash.py flash [xxx.hex]`(= `-c SWD -P <hex> -Rst -Run`;09/19 实测 1MB ≈ 6.5s,09/20 复测 6.47s + 全片 `-CmpFile` 逐字节一致)。**2026-10-10 起 CLI 路径即唯一烧录路径**——原 `download.bat` 的 `UV4 -f` 与 `reset.bat` 均已删除。
**RS-485 采集链路. 回读校验**:`stlink_flash.py cmp [xxx.hex]`(= `-c SWD -CmpFile <hex> 0x08000000`,2026-10-10 加;默认对最新构建 hex)。判定看输出行首的 `No difference found`(`This file is already downloaded` 是同义提示)。⚠ **连接即复位目标**:实测比对瞬间板子重打一遍开机日志 → 在自动化闭环里回读必须排在**日志采集之后**(`run_boot_test.py` 已按此顺序内置)。
**C. 救援**(板子起不来 / 疑似 Flash 问题)——本机 3 线接线的可行子集:
```bat
ST-LINK_CLI -c SWD LPM :: 若目标休眠/连不上,先试低功耗唤醒
ST-LINK_CLI -c SWD -ME :: 全片擦除(前提 RDP=0;RDP≠0 需先 -rOB 确认,RDP 解锁是专门流程)
ST-LINK_CLI -c SWD -P "MDK-ARM\STM32F407-Demo\STM32F407-Demo.hex" -Rst -Run
```
ⓞ 注意:`UR`(复位态连接)在本机不可用(nRST 未接线)——跑飞救援能力受限,能做的只有"正常连接 + LPM + 全擦重烧";若板子连 SWD 都握不上手,需先补 nRST 线。
**D. 运行中检查**:`-c SWD HOTPLUG -SCore` / `-R32` / `-TVolt`(⚠️ 本机 3 线连接下读数无效,见命令表注记)/ `-Dump`。
## 6. `stlink-flash` skill 的复位/烧录子命令(2026-09-19 上板验证;原 `MDK-ARM\reset.bat` 已于 2026-10-10 删除并全并入本 skill)
用法(全部分支 exit=0 实测通过):
| 调用 | 行为 | 本机实际效果 |
|---|---|---|
| `stlink_flash.py reset` | `-c SWD -Rst -Run` | ✅ 软件系统复位 + 运行(重启板子) |
| `stlink_flash.py hard` | `-c SWD RM=Hrst -HardRst PULSE=100`,被拒则回退 | ⓞ 本机 `RM=` 被拒 → **自动回退软件复位**(打印 RESET_NOTE,exit=0);补 nRST 线 + 升级 CLI 后自动升级为真 nRST 脉冲 |
| `stlink_flash.py halt` | `-c SWD -Rst -Halt` | ✅ 复位停核(一次性会话,读状态须同命令行附加;断开后核自动恢复运行) |
| `stlink_flash.py run` | `-c SWD -Run` | ✅ 恢复被停核的目标 |
| `stlink_flash.py list` | `-List` | ✅ 枚举探针 |
| `stlink_flash.py flash [F]` | `-c SWD -P F -Rst -Run`(F 缺省 = 档案 `hex` = `MDK-ARM\STM32F407-Demo\STM32F407-Demo.hex`) | ✅ 烧写 + 复位 + 运行(1MB ≈ 6.5s;2026-09-20 复测验证,见 §2 ⑤) |
| `stlink_flash.py cmp [F]` | `-c SWD -CmpFile F 0x08000000` | ✅ 全片回读比对(`No difference found` = 真写入) |
退出码:`0`=OK;`1`=探针/目标错误;`2`=CLI 未找到/无效;`3`=用法错误。
注意:档案(`.serialtest/config.json`)解析、`DTU_STLINK_CLI` 工具路径解析(未设回退 PATH;显式设了但无效 = 硬报错)、镜像缺省值均内置于脚本;`stlink_flash.py` 为纯标准库 Python,无原 bat 的引号/CRLF 行尾坑。
## 7. 故障排查速查
| 现象 | 排查 |
|---|---|
| `No ST-LINK detected!`(exit=2) | 探针没插/USB 未枚举/驱动问题。本机已装 STLinkWinUSB 驱动;`stlink_flash.py list` 复核;换 USB 口(避免前端_hub) |
| `[RM=xxx]: Unknown debug protocol or option!`(exit=1) | ⓞ v3.5.0.0 CLI 不支持 `RM=`(帮助与实现不符);**且本机 nRST 未接线**——直接用软件复位 `-Rst`(`stlink_flash.py reset`) |
| 连接失败 | 目标供电;SWDIO/SWCLK 接线(本机 3 线,勿依赖 nRST 辅助);芯片休眠 → 加 `LPM`;看门狗反复复位 → 提高连接速度(本机无 `UR` 可用);RDP 被锁 → 只能读有限信息 |
| 复位后程序没跑 | 读复位向量确认 Flash 有效:`-R32 0x08000000 1`(应指向 0x08xxxxxx,`0xFFFFFFFF`=空片);查 BOOT0 状态;看串口是否有输出 |
| 复位后卡死(串口日志中断在半路) | ⓞ 2026-09-19 实测案例:`-c SWD HOTPLUG -SCore -CoreReg` 读 PC/寄存器定位卡点(案例:V2 引脚固件卡在 0x08000FA0 启动循环,见 §5)——**先定位再下结论**,勿直接怀疑探针 |
| 烧录报成功但芯片行为不变 | ⓞ **先怀疑静默写入失败**(2026-09-20 实测):命令缺 `-Rst -Run`(裸 `-P` 在目标核死循环/异常时不落地)或选项字节异常(RDP 字节非法,见 §3 与 §7)。处置:`-CmpFile` 全片比对/回读向量表首字 → 用 `stlink_flash.py flash` 重烧 → 再 `-CmpFile` 复核;勿直接怀疑探针/接线 |
| `daemon unresponsive after auto-start`(serial_tool) | ⓞ 复位后几秒内 daemon 忙于排空日志突发;稍等后直接读 `state/serial.log` 文件验证,勿反复重试 |
| `port not found: COMx (available: COMy)`(serial_tool) | ⓞ 端口重新枚举(板子重插常见):改 `.serialtest/config.json` → **kill 旧 daemon 进程** → 重新 `open`(daemon 启动时缓存配置,不重启不生效) |
| `log --grep` 查不到明明存在的标记 | ⓞ 该子命令实测不可靠(0 命中);改用直接读/`Select-String` 查 `state/serial.log` |
| SWD 通信不稳 | 不传 `SWCLK` 用默认时钟(本机实测 4MHz);检查长线/夹子接触 |
| 误改 option bytes | `-rOB` 读回现状;`-OB RDP=0` 等回写后需再复位生效;**RDP=2 会锁死调试+全片擦除,操作前务必确认** |
| 多板混淆 | `stlink_flash.py list` 拿串号,`-c SN=<串号>` 指定 |