STM32使用Jlink下载时 "Can not attach to CPU" 调试笔记
现象:J-Link 能识别 SW-DP (ID 0x2BA01477),但无法挂载 CPU 核心,RTT Viewer 和 J-Link Commander 均连接失败。长按复位键后恢复正常。
环境
| 项目 | 详情 |
|---|---|
| MCU | STM32F411RET6 (Cortex-M4F, 100MHz) |
| 调试器 | J-Link V11, SWD 接口 |
| 工具链 | arm-none-eabi-gcc 15.2.1, CMake, FreeRTOS V11.3.0 |
| 固件 | IAP Bootloader (Ymodem), 纯轮询架构, 100MHz 全速运行 |
| 硬件 | 最小系统板, BOOT0 硬接地, NRST 未接 J-Link |
症状
LOG: Found SW-DP with ID 0x2BA01477
LOG: STM32 (connect): Can not attach to CPU. Trying connect under reset.
LOG: Found SW-DP with ID 0x2BA01477
ERROR: STM32: Connecting to CPU via connect under reset failed.
ERROR: Could not connect to target device.
- J-Link 可以读取 SW-DP ID 寄存器(物理 SWD 连接正常)
- 无法访问 AHB-AP(CPU 调试访问端口)
- "connect under reset" 也失败(NRST 引脚未连接)
排查过程
第一步:排除代码显式禁用
全面审查 IAP 固件源码:
| 排查项 | 结果 |
|---|---|
| PA13/PA14 复用为 GPIO | 未发生 |
| RDP 读保护 | Level 0 (未开启) |
| 低功耗模式 (Sleep/Stop/Standby) | 未进入 |
| DBGMCU 调试寄存器修改 | 未发生 |
| __WFI / __WFE | 无调用 |
| HAL_PWR_EnterSTOPMode | 无调用 |
固件没有显式禁用 SWD。
第二步:电路检查
- VTref = 3.314V,供电正常
- SWDIO、SWCLK、GND 连通性正常
- BOOT0 硬接地 — 无法进入系统 Bootloader 模式
- NRST 未接 J-Link Pin 15 — "connect under reset" 不可用
第三步:固件行为分析
IAP Bootloader 的主循环:
// 当没有有效 APP 时, CPU 死循环在此
while (1) {
printf("run in boot while(1)\r\n"); // 阻塞轮询 UART TX
printf("there is no legal APP\r\n"); // 阻塞轮询 UART TX
HAL_Delay(500); // 轮询 SysTick uwTick 变量
Power_DisEnable(); // GPIO 操作
}
整个固件没有使用任何中断驱动 I/O,所有 UART 收发均为阻塞轮询,CPU 以 100MHz 持续运转。
第四步:根因确认
用 J-Link Commander 配合上电时序抢占验证:
# 先拔掉目标板电源
# 终端准备好连接命令
$ JLink.exe -device STM32F411RE -if SWD -speed 100 -autoconnect 1
# 回车启动扫描的同时立刻给目标板上电
# → 连接成功
抢占窗口约 5-10ms(从上电到 main() 执行),在此窗口内 AHB 总线空闲,J-Link 可正常 attach。
根因
AHB 总线竞争,而非 SWD 被禁用。
┌─────────────┐ SWD (物理层) ┌──────────────┐
│ J-Link │ ◄──────────────────► │ STM32F411 │
│ │ SW-DP 响应 ✓ │ │
│ halt请求 → │ AHB-AP 无响应 ✗ │ CPU @100MHz │
│ │ │ 全速轮询 │
└─────────────┘ │ AHB 持续占用 │
└──────────────┘
- SW-DP(调试端口)是独立于 CPU 的硬件模块,始终可访问
- AHB-AP(访问端口)需要通过 AHB 总线矩阵访问 CPU 核心
- J-Link 发起 halt 请求时,需要在 AHB 总线上获得仲裁时隙
- 纯轮询固件以 100MHz 持续访问 Flash 和 UART 寄存器,AHB 总线几乎无空闲
- J-Link 的 SWD 时钟(4MHz)相对较慢,在总线竞争中长期抢不到窗口 → 超时
按复位键后,CPU 停在 Reset_Handler,AHB 空闲 → J-Link 立即可连。
解决方案
临时方案:上电时序抢占
断电 → 启动 J-Link 扫描 → 立即上电 → 抢占成功 → erase → 烧新固件
适用于紧急恢复,可能需要多次尝试。
永久方案一:接 NRST(推荐)
J-Link Pin 15 → STM32 Pin 7 (NRST),一根飞线即可。之后 connect under reset 正常工作,无论固件状态如何都能强制连接。
永久方案二:避免纯轮询架构
在固件空闲路径中使用 __WFI() 或 RTOS 的空闲任务(vApplicationIdleHook 中执行 __WFI())。FreeRTOS 默认在 idle task 中调用 __WFI(),AHB 总线有充足的空闲窗口供调试器访问。
教训
- SWD 连接失败 ≠ 接口被禁用。 先检查固件的总线占用模式,再怀疑 RDP 或 GPIO 复用。
- NRST 线建议永远接上。 它是在固件失控时唯一的硬件级恢复通道,成本仅一根飞线。
- BOOT0 不要硬接地。 留一个跳线或按键,在 RDP 意外开启时还能通过系统 Bootloader 擦除。
- 调试受阻时先分析固件行为,而非硬件。 VTref 正常 + SW-DP 可读 = 硬件链路大概率正常。
快速诊断流程图
J-Link 连接失败
│
├─ 能读到 SW-DP ID?
│ ├─ 否 → 检查 SWD 接线 / 供电
│ └─ 是 ↓
│
├─ 按复位键后能连?
│ ├─ 是 → AHB 总线竞争(本文场景)
│ │ ├─ 接 NRST(永久修复)
│ │ └─ 固件空闲路径加 __WFI()
│ │
│ └─ 否 ↓
│
├─ BOOT0 拉高 + 复位后能连?
│ ├─ 是 → 固件可能禁用了 SWD
│ │ └─ 擦除旧固件,烧新固件
│ │
│ └─ 否 ↓
│
└─ 可能原因:RDP 已开启、芯片损坏
├─ RDP Level 1 → 系统 Bootloader mass erase
└─ RDP Level 2 → 无解,换芯片
2026-06-29, STM32F411RET6 / J-Link / FreeRTOS / RTT

浙公网安备 33010602011771号