1. 最终问题?

这次遇到的问题,在只使用IDE生成的最初的代码下遇到:

Windows 能识别 ST-LINK,但 STM32CubeIDE 默认使用的 ST-LINK GDB Server 无法顺利启动调试。

最后通过把 CubeIDE 的调试后端从:

ST-LINK (ST-LINK GDB server)

改成:

ST-LINK (OpenOCD)

成功建立了:

电脑
 ↓
OpenOCD
 ↓
ST-LINK V2
 ↓ SWD
STM32L011

最终程序成功下载,并停在:

main.c:76
地址:0x08000224

整个 SWD 调试链路最后正常使用。


2. 先理解整个调试链路

“ST-LINK” 并不是只是一个东西,其实整个调试过程有好几层。

STM32CubeIDE
    │
    │ GDB
    ▼
调试服务器
    │
    ├──────── ST-LINK GDB Server
    │
    └──────── OpenOCD
                  │
                  ▼
             USB驱动
                  │
                  ▼
             ST-LINK硬件
                  │
                  │ SWD
                  ▼
             STM32 MCU

也就是说:

ST-LINK —— 硬件调试器

ST-LINK USB Driver —— Windows 用来识别它的驱动。

ST-LINK GDB Server —— ST 官方的一套调试后端。

OpenOCD —— 另一套调试后端,同样可以控制 ST-LINK。

GDB 则是CubeIDE 用来做:

断点
单步
变量查看
寄存器查看

的调试器。

所以:ST-LINK 硬件正常,不代表 ST-LINK GDB Server 一定正常。

这就是这次容易误判的地方。


3. 第一个现象:CubeIDE 报 No ST-LINK detected

最开始 Debug 时出现:

No ST-LINK detected!
Please connect ST-LINK and restart the debug session.

开始容易认为:

ST-LINK坏了
或者
SWDIO/SWCLK没接好

但其实这是不准确。因为:

No ST-LINK detected

意味着问题发生在:

电脑
 ↓
ST-LINK

还没有走到:

ST-LINK
 ↓
STM32

所以这时:

PA13 SWDIO
PA14 SWCLK
NRST
STM32代码
NFC

都不是优先排查对象。


4. Windows 设备管理器其实能看到 ST-LINK

进入:

设备管理器
→ STM32 STLink
→ 属性
→ 详细信息
→ 硬件 ID

读到了:

USB\VID_0483&PID_3748

其中:

VID_0483

是 STMicroelectronics。

PID_3748

对应 ST-LINK/V2 这一类设备。

所以至少可以证明:

电脑USB
 ↓
ST-LINK设备

已经枚举成功

Windows 并不是完全看不到它。


5. 设备实例路径不是 ST-LINK 序列号

还看到:

USB\VID_0483&PID_3748\6&1562FF49&0&3

这里非常容易犯错误。

最后:

6&1562FF49&0&3

是 Windows 的:

设备实例路径

不是 ST-LINK 的真实 Serial Number。

所以不能把它填到 CubeIDE:

使用特定的 ST-Link 序列号

里面。


6. 驱动也存在一个疑点

设备管理器看到:

驱动程序提供商:
STMicroelectronics

驱动版本:
2.1.0.0

日期:
2017/6/8

说明驱动确实是 ST 的,但是很老。

因此尝试了 CubeIDE 自带的:

STM32CubeIDE
└─ drivers
   └─ STLinkUSBDriver

其中有:

dpinst_amd64.exe
dpinst_x86.exe
stlink_winusb_install.bat

这里的经验是:

设备管理器能看到 ST-LINK,不代表 CubeIDE 的 GDB Server 一定能正确访问。

但也不能看到旧驱动就直接认定一定是驱动导致。

必须继续分层验证。


7. 找到 CubeIDE 自带的 ST-LINK GDB Server

CubeIDE 自身已经带:

ST-LINK_gdbserver.exe

路径类似:

STM32CubeIDE
└─ plugins
   └─ com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server...
      └─ tools
         └─ bin
            └─ ST-LINK_gdbserver.exe

