上个月有个搞电机驱动的朋友给我发消息,说他的ST-Link V2在Keil里弹出固件升级提示,他随手点了确认,升级进度条走到100%,紧接着Keil报错:No target connected。他的第一反应是调试器废了,已经在购物车加了个新的。我说你先别下单——这种“升级前一切正常,升级后目标消失”的情况我这些年处理过不下十次,九成不是调试器烧了,而是升级这个动作牵动了某个隐藏环节,剩下的那一成也基本有救。
这篇就是给你的排查参考。无论你用的是官方ST-Link还是各种兼容版,只要你踩过“固件升级后目标芯片检测不到”“No target connected”“Target connection failed”这类坑,或者正准备升级固件想提前避雷,下面这些内容都能派上用场。我会按实际的排查链路来写,从最简单的物理检查到最容易被忽略的读保护问题,尽量让你少走弯路。
1. 升级前一切正常,升级后"No Target Connected":先判断是调试器坏了还是目标丢了
1.1 固件升级到底改了什么东西
很多人误以为ST-Link升级固件会“顺便”影响目标芯片,其实完全不是。ST-Link内部有一颗MCU,固件是跑在调试器自己芯片里的程序,负责将USB协议转换成SWD或者JTAG时序。升级固件这件事,从头到尾只碰调试器自身,不写目标芯片的Flash,也不改目标芯片的任何寄存器状态。
那问题出在哪?问题在于:升级固件会重置调试器的默认行为。不同版本的固件,SWD时钟频率的默认档位、枚举时序、信号握手策略可能都有细微差异。升级前你用旧固件能连上目标,升级后新固件可能用更高的默认频率去探测目标,一旦目标板上的线缆质量、接线方式、供电环境撑不住这个频率,连接就会失败。
换句话说,升级往往是“压垮骆驼的最后一根稻草”——真正的瓶颈一直存在,只是旧固件恰好没触发它。
1.2 先做一个关键区分
拿到问题先别急着拆线。我要先让你做一个判断:电脑还能不能识别到ST-Link本身?
这个判断很快。打开设备管理器(Windows),看在“通用串行总线设备”或者“通用串行总线控制器”下面有没有ST-Link相关条目,比如“STLink dongle”或者“STM32 ST-LINK”之类。
- 如果设备管理器里还能看到ST-Link,说明调试器自身活着,USB通信没问题,问题出在“调试器到目标芯片”这一段。
- 如果设备管理器里连ST-Link都消失了,或者显示黄色感叹号,那才是调试器固件刷挂了或者驱动出了问题。这种情况要用后面第三章的方法救。
我第一次遇到这问题时也下意识以为是ST-Link坏了,后来发现设备管理器里它好好的,问题全在SWD那条链路上。这个判断能帮你省掉一整天的无用功。
1.3 记录下具体的报错信息
不同工具报错信息略有差异,把这些信息记下来有助于定位:
| 工具 | 典型报错 | 通常指向 |
|---|---|---|
| Keil MDK | No target connected | SWD连接失败 |
| STM32 ST-LINK Utility | Target connection failed | 握手失败或RDP保护 |
| STM32CubeProgrammer | Error: No STM32 target found | SWD链路不通或RDP保护 |
| IAR EWARM | Could not find device | 目标未响应 |
1.4 目标芯片的供电状态先确认
在拆线之前,先用万用表测一下目标板的电源。这个问题看着低级,实际发生频率极高。很多开发板用USB供电,但电源开关被误碰关掉,或者独立供电的板子电源适配器松了,目标板压根没上电,ST-Link当然连不上。
为什么升级前没这个问题?因为升级前你可能刚好处于前一次调试的整个流程中,板子一直通着电。而升级固件通常需要拔插USB,重新接电的时候,某个环节就出岔子了。所以排查第一步永远是:目标板电源指示灯亮不亮?VCC对GND电压正不正常?
2. SWD四根线的物理链路排查:最容易翻车的地方往往在连接器上
2.1 四根线的角色不能搞混
SWD调试只需要四根线:SWDIO、SWCLK、VCC、GND。SWDIO是双向数据线,SWCLK是调试器输出的时钟,VCC是电平参考,GND是共地。
SWD的VCC比较特殊,它的主要作用不是给目标板供电,而是让调试器知道目标板的IO电平是多少。一般来说调试器会通过VCC引脚读取目标板的电压,然后决定SWDIO和SWCLK的输出电平。如果VCC悬空或者电压不对,调试器输出的逻辑电平就是错的,目标芯片根本接收不到有效信号。
在排查中我见过太多人把SWD四根线接错。最典型的是SWDIO和SWCLK接反——两根线在排针上挨得很近,插反了看不出太大异常,但目标芯片就是没响应。
2.2 20pin座子的引脚定义,你得心里有数
很多人用的是ST-Link V2自带的20pin排线,20pin座子是标准ARM调试接口定义,但实际调试一般只用其中的SWD四根线。20pin里对应的引脚位置是:
- Pin 1:VCC(目标板参考电压)
- Pin 7:SWDIO
- Pin 9:SWCLK
- Pin 20:GND
简单记就是:1号VCC,7号SWDIO,9号SWCLK,20号GND。排线插反、错位这类物理连接问题,在频繁插拔的开发环境中非常常见。我自己的习惯是每次接好线先用万用表蜂鸣档量一下这四根线的通断,确认线序没问题再上电。整个过程不到半分钟,但能过滤掉一半以上的连接故障。
2.3 杜邦线和排线接触不良的隐蔽性
杜邦线的氧化和松动是另一个大坑。尤其在实验室环境,板子放久了,杜邦线插头表面会氧化发黑,接触电阻变大。SWD时钟频率一高,信号边沿在接触电阻上产生反射,目标芯片就无法稳定采样。
遇到这种情况,把杜邦线重新插拔几次、换一根新线、或者用排针直接焊接,一般都能解决。这里有个实测出来的经验:SWD频率降到1.8MHz以下时,很多松动的杜邦线会“假装正常”,因为在低频下信号边沿变缓,接触电阻的影响被稀释了。所以如果你降低频率后能连上目标,但又不敢确定是不是接触问题,那就需要从物理层面彻底解决。
2.4 目标板必须独立供电
ST-Link的VCC引脚能不能给目标板供电?这个问题我问过很多人,得到的答案各不相同。实测下来:有些ST-Link V2的VCC确实能输出3.3V,但电流限制得很死,基本只能点亮LED,带不动MCU正常工作。你如果用ST-Link的VCC给目标板供电,MCU可能处于一种“半死不活”的上电状态,SWD自然连不上。
正确的做法是目标板独立供电,ST-Link的VCC只作为电平参考。如果目标板的电压不是3.3V而是5V或者1.8V,那就更要注意:ST-Link V2的SWDIO和SWCLK引脚电平上限一般是3.3V,强行接5V的目标板有风险,需要加电平转换或者使用支持宽电压的调试器。说到这里顺便提醒一下,V3版本的ST-Link在电压适配方面做得更好,但V2仍然是目前存量最大的调试器,所以V2遇到的情况也最多。
2.5 复位引脚在连接时的特殊作用
排查过程中,你可以试试一个非常有效的手段:按住目标板的复位键不放,然后点击连接。如果能在按住复位的情况下连上目标,说明目标芯片里跑的程序把SWD引脚占用了,或者芯片进入了某种异常状态。
为什么按住复位有效?因为STM32在复位期间,SWD端口是默认激活的,此时调试器可以抢占连接。一旦连接成功,调试器会暂停内核,然后再释放复位。IDE通常提供“Connect under Reset”选项来实现这个流程,但有时候硬件上手动按住复位反而更直接。
之前我帮朋友排查一个跑飞了的STM32F103项目,程序里把SWD引脚重映射成了GPIO,正常模式怎么都连不上,按住复位再点连接,一下就OK了。这个技巧在后面的软件排查中我会再展开讲。
3. 软件与工具层面的强制恢复手段:驱动、连接模式与频率调整
3.1 先从设备管理器确认驱动状态
物理链路排查完,如果问题还没解决,回到设备管理器看ST-Link的驱动是否正常。有时候固件升级会把驱动信息搞乱,设备管理器里ST-Link条目出现黄色感叹号,或者变成未知设备。
处理办法是卸载设备后重新扫描,或者去ST官网下载最新的ST-Link驱动安装包重新装一遍。如果你是第三方兼容版ST-Link,装官方驱动也能覆盖大部分情况。有一个小技巧:更换USB口插一下,很多兼容版ST-Link对某些USB Hub的兼容性不好,插在主机背板上的USB口反而更稳定。
3.2 用STM32 ST-LINK Utility做一次“体检”
确认驱动正常后,打开STM32 ST-LINK Utility。这个工具虽然ST官方已经停止更新,但在老用户中存量巨大,它有一个核心功能是其他工具替代不了的:可以直接查看ST-Link固件版本,并对ST-Link执行固件升级或恢复操作。
打开Utility后,如果左侧能看到ST-Link的信息(包括固件版本号),说明调试器和电脑通信OK。接下来点击菜单栏的Target -> Settings,在调试连接设置里可以调整连接模式。
3.3 三种连接模式的选择逻辑
ST-Link Utility的Settings里,Connect Mode有三个选项:Normal、Connect under Reset、Hot Plug。
- Normal:常规模式,直接尝试和目标芯片握手。适用于目标芯片处于正常状态的情况。
- Connect under Reset:连接过程中将复位引脚拉低,让目标芯片停在复位状态再建立连接。适用于目标芯片里跑飞的程序占用SWD、或者异常低功耗模式导致调试口失效的情况。
- Hot Plug:热插拔模式,不主动控制复位,适合目标芯片已经在运行、不能打断的场景。
固件升级后连不上目标,我建议优先试Connect under Reset模式。很多“看起来死了”的目标芯片,在复位期间都能被顺利接管。
3.4 把SWD频率降到“龟速”
频率是另一个高频有效的突破口。打开Settings里的Frequency下拉框,默认可能是4MHz甚至更高,你可以降到1.8MHz试一下,还不行就降到950kHz、480kHz、180kHz,一路降下去。
为什么频率越高越容易失败?因为SWD协议在更高时钟频率下,对信号质量的要求更苛刻。信号线上的分布电容、接触电阻、参考电压纹波,都会在高频下被放大。降低频率等于给信号链路“减压”,很多布线不够讲究的开发板、飞线调试的场景,必须把频率降到一个很保守的值才能稳定连接。
我调试一个用飞线连接的传感器板时,4MHz死活连不上,降到480kHz秒连。这个案例我写进过自己的调试笔记里:频率不是越高越好,稳定才是目标。
3.5 用STM32CubeProgrammer做最后尝试
如果ST-Link Utility不行,试试STM32CubeProgrammer。这个工具是ST官方目前的推荐工具,功能比Utility更完整,UR也更新。
使用CubeProgrammer时同样可以设置连接模式和频率。左侧栏选择ST-LINK,然后点击右上角的Connect按钮。如果连接失败,注意看报错信息里的代码,比如:
Error: No STM32 target found或者:
Error: Target connection failedCubeProgrammer在检测到RDP保护时,报错信息会比较明显,比如提示目标芯片处于读保护状态。这正好引出下面要说的内容——读保护是ST-Link升级后“目标消失”的最大隐藏元凶。
3.6 通过全片擦除强制恢复
如果目标芯片处于调试锁定状态但RDP等级还是Level 0(无保护),可以直接执行全片擦除(Mass Erase)。在ST-Link Utility里是Target -> Erase Chip,在CubeProgrammer里是左侧菜单的Erase & Programming,选择Full chip erase。
全片擦除会把Flash里的程序、配置位全部抹掉,芯片恢复出厂状态。如果目标芯片里没有重要数据,或者你已经备份了源码,这招是恢复连接最快的路径。但擦除之前必须确认RDP等级,如果是Level 1的保护,擦除操作会被拒绝或需要先解除保护。
4. 读保护(RDP)才是隐藏最深的元凶:调试端口被锁住的识别与解锁
4.1 升级动作和读保护的关系
很多人不理解:为什么升级ST-Link固件会跟目标芯片的读保护扯上关系?
原因很微妙。在升级固件之前,你如果用过某些工具(比如STM32CubeProgrammer、或者某些量产烧录软件)给目标芯片设置了读保护,当时因为旧固件和旧工具的配合“一切正常”,你可能根本没注意到。升级固件后,新固件对目标芯片状态的探测逻辑更严格,遇到RDP保护的芯片时直接拒绝连接,报错信息就变成了No target connected。
也就是说,读保护可能一直都在,只是升级前没触发显性故障,升级后才暴露出来。
4.2 RDP三种等级决定了你的抢救空间
STM32的读保护分为三个等级,这直接影响你能否自己解锁:
| 等级 | 保护作用 | 能否通过调试口解除 |
|---|---|---|
| Level 0 | 无保护,调试口完全开放 | 无需解除 |
| Level 1 | 禁止通过调试口读写Flash,但可以通过调试口修改Option Bytes | 可以,解除时会触发全片擦除 |
| Level 2 | 永久保护,调试口彻底禁用,芯片不可再调试 | 不能,只能换芯片 |
我在排查中遇到的情况大多是Level 1。这类芯片数据还有救——解除保护后全片擦除,程序没了但芯片还能继续用。Level 2基本是终结性的,一旦设置,任何调试器都无法再连接,也不是没有代价,代价就是芯片变一次性了。
4.3 怎么判断目标芯片是不是被RDP锁住了
当连接失败时,如果报错信息里带类似“readout protection”或者“RDP”字样,基本可以断定是读保护问题。
但有时报错不明确,就比如简单的No target connected。这时候可以在ST-Link Utility里试一下Target -> Option Bytes,看能否读取选项字节内容。如果能读出来,说明调试握手已经建立;如果RDP等级显示为Level 1或更高,原因就清楚了。注意:当RDP等级为Level 1时,一些调试操作会受限,但读取Option Bytes通常还是可以的。
4.4 解除读保护的完整操作
在STM32 ST-LINK Utility里解除Level 1的流程是:
- 在连接失败时先调整连接模式为Connect under Reset,重新尝试连接。
- 连接成功但无法操作Flash时,点击Target -> Option Bytes。
- 在Option Bytes界面里找到Readout Protection(RDP)选项,将等级从Level 1改为Level 0。
- 点击Apply。工具会弹窗提示“此操作将擦除整个Flash”,确认。
- 芯片全片擦除完成后,RDP自动降为Level 0,调试口完全开放。
在STM32CubeProgrammer里的操作类似:连接后点击左侧的Option Bytes,把RDP等级切到0xAA(即Level 0),然后点击Apply。CubeProgrammer同样会警告数据将被擦除。
这里要特别提醒:解除Level 1保护会擦掉整个Flash。如果芯片里有你需要保留的数据或者量产固件,操作前一定确认备份。可问题是,Level 1保护状态下你本来就读不出Flash内容,所以基本等于放弃数据换取调试能力。做这个操作前给自己一个心理准备:数据大概率保不住了。
4.5 升级前调低读保护等级?这不现实
有人会问:能不能在升级前先把RDP降为Level 0再升级?理论上是可行的,但意义不大。因为读保护不是升级固件设置的,而是目标芯片Option Bytes里的状态。固件升级改的是调试器内部程序,不改变目标芯片的任何配置。所以这里的核心并不是“升级导致读保护”,而是“读保护一直都在,升级后的调试器不再帮你绕过它”。
这句话我建议你反复体会。排查方向对了,问题才有解。
5. 固件升级的防翻车清单:升级前的准备与升级后的验证流程
5.1 升级前必须做的三件事
第一件事:确认目标芯片数据已备份。如果你的目标板Flash里有重要固件或校准参数,先用当前可用的调试器把固件完整读取出来保存好。升级固件本身不碰目标芯片,但因为升级后可能出现各种连接问题,一旦需要全片擦除来恢复连接,数据就没了。有备份,你才敢放手折腾。
第二件事:记录当前ST-Link固件版本。在ST-Link Utility的左上角可以看到当前设备信息,包括固件版本。记下这个数字,万一升级后出了问题,你可以用旧版本固件刷回来(部分场景下可以降级,但ST官方不保证所有版本都可降级)。
第三件事:给目标板额外供电。升级前把目标板用独立电源供上电,不要依赖ST-Link或USB供电。这一步能让你在升级后第一时间排除供电因素干扰,也能避免因供电不稳导致升级过程中信号抖动。
5.2 升级过程中的操作红线
升级固件的几十秒内,不要碰USB线,不要碰目标板,不要打开其他占用USB的程序。原因很简单:固件升级本质是往ST-Link内部Flash写入数据,如果这个过程中USB通信中断或者供电波动,可能把ST-Link自己的固件写坏。一旦写坏,调试器就真的变砖了,必须借助另一个调试器才能救回来。
我见过一个最惨的例子:有人用带开关的USB Hub连接ST-Link,升级过程中随手关了Hub开关,ST-Link直接变砖。所以升级时务必选一个独立的、供电稳定的USB口,别用劣质Hub。
5.3 升级后的功能验证流程
升级完成后,不要直接去连目标芯片。建议先做一轮快速验证:
- 在设备管理器里确认ST-Link正常枚举。
- 打开ST-Link Utility,确认能读到ST-Link自身信息。
- 不连接目标芯片的情况下,把连接模式改为Connect under Reset。
- 把目标板重新上电,连接目标。
如果以上步骤都通过,说明固件升级本身没问题,再进入正常调试流程。如果第4步失败,参考前面的章节逐步排查。
5.4 为什么我建议你手里至少备两个调试器
这是我最想强调的实操建议。多备一个调试器不是为了攀比设备,而是为了交叉验证问题归属。当升级后目标丢失时,你可以用第二个调试器去连同一个目标芯片:
- 如果第二个调试器也连不上,问题大概率在目标芯片侧。
- 如果第二个调试器能连上,问题才在第一个调试器。
这种交叉验证的效率远高于反复修改参数瞎试。我手头常备两个ST-Link V2和一个DAPLink,三者固件版本各不相同。每次遇到疑难杂症,换调试器测试是最快的定位手段。你不一定需要昂贵的原装设备,两个兼容版ST-Link V2就能撑起这套验证体系。
5.5 第三方兼容版ST-Link的升级策略
网上大量流通的ST-Link V2兼容版,固件芯片用的可能是STM32F103的克隆方案。这类调试器在购买时内部已经预置了某个版本的固件。官方升级工具可以给它们升级,但升级后可能存在两个风险:
一是不同版本的兼容固件在SWD时序实现上有差异,升级后可能反而变慢或出现不稳定的情况。 二是某些兼容版使用的芯片型号和官方不完全一致,强行升级官方固件可能导致功能异常。
所以对兼容版ST-Link,我的建议是:如果当前用的好好的,不是特别需要新固件支持的新芯片,尽量不要主动升级。工具稳定大于版本新鲜。如果确实需要升级,一定要确认卖家有没有提供对应的固件刷回方案,否则升级前先做好“可能变砖”的心理准备。
我记得有一次,朋友的一个兼容版ST-Link升级后连不上目标,折腾了半天没结果,最后用一个原装ST-Link交叉验证,发现目标芯片是好的,兼容版在升级后对高频率SWD的支持变差了,把频率降到950kHz后一切恢复正常。这类玄学问题虽然不致命,但非常消耗时间。
5.6 最后再分享一个容易被忽略的小细节
ST-Link的USB连接线,用太长的线或者太细的线也会导致各种诡异问题。建议USB线控制在1米以内,尽量选带屏蔽的。有次我在一哥们儿的工位上排查了半天,最后发现他那根USB线是某设备附赠的充电线,只有电源线没有数据线,ST-Link偶尔能枚举成功偶尔失败。换了根数据线后整个世界都清净了。
这也是为什么我在怀疑软件问题之前,一定会把物理链路(USB线、SWD杜邦线、供电)彻底过一遍——低级问题不排除,高级问题根本没法定位。
整个排查链路走下来,你会发现“ST-Link固件升级后目标丢失”这个问题,本质上不是升级本身做错了什么,而是升级作为一个扰动因素,暴露了原本就存在的问题。把排查的重心放在目标芯片的状态和SWD链路上,问题基本都能解决。希望这篇经验能帮你少走我走过的那些弯路。