数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 77|回复: 2

[ARM] 用 pyOCD 与 Cortex-Debug 在挂机异常后连接 MCU 查看现场

[复制链接]
发表于 昨天 14:04 | 显示全部楼层 |阅读模式
本帖最后由 创天蓝 于 2026-7-28 14:05 编辑

用 pyOCD 与 Cortex-Debug 在挂机异常后连接 MCU 查看现场
几十台产品需要长期挂机,异常可能数小时或数天后出现。每台一直挂调试器不现实,启动调试还可能复位目标。设备平时独立运行,出现停转、卡死或状态异常后,再通过 SWD 暂停 MCU 查看现场。



Reset 与现场边界
常规 Launch 调试会让程序从复位入口重新开始:
  1. Reset -> Reset_Handler -> SystemInit -> main
复制代码
现场连接需要保留当前执行位置:
  1. 异常位置 -> SWD 连接 -> Debug Halt -> 读取 CPU 状态
复制代码
一旦执行 Reset,PCSP、调用栈和外设状态都会发生变化,故障现场也随之改变。

目标中的固件与本地 ELF 必须来自同一次构建。executable 只用于加载 ELF 符号,把地址映射到函数、源码和变量;现场调试不要执行 GDB 的 load 命令。load 会进入 Flash 编程流程,可能执行擦除、写入或复位,直接改变现场。ELF 与设备固件不一致时,调用栈和变量显示可能失真。

这套方法保存的是“调试器暂停 MCU 那一刻”的状态。若看门狗已经复位设备,或程序继续运行并覆盖了故障栈,原始现场无法靠延迟连接恢复。



Cortex-Debug Attach 配置
Cortex-Debug 应使用 request: "attach"。它跳过 Launch 模式默认的下载和启动流程,不会主动把设备重新运行到 main。自定义 GDB 命令、启动脚本和 GDB Server 仍可能触发 Reset,使用前需要逐项检查。
  1. {
  2.   "name": "MCU Attach (pyOCD)",
  3.   "type": "cortex-debug",
  4.   "request": "attach",
  5.   "cwd": "${workspaceFolder}",
  6.   "servertype": "pyocd",
  7.   "targetId": "TARGET_ID",
  8.   "executable": "./build/firmware.elf",
  9.   "cmsisPack": "./pack/Vendor.Device.pack",
  10.   "svdFile": "./svd/device.svd",
  11.   "serverArgs": [​
  12.     "-O",
  13.     "connect_mode=attach"
  14.   ​],
  15.   "overrideGDBServerStartedRegex": "GDB server listening on port"
  16. }
复制代码
当前版本的 Cortex-Debug 无法识别新版 pyOCD 的启动输出,需要用 overrideGDBServerStartedRegex 指定成功日志。否则 pyOCD 已监听端口,Cortex-Debug 仍可能停在等待启动。

异常出现后,在 VS Code 中启动这项配置。connect_mode=attach 只控制 pyOCD 初始化阶段,此时 pyOCD 不主动暂停 CPU。

本机 pyOCD 0.44.1 会在 GDB 接入时调用 halt(),所以此版本冻结点位于 GDB 连接阶段;其他版本请以启动日志为准。



Attach 与 Halt 的冻结时机
状态仍在快速变化时,等待 GDB 完成连接可能太晚。把连接模式改成 halt,pyOCD 会在 GDB Server 初始化期间暂停内核。
  1. "serverArgs": [​
  2.   "-O",
  3.   "connect_mode=halt"
  4. ​],
  5. "overrideGDBServerStartedRegex": "GDB server listening on port"
复制代码
暂停由 Cortex-M 调试硬件完成,CPU 无需运行到某个暂停函数。概念链路如下:
  1. SWD -> DAP -> DHCSR.C_HALT -> CPU 停止
复制代码
两种模式都配合 Cortex-Debug 的 request: "attach" 使用:

pyOCD 模式暂停时机使用场景
attachGDB 客户端接入时状态稳定
haltpyOCD 连接目标时状态变化快


独立 GDB Server 提前冻结
需要先冻结、后打开 VS Code 时,可以运行一次性脚本。它用 halt 启动 pyOCD GDB Server,冻结 MCU 后等待 GDB 接入。
  1. @echo off
  2. pyocd gdbserver --pack .\pack\Vendor.Device.pack -t TARGET_ID -O connect_mode=halt
  3. pause
复制代码
VS Code 使用外部 GDB Server,并继续采用 request: "attach"
  1. {
  2.   "name": "MCU External Attach",
  3.   "type": "cortex-debug",
  4.   "request": "attach",
  5.   "servertype": "external",
  6.   "gdbTarget": "localhost:3333",
  7.   "executable": "./build/firmware.elf",
  8.   "svdFile": "./svd/device.svd"
  9. }
复制代码
脚本只启动一次。参数错误或 GDB Server 退出后,pause 会保留错误信息,避免快速重复启动 pyOCD。

几十台设备可以继续独立挂机,调试探针只接到发生异常的设备上。halt 负责尽早冻结,Cortex-Debug 负责把寄存器、源码和变量组织成可读现场。




build 28 July 2026 14:03 (UTC+8)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 1家元 +15 收起 理由
不长叶子的树 + 15

查看全部打赏

发表于 昨天 22:09 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|数码之家-技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2026-7-29 03:46 , Processed in 0.218400 second(s), 7 queries , Gzip On, Redis On.

Powered by Discuz!

© MyDigit.Net Since 2006

快速回复 返回顶部 返回列表