于是进入 PowerShell。执行:

.\ST-LINK_gdbserver.exe --help

执行成功后,打印出了 GDB Server 的所有参数。

这说明:

ST-LINK GDB Server程序本身
✅ 能正常启动

8. 用 -q 扫描 ST-LINK

帮助中有:

-q, --debuggers
List serial number for connected ST-LINK devices

于是执行:

.\ST-LINK_gdbserver.exe -q

结果却报:

ERROR: Couldn't locate STM32CubeProgrammer
in '..\..\STM32CubeProgrammer\bin\',
use -cp <path>

这一步非常关键。

它说明:不是 ST-LINK 一定不存在。

是因为:ST-LINK GDB Server 在扫描探针之前,就因为找不到 CubeProgrammer 的组件失败了。


9. 找到 CubeProgrammer CLI

虽然没有单独安装 STM32CubeProgrammer GUI,但是 CubeIDE 自己带有 CLI 组件。

路径类似:

STM32CubeIDE
└─ plugins
   └─ com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer...
      └─ tools
         └─ bin

然后给 GDB Server 明确指定:

.\ST-LINK_gdbserver.exe -q -cp "H:\...\cubeprogrammer...\tools\bin"

这一次终于输出:

ST-LINK: E10072000D0D2139393740544

这才是真正的:

ST-LINK Serial Number / ID

所以这一刻已经可以确认:

Windows
 ↓
USB驱动
 ↓
CubeProgrammer CLI
 ↓
ST-LINK GDB Server
 ↓
ST-LINK

✅ 能够被枚举

10. 为什么 CubeIDE 默认还是调试失败?

继续使用:

ST-LINK (ST-LINK GDB server)

Debug 时,CubeIDE 弹出:

This version of STM32CubeIDE provides a newer firmware version
of the attached ST-LINK.
Proceed with update?

也就是说:

CubeIDE 认为当前 ST-LINK 固件版本太旧,需要升级。

但是打开:

STLinkUpgrade

以后却显示:

ST-Link ID:
E10072000D0D2139393740544

Current Firmware:

Type:

Version: Unknown

Update to Firmware: Unknown

这就是第二个非常重要的异常。

正常 ST-LINK 通常应该能看到:

Type: ST-LINK/V2
Version: V2JxxSx

但这个设备:

Version = Unknown

说明升级工具无法正确识别它的固件信息。

可能原因包括:

固件过旧
非标准固件
兼容/克隆 ST-LINK
固件信息异常

11. 为什么没有强制升级?

这是一个很重要的经验。

看到:

Version: Unknown

时,不应该贸然:

Upgrade

特别是淘宝、国产兼容 ST-LINK/V2。

因为一些兼容版本:

USB VID/PID

可以模仿官方 ST-LINK:

0483:3748

但内部固件不一定是完全兼容的官方版本。

强行更新可能导致:

ST-LINK变砖
USB无法识别
无法继续烧录

所以采取的策略是:

先不升级硬件固件,换调试后端。


12. 为什么最后改成 OpenOCD?

CubeIDE 默认的:

ST-LINK GDB Server

在我们的环境中存在两层麻烦:

第一层:
需要正确找到 CubeProgrammer CLI

第二层:
又要求检查/升级 ST-LINK Firmware

而当前 ST-LINK:

Firmware Version = Unknown

所以继续硬搞 ST 官方 GDB Server 没有太大意义。

于是换成:

ST-LINK (OpenOCD)

架构变成:

CubeIDE
 ↓
GDB
 ↓
OpenOCD
 ↓
ST-LINK
 ↓
SWD
 ↓
STM32L011

OpenOCD 不走刚才那套固件升级检查流程。


13. OpenOCD 怎么配置?

进入:

Run
→ Debug Configurations
→ nfc Debug
→ 调试器

选择:

调试探头:
ST-LINK (OpenOCD)

然后:

Configuration Script:
Automated Generation

不需要自己写 .cfg

Generator Options:

Interface:
SWD

Frequency:
240 kHz

