新增 ST-LINK CLI 复位脚本 reset.bat(复位/停机/运行/查探头/烧录)及测试说明文档

This commit is contained in:
2026-09-19 17:36:05 +08:00
parent deb4385a06
commit 6fea76463a
2 changed files with 333 additions and 0 deletions
@@ -0,0 +1,265 @@
# 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 官方文档语义。
> 探针路径:`C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ST-LINK_CLI.exe`
> 2026-09-19 已上板实测(ST-LINK/V2,FW V2J37S7,SN `0B250D12A218303030303032`;STM32F407ZGTx 目标,SWD)。
> ⚠️ **本机接线:3 根线(SWDIO / SWCLK / GND),nRST 未接** → 能力边界见 §0,实测记录见 §9。
> 文中标注 ⓞ 的为"官方帮助/文档说法"与"本机实测"不一致处的更正。
---
## 0. 本机接线与能力边界(先读)
当前 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`/`-Cksum`) | ✅ | |
| 不扰连接 / 低功耗唤醒 / 读电压 / 枚举探针(`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。
- `reset.bat` 的 `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 是"连接→执行→断开"的一次式进程,**会话结束(断开)时核自动恢复运行**。因此 `reset.bat 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` 静默。
- 与 `download.bat`(`UV4 -f` 走 CMSIS-DAP)功能等价;脚本化场景用 CLI 更轻,两者并存。
### ⑥ 不扰目标连接(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 <地址> <大小> <文件>` | 内存转储到文件 |
| `-Cksum <文件\|地址+大小>` | 校验和(对比 Flash 与文件) |
| `-P <文件> [地址] [ske] [skpv]` | 编程(ske=跳擦除 skpv=跳校验) |
| `-V [after_programming]` | 校验 |
| `-ME` / `-SE <扇区>` | 全片擦除 / 扇区擦除(⚠️ RDP≠0 时 `-ME` 会被拒) |
| `-TVolt` | 目标 VDD 电压 |
| `-Q` / `-Log` / `-NoPrompt` | 静默 / 生成跟踪日志 / 免交互确认 |
| `-List` | 枚举所有已连接探针(固件版本 + 串号) |
退出码:`0`=成功;`2`=未检测到探针(本机实测);其他非零=失败。
## 5. 本工程实战组合
**A. 只重启不烧录**(固件没变,重新验证启动/串口行为;配合 serial_tool)
```powershell
& '.venv\Scripts\python.exe' tools/serial_tool/serial_tool.py open
& '.venv\Scripts\python.exe' tools/serial_tool/serial_tool.py clear
& "MDK-ARM\reset.bat" # 等价于 ST-LINK_CLI -c SWD -Rst -Run -Q
# 等待开机完成后直接读日志文件校验标记:
Get-Content tools\serial_tool\state\serial.log -Tail 100
```
顺序关键:**先开串口清日志,再复位**,否则错过开机头几行(与 `run_boot_test.ps1` 的"采集先于烧录"原则一致)。
ⓞ 实测补充三条:
1. **改过 `serial_config.json` 端口后必须重启 daemon**:daemon 在启动时缓存配置,改端口后 `close` + 杀旧进程再 `open`,否则一直按旧端口报 `port not found`;
2. **复位刚发生的几秒内 `wait-idle` 可能报 `daemon unresponsive after auto-start: timed out`**——daemon 正在排空开机日志突发,数据其实已落盘;
3. **日志校验直接读文件最可靠**:`tools/serial_tool/state/serial.log` 用 Read/Grep/Select-String 直接查(实测 `log --grep` 子命令对确定存在的标记返回 0 命中,语义存疑,勿作为判定依据)。
**B. 完整烧写 + 运行**:`MDK-ARM\reset.bat flash [xxx.hex]`(= `-c SWD -P <hex> -Rst -Run`;实测 1MB 约 7s 完成)。正式流程仍以 `download.bat`(`UV4 -f`)为准,CLI 路径作为脚本化/快速路径。
**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` / `-Dump`。
## 6. `reset.bat`(已落工程 `MDK-ARM\reset.bat`,2026-09-19 上板验证)
用法(全部分支 exit=0 实测通过):
| 调用 | 行为 | 本机实际效果 |
|---|---|---|
| `reset.bat` | `-c SWD -Rst -Run` | ✅ 软件系统复位 + 运行(重启板子) |
| `reset.bat hard` | `-c SWD RM=Hrst -HardRst PULSE=100`,被拒则回退 | ⓞ 本机 `RM=` 被拒 → **自动回退软件复位**(打印 RESET_NOTE,exit=0);补 nRST 线 + 升级 CLI 后自动升级为真 nRST 脉冲 |
| `reset.bat halt` | `-c SWD -Rst -Halt` | ✅ 复位停核(一次性会话,读状态须同命令行附加;断开后核自动恢复运行) |
| `reset.bat run` | `-c SWD -Run` | ✅ 恢复被停核的目标 |
| `reset.bat list` | `-List` | ✅ 枚举探针 |
| `reset.bat flash [F]` | `-c SWD -P F -Rst -Run`(F 缺省 = 最新构建 `MDK-ARM\STM32F407-Demo\STM32F407-Demo.hex`) | ✅ 烧写 + 复位 + 运行(1MB ≈ 7s) |
退出码:`0`=成功;`1`=探针/目标错误;`2`=用法或工具缺失。
注意:bat 内 `STLINK` 变量**不带引号**、调用处再加引号(`set VAR="带空格路径"` 会把引号存进变量,导致 `if not exist` 与执行都失败——2026-09-19 实测踩坑并已修复);bat 文件必须 **CRLF** 行尾(LF 会破坏 `:label` 解析)。
## 7. 故障排查速查
| 现象 | 排查 |
|---|---|
| `No ST-LINK detected!`(exit=2) | 探针没插/USB 未枚举/驱动问题。本机已装 STLinkWinUSB 驱动;`reset.bat list` 复核;换 USB 口(避免前端_hub) |
| `[RM=xxx]: Unknown debug protocol or option!`(exit=1) | ⓞ v3.5.0.0 CLI 不支持 `RM=`(帮助与实现不符);**且本机 nRST 未接线**——直接用软件复位 `-Rst`(`reset.bat` 默认分支) |
| 连接失败 | 目标供电;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 启动循环,见 §9)——**先定位再下结论**,勿直接怀疑探针 |
| `daemon unresponsive after auto-start`(serial_tool) | ⓞ 复位后几秒内 daemon 忙于排空日志突发;稍等后直接读 `state/serial.log` 文件验证,勿反复重试 |
| `port not found: COMx (available: COMy)`(serial_tool) | ⓞ 端口重新枚举(板子重插常见):改 `.opencode/serial_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 会锁死调试+全片擦除,操作前务必确认** |
| 多板混淆 | `reset.bat list` 拿串号,`-c SN=<串号>` 指定 |
## 8. 与 J-Link 命令的对照(备查)
| 操作 | ST-LINK_CLI(本机已装) | JLinkExe(SEGGER,未安装) |
|---|---|---|
| 复位并运行 | `-c SWD -Rst -Run` | `-device STM32F407xG -if SWD -speed 4000 -reset -go` |
| 复位停核 | `-c SWD -Rst -Halt`(ⓞ 必须显式 `-Halt`) | `... -resetHalting` |
| nRST 脉冲 | ❌ 本机不可用(nRST 未接线 + v3.5.0 不支持 `RM=`) | 需 nRST 接线 + J-Link 引脚控制脚本 |
| 烧写并运行 | `-c SWD -P x.hex -Rst -Run`(实测 6.5s/1MB) | `-loadfile x.axf -reset -go` |
| 运行中检查 | `-c SWD HOTPLUG -SCore` | 需先 `-noReset` 连接或用 GDBServer |
## 9. 上板实测记录(2026-09-19)
- 目标:STM32F407ZGTx(CPUID 0x413,Flash 1MB),V2 CPU 板
- 探针:ST-LINK/V2,FW **V2J37S7**,SN `0B250D12A218303030303032`;**接线 3 根(SWDIO/SWCLK/GND),nRST 未接**
- VDD 实测 **3.136V**(偏低,正常 3.3V——当前走 PC 端口供电,长期/大电流场景建议改 5V 供电)
- 串口 **COM7** @115200(板子重插后重新枚举,`serial_config.json` 已同步)
- 板内固件:测试前半段为较早的 ui-research 线构建(引脚集未知);13:59 起为 **v2-on-ui 构建(ui-research + V2 引脚补丁,10:03 编译)**
| # | 时间 | 命令 | 结果 |
|---|---|---|---|
| 1 | 13:40 | `-List` | ✅ 识别探针(V2 / V2J37S7 / SN 如上) |
| 2 | 13:41 | `-c SWD HOTPLUG -SCore` | ✅ `Core is Running`(连接不扰运行中目标) |
| 3 | 13:41 | `-c SWD HOTPLUG -R32 0x08000000 4` | ✅ 首字=0x2001E8B8(192K SRAM 的 IRAM2 区)→ Flash 程序有效 |
| 4 | 13:41 | `-c SWD HOTPLUG -TVolt` | ✅ 3.136V |
| 5 | 13:43~13:55 | `-c SWD -Rst -Run`(多次,含 `reset.bat` 默认分支) | ✅ 每次均重启成功:`App init OK` / `Network Init` / `net init: OK` 齐备,PHY 100M FULL,UI port/menu init OK,0 条 FAIL/ERROR/HardFault |
| 6 | 13:44 | `-c SWD -Rst -SCore` | ⓞ 复位后核为 `Running`(不停核)→ 停核必须加 `-Halt` |
| 7 | 13:44 | `-c SWD -Rst -Halt -SCore -CoreReg` | ✅ 停核:SP=0x2001E8B8、PC=0x08004664(启动代码中段)、xPSR=0x21000000 |
| 8 | 13:45 | `-c SWD RM=Hrst -HardRst PULSE=100`(4 种语法排列) | ❌ v3.5.0.0 全部拒 `RM=`(`Unknown debug protocol or option`)→ CLI 层无 nRST 能力(且本机 nRST 未接线) |
| 9 | 13:4x | `reset.bat list / (默认)/ hard / halt / run` | ✅ 全分支 exit=0;`hard` 分支按设计回退软件复位(RESET_NOTE);`halt` 断开后核自动恢复运行 |
| 10 | 13:59 | `reset.bat flash`(= `-P <hex> -Rst -Run`) | ✅ `.hex` 直接支持:**1MB 编程 6.5s**,`Programming Complete` → `MCU Reset` → `Application started`,exit=0 |
| 11 | 13:59 | 烧录后启动观察 | ⚠️ **V2 引脚固件启动异常**:日志到 `[APP] RS485 init: OK` 后中断(无 GD5F/TPAFE/存储/UI 后续日志,无二次重启);核状态回读:`Core is Running`,**PC=0x08000FA0**(启动区死循环,LR=0x08000FA5,SP 正常推进)→ 疑似 v2-on-ui 构建的启动阶段问题,**排查中**(待办:反汇编该地址 + 对比 V1 引脚构建行为) |
**结论**:
1. **命令行复位成立**:`ST-LINK_CLI -c SWD -Rst -Run` = 板子重启(多次实测全部成功、开机日志完整)——这就是"命令控制板子重启",3 线接线完全够用。
2. **本机复位能力 = 软件系统复位**:nRST 未接线 + v3.5.0 CLI 不支持 `RM=`,nRST 引脚级操作不可用(`reset.bat hard` 自动回退,不影响脚本闭环);需要时补 nRST 线 + 升级工具链。
3. 停核 = `-Rst -Halt`(停点不保证是复位向量,实测 0x08004664);一次性连接语义——断开即恢复运行。
4. **烧录路径打通**:`-P <hex>` 实测可用(1MB ≈ 6.5s,比 UV4 快得多),`reset.bat flash` 可作为快速烧录通道。
5. ⚠️ **发现新问题**:v2-on-ui(V2 引脚)固件在本板上启动卡死(PC=0x08000FA0),旧固件正常——与 ST-LINK 无关,属固件/引脚配置问题,另行排查(见 `docs/问题记录/` 后续条目)。