OpenOCD Raspberry pi Bit Bang SWD 无法连接 DP 并读取 IDR
结论
USB device firmware 通常不会直接导致 SW-DP 消失。STM32F407 的 USB FS 使用 PA11/PA12,SWD 使用 PA13/PA14。OpenOCD 读取调试端口的 DPIDR 时,Flash 中的应用代码还没有执行。
ST-Link 可以正常连接,但 mass erase 后 Raspberry Pi GPIO Bit Bang 仍然读不到 DP,问题更可能出在 Raspberry Pi 端,包括 SWD 时序、GPIO 方向切换、复位控制和信号完整性。Wrong Parity Error 也符合这类故障的特征:OpenOCD 收到了响应,但采样的数据位或校验位有误。
有一种情况需要单独考虑。如果程序启动后立即重配置 PA13/PA14、进入低功耗模式或关闭调试功能,普通 attach 可能失败,通常可以通过 connect-under-reset 连接。整片擦除后如果故障依旧,应先检查 Bit Bang 接口。
ST-Link 能用,GPIO Bit Bang 不能用的原因
ST-Link 内部有专用调试硬件,可以可靠处理 SWDIO 双向切换、turnaround 周期、复位时序和信号采样。Raspberry Pi GPIO Bit Bang 依靠软件控制 GPIO,更容易受以下问题影响:
- SWCLK 频率过高,目标端或 Raspberry Pi 无法稳定采样。
- SWDIO 在读写切换时未及时释放,导致主机和目标同时驱动总线。
- OpenOCD、Linux 内核或 Raspberry Pi 型号变化后,原来的 GPIO 时序参数不再适用。
reset_config与实际的 NRST 接线不匹配。- SWDIO、SWCLK 没有合适的上拉或下拉,空闲电平不稳定。
- 线缆过长、接地不良、供电噪声,或者接入 USB 后地电位发生变化。
- Raspberry Pi GPIO 电平超出允许范围。GPIO 只能使用 3.3 V 逻辑,不能承受 5 V。
- SWDIO 引脚编号、GPIO 模式或 peripheral base 配置不适用于当前 Raspberry Pi 型号。
- 后台进程、内核驱动或 GPIO overlay 占用了相同的 GPIO。
mass erase 只能清除 MCU Flash,无法解决这些接口层问题。
先降低 SWD 时钟
排查 Bit Bang SWD 时,先降低 adapter speed。可用范围取决于 OpenOCD 版本和 Raspberry Pi GPIO driver,配置值不一定等于实际的 SWCLK 频率。
先从较低的值开始测试:
transport select swd
adapter speed 50
如果仍然失败,再继续降低:
adapter speed 10
启动命令可以参考下面的示例,其中接口配置文件需要替换为当前实际使用的文件:
openocd \
-d3 \
-f interface/raspberrypi-native.cfg \
-c "transport select swd" \
-c "adapter speed 50" \
-f target/stm32f4x.cfg
部分 OpenOCD 版本已经修改了 Raspberry Pi GPIO driver 的名称和参数。如果配置文件来自较早的安装版本,应与当前版本附带的 interface/ 配置核对,重点检查 GPIO 编号、Raspberry Pi 型号和速度校准参数。
使用 connect-under-reset
如果 USB 固件启动后修改了 SWD 引脚、时钟或低功耗状态,应在 MCU 执行用户代码前保持 NRST 有效。
这种方式要求 Raspberry Pi 已经连接 STM32 的 NRST:
reset_config srst_only srst_nogate connect_assert_srst
然后尝试运行:
openocd \
-d3 \
-f interface/raspberrypi-native.cfg \
-c "transport select swd" \
-c "adapter speed 50" \
-c "reset_config srst_only srst_nogate connect_assert_srst" \
-f target/stm32f4x.cfg \
-c "init; reset halt"
没有连接 NRST 时,无法使用依赖硬件复位的连接方式。可以手动拉低 NRST,启动 OpenOCD 后再释放 NRST,以此判断用户程序是否抢占了 SWD 引脚。
整片擦除后,MCU 中已经没有可执行的用户程序。此时如果 Raspberry Pi 仍然读不到 DP,而 ST-Link 可以正常连接,基本可以排除 USB firmware。
检查 SWDIO 双向切换
SWDIO 是双向信号。主机发出请求后,要在 turnaround 周期释放 SWDIO,再由目标返回 ACK 和数据。如果 GPIO Bit Bang driver 释放过晚、读取过早或 GPIO 方向配置错误,可能出现以下报错或现象:
Error connecting DPcannot read IDRWrong ACKWrong Parity Error- 读取结果全为
0或全为1
Wrong Parity Error 表示收到的 32 位数据与 parity bit 不匹配,与 STM32 Flash 内容是否损坏无关。常见原因包括信号边沿不干净、采样时刻错误,以及 turnaround 期间的总线争用。
如果手边有逻辑分析仪或示波器,可以同时观察 SWCLK、SWDIO 和 NRST,检查以下内容:
- SWD line reset 是否发送了至少 50 个 SWCLK 周期的高电平。
- JTAG-to-SWD sequence 是否完整。
- 请求包发送后,Raspberry Pi 是否及时释放 SWDIO。
- 目标返回的 ACK 是否为
001,也就是 SWD 协议定义的OK。 - 数据阶段是否有毛刺、缓慢边沿或两个器件同时驱动造成的中间电平。
不要只根据普通逻辑分析仪的协议解码结果下结论。采样率不够时,分析仪本身也可能漏掉毛刺。
重新检查硬件连接
导线没有断路,不代表信号质量一定正常。可以按照下面的最小连接重新测试:
Raspberry Pi STM32F407
------------ ---------
GND -> GND
GPIO for SWCLK -> PA14 / SWCLK
GPIO for SWDIO <-> PA13 / SWDIO
GPIO for NRST -> NRST (推荐)
3.3 V sense -> VDD (仅在接口设计需要时)
同时检查以下事项:
- Raspberry Pi 和目标板必须共地。
- SWDIO、SWCLK 导线应尽量短,避免使用接触不良的杜邦线。
- 不要将 Raspberry Pi GPIO 直接接到 5 V 信号。
- 确认 Raspberry Pi 和 STM32 没有同时向对方供电。
- 检查接入 USB 数据线后,是否形成了第二条地线或供电回路。
- 测量目标板的 3.3 V,确认连接 USB 后没有明显的电压跌落或纹波。
- 确认没有外设占用
PA13/PA14,外部电路也没有强拉这两个引脚。
可以尝试给 SWDIO 增加弱上拉,但阻值需要结合现有板级电路确定。电阻过小会强拉 SWDIO,增加目标返回数据时的负载。
核对 Raspberry Pi GPIO 配置
先确认配置文件使用的是 BCM GPIO 编号还是物理排针编号。两者混用时,可能偶尔能收到响应,但数据并不可靠。
旧式配置可能包含类似内容:
adapter driver bcm2835gpio
bcm2835gpio swd_nums <SWCLK_GPIO> <SWDIO_GPIO>
占位符需要替换为实际的 BCM GPIO 编号:
bcm2835gpio swd_nums 25 24
这里的 25 和 24 只是语法示例,不表示当前接线应该使用这两个 GPIO。不同 OpenOCD 版本对 Raspberry Pi GPIO driver、参数名称和 Raspberry Pi SoC 地址的处理可能不同,应以本机安装版本附带的配置文件为准。
还要检查 GPIO 是否被其他功能占用:
gpioinfo
如果系统没有安装提供 gpioinfo 的工具,可以检查设备树 overlay,以及 SPI、I2C、UART、PWM 和其他 GPIO 服务是否占用了相同引脚。
获取有效的 OpenOCD 调试日志
以较高的日志级别运行 OpenOCD:
openocd \
-d3 \
-f interface/raspberrypi-native.cfg \
-c "transport select swd" \
-c "adapter speed 50" \
-f target/stm32f4x.cfg
排查时记录以下信息:
- OpenOCD 的完整版本号和构建来源。
- Raspberry Pi 型号及操作系统版本。
- 当前使用的 interface 配置文件。
- SWCLK、SWDIO、NRST 对应的 BCM GPIO 编号。
adapter speed。- 接入 USB 前后的完整日志差异。
- ST-Link 成功连接时是否使用了 under-reset 模式。
如果近期升级过 OpenOCD、操作系统或 Raspberry Pi 硬件,需要检查接口 driver 是否发生变化。即使应用固件也在同一时间修改过,时间上的先后关系仍不足以证明 USB firmware 是故障原因。
建议的排查顺序
- 用 ST-Link 确认 MCU、SWD 引脚和 option bytes 正常。
- 执行 mass erase,然后断电重启目标板。
- 暂时断开 USB,只保留电源、GND、SWCLK、SWDIO 和 NRST。
- 将
adapter speed降到50或更低。 - 使用 connect-under-reset。
- 核对 BCM GPIO 编号和当前 OpenOCD 接口配置。
- 换用短线,并测量 SWCLK、SWDIO 和 3.3 V。
- 用示波器检查 SWDIO turnaround 和数据采样。
- 如果仍然失败,用相同接线测试另一块 STM32 板,或者用当前目标板测试另一台 Raspberry Pi,以区分目标板故障和主机接口故障。
从这些现象看,Wrong Parity Error 的诊断价值高于 USB 软件的影响。这个错误说明链路已经部分连通,但 Raspberry Pi Bit Bang 接口没有稳定接收到正确的 SWD 数据。应先降低速度,再检查 SWDIO 方向切换和复位时序,通常比反复擦除 Flash 更有效。
备注:内容仅供参考。