最开始建议低速。

不是因为 I²C 是 100 kHz。

这里的 240 kHz 指的是:

ST-LINK ↔ STM32 的 SWD 调试时钟。

和:

I²C速度
CPU速度
NFC速度

都没有直接关系。

Reset:

Software system reset

SWV:

Disabled

RTOS Proxy:

Disabled

14. OpenOCD 第一次真正连上以后看到了什么?

Console 输出:

Info : STLINK V2J37S7 (API v2) VID:PID 0483:3748

这一行非常重要。

它说明 OpenOCD 实际已经可以识别出:

ST-LINK V2
Firmware:
V2J37S7

这也说明:

ST-LINK 本身并非完全无法工作。

只是 STLinkUpgrade 的识别机制和当前固件之间存在兼容性问题。


然后:

Info : Target voltage: 3.246215

说明 STM32 板:

VDD ≈ 3.25V

供电正常。

Info : SWD DPIDR 0x0bc11477

说明:

ST-LINK
 ↓
SWDIO/SWCLK
 ↓
ARM Debug Port

已经通信成功。

Info : Cortex-M0+ r0p1 processor detected

说明 CPU 被正确识别。

Info : STM32L flash size is 16kb

说明芯片 Flash 也被正确识别:

STM32L011F4
Flash = 16KB

15. 最终什么才是真正 Debug 成功?

最后 CubeIDE Debug Perspective 左上角出现:

Thread #1 (Suspended : Breakpoint)

main() at main.c:76
0x08000224

其中:

0x08000224

是非常关键的信息。

STM32 内部 Flash:

起始地址 = 0x08000000

现在 CPU:

PC = 0x08000224

说明正在执行 Flash 里的合法程序。

而且:

main() at main.c:76

说明:

启动代码
 ↓
Reset_Handler
 ↓
SystemInit()
 ↓
main()

都已经跑通。

所以至此:

编译              ✅
下载ELF           ✅
烧入Flash         ✅
Reset             ✅
SWD               ✅
断点               ✅
main()             ✅

整个环境彻底正常。


16. 这次最大的坑是什么?

最大的坑不是某一个错误,而是:

没有一开始把整个调试系统按层次拆开。

错误排查应该永远按照:

电脑USB
 ↓
ST-LINK设备
 ↓
驱动
 ↓
调试服务器
 ↓
SWD
 ↓
MCU
 ↓
Flash程序
 ↓
main()

一级一级排。

而不是看到:

Debug失败

就马上怀疑:

STM32代码错了
SWD接反了
芯片坏了

17. 如何根据错误判断是哪一层出问题?

这是最值得教给别人的部分。

情况 1

设备管理器都没有 STM32 STLink

查:

USB接口
USB线
Windows驱动
ST-LINK硬件

不要查 STM32。


情况 2

设备管理器有:

VID_0483
PID_3748

但 CubeIDE:

No ST-LINK detected

查:

ST-LINK驱动
GDB Server
CubeProgrammer路径
ST-LINK兼容性

不要先查 SWDIO。


情况 3

能找到 ST-LINK 序列号,但是:

No target found

此时才查:

STM32有没有3.3V
GND有没有共地
SWDIO
SWCLK
NRST
MCU焊接

情况 4

OpenOCD显示:

SWD DPIDR 0x...
Cortex-M0+ detected

意味着:

ST-LINK
 ↓
STM32

已经通

这时不要再折腾驱动。


情况 5

显示:

Flash size is 16kb

说明 MCU 基本已经完全被识别。


情况 6

最后停在:

main() at main.c
0x0800xxxx

说明:

整个下载调试环境全部正常。


18. 在遇到ST-LINK出现问题时

Step 1:设备管理器

确认:

STM32 STLink

记录:

VID
PID

不要把:

Device Instance Path

当 Serial Number。


Step 2:CubeMX 保留 SWD

必须:

SYS
→ Debug Serial Wire

于是:

PA13 = SWDIO
PA14 = SWCLK

Step 3:硬件连接

ST-LINK            STM32

