STM32CubeIDE使用ST-LINK调试问题
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 这一套配置。
更多推荐



所有评论(0)