SWDIO  ────────── PA13
SWCLK  ────────── PA14
GND    ────────── GND
VTref  ────────── 3.3V

推荐再接:

NRST   ────────── NRST

Step 4:优先尝试正常 ST-LINK GDB Server

如果:

ST-LINK (ST-LINK GDB server)

正常:

直接用,不需要 OpenOCD。


19. 什么情况下直接考虑 OpenOCD?

如果出现:

Windows能识别ST-LINK

但是CubeIDE官方GDB Server
不断要求Firmware升级

而升级器又显示:
Version Unknown

这时不要继续死磕。

直接试:

ST-LINK (OpenOCD)

特别是:

老ST-LINK/V2
兼容ST-LINK/V2
Clone ST-LINK

OpenOCD 往往更宽容。


20. OpenOCD 第一次建议低速

第一次连接不要:

4000 kHz
8000 kHz

直接:

240 kHz
480 kHz

成功以后再提高。

对 16KB Flash 的 L011:

240k

烧录已经足够快。

稳定比速度重要。


21. 不要随便升级 Unknown Firmware

这是这次非常值得保留的一条经验。

如果升级器显示:

Version: Unknown
Update to Firmware: Unknown

不要因为 CubeIDE 写着:

Firmware update required

就直接点 Upgrade。

先判断:

是不是官方ST-LINK
是不是兼容版
OpenOCD能不能正常用

如果 OpenOCD:

STLINK V2J37S7
SWD DPIDR
Cortex-M0+

全部正常,那这个调试器当前其实是可用的。

没有必要为了“升级”冒着刷坏的风险。


22. 这次完整问题链可以浓缩成

CubeIDE Debug
      ↓
No ST-LINK detected
      ↓
设备管理器检查
      ↓
0483:3748
ST-LINK/V2 已被Windows识别
      ↓
检查 ST-LINK GDB Server
      ↓
程序可以运行
      ↓
执行 -q
      ↓
找不到 STM32CubeProgrammer
      ↓
手动加 -cp 路径
      ↓
成功得到 ST-LINK ID
      ↓
CubeIDE官方GDB Server继续要求升级Firmware
      ↓
STLinkUpgrade显示 Version Unknown
      ↓
不冒险强刷Firmware
      ↓
改用 ST-LINK(OpenOCD)
      ↓
SWD = 240/480kHz
      ↓
OpenOCD识别:
STLINK V2J37S7
Target 3.246V
SWD DPIDR OK
Cortex-M0+ OK
Flash 16KB OK
      ↓
GDB建立连接
      ↓
程序下载
      ↓
Breakpoint at main()
      ↓
调试环境成功

23. 最重要的工程经验

以后遇到 STM32 烧录/Debug 问题,要想到的点是:

“链路具体断在哪一层?”

永远按这个顺序:

① Windows认识ST-LINK吗?
          ↓
② 调试服务器认识ST-LINK吗?
          ↓
③ ST-LINK能看到目标电压吗?
          ↓
④ SWD能读DPIDR吗?
          ↓
⑤ 能识别Cortex-M内核吗?
          ↓
⑥ 能识别STM32 Flash吗?
          ↓
⑦ ELF是否下载成功?
          ↓
⑧ CPU能否停在main()?

只要按照这八步查,基本不会出现:

在驱动问题上改 STM32 代码,
在 SWD 问题上调 I²C,
在 ST-LINK 固件问题上怀疑 NFC 芯片。

这也是这次踩坑最有价值的结论。


最终配置

当前这个项目:

STM32CubeIDE

Debug Probe:
ST-LINK (OpenOCD)

Interface:
SWD

SWD Frequency:
240 ~ 480 kHz

Configuration:
Automated Generation

Reset:
Software system reset

SWV:
Disable

RTOS Proxy:
Disable

Startup:
Download = true
Load Symbols = true
Breakpoint at main = true
Resume = true

当前已经验证:

ST-LINK → STM32L011 → main()

PASS

因此后面的 NFC / I²C 调试,不需要再改 ST-LINK 这一套配置。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