去年年底接了一个批量生产的项目,两百多块板子要烧固件,客户那边只有一把ST-LINK,电脑上装了Keil但没激活,烧个程序还得先打开工程,加载配置,点Debug,再等编译器飞一遍——光是等待和误操作浪费的时间就够喝一壶的。后来我彻底换成ST-LINK Utility来烧录,不仅开发阶段调试方便,生产线上也直接用它,一键烧录、自动校验、连选项字节都能一次性搞定,省了太多事。
这篇文章我不打算讲那些花里胡哨的东西,就从一个实际干活的工程师角度,把ST-LINK Utility给STM32烧录程序的完整流程、量产配置、以及我在现场踩过的坑全部写出来。你要是手里有STM32的开发板、样品机或者正在准备小批量产,这篇文章应该能帮你省下半天时间。
1. 为什么烧录还要单独用一个工具
很多人第一次听到“烧录用ST-LINK Utility”会觉得奇怪:Keil不是自带烧录功能吗?点击Download不就行了吗?确实,Keil的Flash Download能做这件事,但只适合开发阶段。当你面对的是量产、更新固件、批量维修这类场景时,Keil反而成了累赘。
1.1 先搞清楚烧录这件事的本质
所谓“烧录”,本质上就是把编译好的bin或hex固件文件,通过调试接口(通常是SWD或JTAG)写入芯片内部的Flash存储器,并完成校验。STM32的Flash不是随便写的,它有一套自己的烧录协议,需要工具通过调试接口和芯片内部的Flash控制器通信,执行擦除、编程、校验等步骤。
Keil做这件事的时候,它要做的事情太多:先打开整个工程,加载一堆中间文件,再通过调试器连接目标芯片,然后才执行烧录。而如果你只是想把手里的hex文件烧到芯片里,完全没必要动用整个IDE。这就好比你想拧个螺丝,却要把整个工具箱搬到现场——你需要的其实就是一把螺丝刀。
ST-LINK Utility就是这把螺丝刀。它是ST官方出品的独立烧录工具,不需要任何工程文件,不需要编译器,直接把固件文件拖进去就能烧。而且它不仅有图形界面,还支持命令行模式,这才是量产场景真正需要的功能。
1.2 为什么选了ST-LINK Utility而不是其他
市面上能烧STM32的工具不少,我自己试过的就有ST-LINK Utility、STM32CubeProgrammer、J-Flash、还有各种国产烧录器自带的软件。为什么我最后落地用的是ST-LINK Utility?
首先是上手成本。STM32CubeProgrammer功能确实强大,但界面复杂,选项繁多,新手上手容易懵。ST-LINK Utility的界面极其简洁,主界面就是一个文件列表加一个按键区,十分钟就能学会全部操作。
其次是稳定性。我这几年用了无数遍,它在标准的ST-LINK/V2和芯片连接上非常稳定,几乎没出现过莫名其妙的烧录失败。对于量产场景来说,“稳定不出错”比“功能多”重要得多。
第三是命令行支持。量产的时候没人会傻到一块板子一块板子地打开界面点鼠标,都是写一个批量脚本,插上一块板子跑一条命令,拔下来换下一块。ST-LINK Utility提供完整的命令行参数,可以实现无人值守的批量烧录。
ST官方后来主推STM32CubeProgrammer,有人担心Utility会被废弃,但至少到目前为止,它依然可以正常下载使用,而且在社区里的存量教程和操作经验非常丰富,遇到问题很好搜到解决方案。
2. 准备工作:软硬件与接线
在开始烧录之前,先把环境和设备都准备好。这块看起来很基础,但我见过太多人在这里栽跟头——接口没插紧、驱动没装好、固件文件格式不对,各种低级问题能卡你半天。
2.1 软硬件清单
核心硬件只需要三样:
- 一块STM32目标板(不管什么型号,F0、F1、F4、L0、L4都支持)
- 一个ST-LINK/V2调试器(建议买正品或者靠谱的国产兼容版,那种10块钱包邮的就要有折腾的心理准备了)
- 四条杜邦线(或者直接买带杜邦头的连接线也行)
软件方面,需要先装一个ST-LINK的USB驱动。在Windows系统下,如果你之前装过Keil或者STM32CubeProgrammer,驱动一般已经自动装好了。如果没装过,可以去ST官网下载ST-LINK驱动包,或者直接装ST-LINK Utility,安装程序里面会附带驱动。
2.2 接线没有你想的那么复杂
ST-LINK/V2的接口定义其实有好几种排列,但用SWD模式只需要接4根线:
| ST-LINK/V2引脚 | 目标板引脚 | 说明 |
|---|---|---|
| SWDIO | SWDIO | 数据线,双向 |
| SWCLK | SWCLK | 时钟线,由调试器输出 |
| GND | GND | 共地,必须接 |
| 3.3V | 3.3V | 给目标板供电(可选但推荐) |
为什么要强调共地?因为SWD信号是参考GND的,如果两边地电位不一致,轻则通信不稳,重则直接烧毁IO口。我在维修的时候见过不少板子,就是没共地导致SWDIO引脚损坏。
供电这个事值得单独说一下:如果你的目标板是独立供电的,那ST-LINK的3.3V可以不接;如果板子本身没电,就需要用ST-LINK给目标板供电。但注意,老款ST-LINK/V2的3.3V输出能力有限,一般只能供几十毫安的电流,如果你的板子上有大功率外设,一定要外接电源,否则烧录一半电压跌落,很容易导致烧录失败,甚至擦除Flash后没写进去,芯片直接变砖(这时候只能靠串口ISP救回来)。
2.3 驱动安装与固件确认
驱动装好之后,把ST-LINK插上电脑,打开设备管理器,在“通用串行总线设备”或“端口”类目下应该能看到一个“STMicroelectronics STLink dongle”之类的设备。如果显示感叹号或者未知设备,说明驱动有问题,右键更新驱动,手动指定到ST-LINK Utility安装目录下的驱动文件夹即可。
另外,ST-LINK本身有内部固件,版本太老的话可能不支持某些新出的芯片型号。如果你用的是多年前的ST-LINK/V2,建议先看看固件版本。在ST-LINK Utility里,点击“ST-LINK”菜单下的“Firmware Update”,可以查看和升级内部固件。升级过程很简单,但要注意:升级过程中绝对不能拔线,否则ST-LINK会变砖。
3. 保姆级烧录实操:从打开软件到断电上电
这一步是整个教程的核心。我会按照实际操作顺序,一步一步写清楚每个动作和界面上的变化,你照着做基本不会出问题。
3.1 第一步:加载目标固件文件
打开ST-LINK Utility,主界面会显示一个空白的内存窗口。注意,这个时候软件只是打开了,还没有和目标板建立连接。
点击工具栏上的“打开文件”按钮(一个黄色的文件夹图标),选择你要烧录的文件。支持的文件格式有三种:
- .hex:Intel HEX格式,包含地址信息,烧录时无需指定起始地址,推荐使用
- .bin:纯二进制格式,不含地址信息,烧录时需要手动指定起始地址
- .srec:Motorola S-record格式,类似hex,现在用的不多了
从Keil工程编译出来的文件默认是hex格式,在工程输出目录下就能找到。如果你的工程没生成hex文件,需要在Keil的Options for Target -> Output选项卡里勾选“Create HEX File”,重新编译一次。
文件加载之后,界面左侧会显示一个目标文件列表,右边内存窗口会显示文件内容对应到某个地址的数据。这个时候还没烧,你可以在这一步再确认一下固件对不对,比如看看文件大小是否在合理范围内。
3.2 第二步:连接目标板并读取芯片信息
把ST-LINK和目标板用SWD线连接好,确保目标板已经上电,然后点击工具栏上的“Connect to the target”按钮(一个带绿色箭头的芯片图标)。
连接成功之后,软件会自动读取芯片的ID、Flash大小等信息,并在左侧信息栏显示当前芯片的型号。这里是一个非常重要的确认点:一定要核对软件识别出来的芯片型号和实际封装的丝印是否一致。比如实际用的是STM32F103C8T6(64KB Flash),软件却识别成STM32F103CBT6(128KB Flash),虽然能烧,但后续做读保护或者配置选项字节时可能会出问题。
如果连接失败,软件会弹出一个错误对话框。常见的情况和解决办法我会放在后面的问题排查章节详细说,这里先说一个最重要的常识:连接失败时,先检查接线和供电,不要急着点重试,因为有时候芯片内部已经被写入了读保护,需要先解除才能连接。ST-LINK Utility有一个专门的按钮叫“Remove Read Protection”或者通过选项字节操作来解除,前提是必须先能建立连接。
3.3 第三步:执行烧录与校验
连接成功之后,点击工具栏上的“Program and verify”按钮(一个绿色向下箭头的图标),软件会弹出烧录选项对话框:
- 烧录起始地址:如果加载的是hex文件,这里会自动带出地址,不需要改
- 烧录前先擦除:有三个选项,Full chip erase(全片擦除)、Sectors erase(按扇区擦除)、Erase needed sectors(只擦除需要的扇区)。量产建议默认用full chip erase,虽然慢几秒钟,但能保证Flash是干净的状态
- 烧录后校验:一定要勾选Verify after programming,这个功能会在烧录完成后把Flash内容和原文件逐字节比较,能及时发现写入错误
点“Start”按钮之后,下面的进度条会从0跑到100%,中间能实时看到正在写入哪些地址、擦除了哪些扇区。烧录完成后会弹出一个“Program memory”对话框,显示“Verification ... OK”之类的提示,这就代表烧录校验一次性通过了。
我个人的习惯是,烧录完成之后不急着断电,先把ST-LINK拔掉(或者断开连接),然后给目标板重新上电,观察程序是否正常运行。因为有时候烧录虽然成功了,但芯片的启动配置不对,比如boot引脚状态不对、选项字节里BOOT地址配错,程序同样不会跑。
3.4 第四步:读取校验与选项字节操作
这件事很多教程不会提,但实际中很有用:烧录完之后,强烈建议点击“Read back”按钮把Flash内容读出来,然后和原始hex对比一遍。虽然“Program and verify”已经做了校验,但那是烧录器内部做的,用“Read back”相当于事后再确认一次,特别是量产的时候,万一某块板子烧录时信号异常但凑巧校验通过,事后读一遍能发现怪异问题。
选项字节(Option Bytes)操作也是ST-LINK Utility的强项。在连接状态,点击“Target”菜单下的“Option Bytes”,可以配置芯片的读保护等级(RDP)、硬件看门狗、BOOT地址、Flash写保护等。
这里重点说一下读保护。如果你不希望别人拿个调试器就把你芯片里的固件读出来,量产的时候很有必要把RDP等级设置成Level 1。设置方法就是在选项字节界面,把Readout Protection从Level 0改成Level 1,然后点Apply。有一点必须知道:一旦设置了Level 1,想要再解除保护芯片,必须执行全片擦除,芯片里的固件就没了,这是ST芯片的硬件设计,没有后门。所以量产时如果设置了读保护,出厂前一定要把测试固件全部烧录完成并验证通过,再执行设置保护这一步。
4. 量产配置:一条命令搞定几十块板子
如果你只是自己开发调试,看到上面这一节就可以去实操了。但如果是给客户交板子、小批量生产,那量产环节的效率问题绕不开。总不能每块板子都打开软件点一遍鼠标,那太浪费生命了。
4.1 批量烧录的三种思路对比
我接触过的批量烧录方案有三种:
第一种是买专门的量产烧录器,比如脱机烧录器。把固件先拷贝到烧录器里,到了产线不接电脑,直接在板子上按一下按钮就能烧。优点是不依赖电脑、速度快、适合大规模生产;缺点是设备贵,一两千起步,而且每种芯片的烧录座或接口定义不同,兼容性要考虑。
第二种就是本文说的ST-LINK Utility命令行模式。用一台电脑插一个ST-LINK(或者用USB HUB扩展多个),跑一个批量脚本,插板子、敲命令、换板子。优点是零额外成本,灵活,遇到问题可以直接看报错;缺点是每烧一块都要人工操作一下,适合几十到几百块的中小批量。
第三种是用STM32CubeProgrammer的CLI模式。功能和Utility命令行类似,但它支持更新的芯片型号。如果你用的是比较新的STM32系列(比如G0、H7),建议优先用CubeProgrammer的命令行;老型号两个工具都能胜任。
我的建议是:300块以下的板子,用方案二就足够了;再往上走,直接买脱机烧录器,别把人力浪费在重复劳动上。
4.2 用ST-LINK Utility命令行做量产烧录
ST-LINK Utility的命令行程序叫做ST-LINK_CLI.exe,安装目录下能找到(通常路径是C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\)。我建了一个批量烧录的批处理脚本,核心命令是这样:
@echo off set STLINK="C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ST-LINK_CLI.exe" set FW=.\firmware.hex %STLINK% -c SWD UR %STLINK% -ME %STLINK% -P %FW% -V %STLINK% -OB RDP=1 pause逐条解释一下含义:
- -c SWD UR:连接目标板,使用SWD模式,UR表示Hot Plug模式,可以适应目标板先上电的情况
- -ME:全片擦除,对应图形界面的“Full chip erase”
- -P firmware.hex -V:编程并校验,-V强制校验
- -OB RDP=1:设置选项字节,把读保护等级设为Level 1
实际使用中,连不上板子的情况经常发生,所以脚本里要加一个连接检测逻辑。如果连不上直接执行擦除,会报错退出,并不会损坏什么,但为了实现“插上板子跑一段就量产完成”的体验,更好的做法是用-List参数先检测一下是否有ST-LINK连接,再用-i参数读取芯片ID,确认通信正常后再干正事。
@echo off set STLINK="...\ST-LINK_CLI.exe" set FW=.\firmware.hex %STLINK% -List if errorlevel 1 ( echo [ERROR] No ST-LINK found, check USB connection. pause exit /b 1 ) %STLINK% -c SWD UR -P %FW% -V if errorlevel 1 ( echo [ERROR] Program failed, check target connection. pause exit /b 1 ) %STLINK% -OB RDP=1 if errorlevel 1 ( echo [WARN] Set RDP failed, double check manually. ) echo [OK] Programming complete, remove board now. pause这个脚本在生产线上用起来非常顺手:插上板子,双击bat,看到OK就拔掉换下一块。这样每块板子的操作时间压缩到一分钟以内,一个上午烧一两百块轻轻松松。当然你也可以把固件路径、读保护等级这些参数用变量提取出来,做成更通用的脚本模板。
4.3 选项字节和读保护的一并处理
量产的时候,选项字节的配置往往不是“烧完程序就完事”那么简单。不同项目可能有不同需求:
- 需要开启硬件看门狗:选项字节里把IWDG_SW设为0(硬件模式)
- 需要限制从RAM启动:配置BOOT地址和nBOOT1位
- 需要防止误擦除某个扇区:设置对应扇区的写保护
- 需要读保护:设置RDP等级
这些操作在图形界面的Option Bytes里都能做,但量产时要在命令行里一并处理。上面的脚本已经演示了设置RDP的写法。如果还有其他选项字节要配置,可以用-OB参数多次指定,或者把所有选项字节写进一个配置里。
一个特别重要的提醒:在烧录过程中和设置读保护的过程中,绝对不能断开ST-LINK与目标板之间的连接。如果RDP=1写了一半线松了,芯片可能进入异常状态,下次连都连不上,只能通过串口ISP全片擦除救回来。所以量产用的连接线材,一定要选质量好的,那种用几次就接触不良的杜邦线,坚决不用在产线上。
量产的另一个痛点是“怎么保证每一块板子烧的固件版本一致”。这个可以用固件文件的哈希值来解决。批量生产之前,先算一下源hex文件的MD5,每烧一批之后随机抽一到两块板子,再用“Read back”的方式读出来并计算哈希,和源文件比对,确保没有人误操作烧错了文件。
5. 常见问题与排查技巧实录
烧录工具用久了,各种错误都遇到过。下面这些问题是真实项目中频率最高的,我按类型整理成速查表,顺便把我自己的排查思路也写进去。
5.1 连不上目标板(No target connected)
这个报错占所有问题的七成以上。排查顺序是固定的:
先看ST-LINK本身是否被电脑识别,设备管理器里有没有感叹号。再看四根线有没有接错,特别是SWDIO和SWCLK是不是接反了。然后确认目标板有没有电,用万用表量一下3.3V引脚是否有正常电压。
排除以上之后,如果还是连不上,要考虑目标芯片是否已经开启了读保护。有些芯片之前被别人设了RDP Level 1,此时需要手动选择“Connect under reset”模式。在ST-LINK Utility的“Target”菜单里,有个“Settings”选项,可以勾选连接时拉低复位脚。量产的时候我习惯在连线里多引一根NRST到ST-LINK的RST脚,关键时刻能多一个手段。
还有一种情况:目标芯片的SWD引脚被程序复用成了普通GPIO,甚至进入了低功耗模式。此时正常情况下连不上,也需要用“Connect under reset”或者在芯片上电瞬间按住复位、再快速点击连接。实际操作中成功率最高的方式,是先按住目标板复位键,然后点击连接,在软件开始通信的瞬间释放复位。
5.2 烧录时报错(Cannot access target, Flash Write failed)
如果连接能建立,但擦除或写入时报错,问题通常在Flash状态上。最常见的是Flash写保护没解除。如果芯片之前配置过选项字节,把某个扇区设了写保护,烧录时就会报写失败。解决办法是连接成功之后,先去Option Bytes界面把写保护全部清除,再回到烧录界面执行全片擦除。前面说了,RDP Level 1状态下芯片无法正常连接和擦除,必须先降级到Level 0(会触发全片擦除)。
另外,供电不稳也会导致Flash写入失败。我遇到过一批板子,用ST-LINK供电能烧,但用独立电源供电就失败,查了半天发现是那个电源在负载变化时电压跌得厉害。烧录瞬间Flash写入电流会有一个尖峰,供电不足就会失败。解决办法很简单:量产烧录时用稳定的电源适配器,不要在USB口上挂一堆东西,也不要让ST-LINK同时给好几块板子供电。
5.3 烧录成功后程序不运行
烧录校验全过了,但重新上电程序没跑,这类问题排第二。先说一个新手最容易忽略的:BOOT引脚的配置。STM32的BOOT0和BOOT1引脚决定芯片从哪个地址启动。如果BOOT0被拉高,芯片会从系统存储器启动而不是用户Flash,程序当然不会跑。很多开发板上BOOT0默认是接低电平的,但自己做的小板子不一定,量一下BOOT0电平就知道问题所在了。
还有一种情况是启动地址和程序地址不匹配。比如你固件编译时链接地址是0x08000000,但选项字节里配置的BOOT地址被改成了0x08010000,芯片上电后跳转到错误地址,程序自然跑不了。出现这种问题,把选项字节恢复默认基本就能解决。
最后,时钟配置错误也可能导致程序跑不动。比如用了外部晶振,但实际板上没有贴晶振,程序上电初始化时钟时直接卡死在等待HSE就绪的循环里。这种情况烧录工具本身没问题,烧录也算成功,但程序就是跑不起来。排查思路就是先跑一个点灯程序验证硬件,再逐步换回自己的固件。
5.4 量产现场的典型问题与应对策略
量产烧录最常见的三个坑,我直接列成清单:
第一个是烧录过程中操作人员不小心碰掉了杜邦线。应对措施是用那种带卡扣的排线,或者直接把线焊到测试点上,别在产线上用松垮的杜邦线。第二个是电脑USB口供电不足,插了多个ST-LINK之后偶尔连不上。应对措施是给每个ST-LINK都配一个有源USB HUB,别把四个ST-LINK直接堆在电脑的两个USB口上。第三个是固件版本管理混乱,烧了老版本还以为是新的。应对措施是每次更新固件都改文件名加版本号,比如app_v2.1.0.hex,同时把脚本里的固件路径指向固定目录,不手动改脚本。
如果你的量很大,还有一个值得做的优化:把ST-LINK_V2的固件更新到最新版,然后使用SWD的最高速度。连接参数里把速率调到最高,单块板子的烧录时间能缩短一半以上。开发调试时用低速是求稳,量产时用高速是求效率,两者目标不同。
6. 几个必须知道的细节和经验
最后这部分是纯粹的实战经验,我把几个容易踩的细节单独拎出来说清楚。
6.1 复位引脚的重要性
绝大多数教程教你接SWD只接SWDIO、SWCLK、GND三根线,但实际量产时我强烈建议把NRST也接到ST-LINK上。为什么?因为部分STM32型号在特定条件下SWD会锁死,或者程序运行后把SWD引脚复用成了其他功能,此时如果能在连接时同时控制复位脚,就有很大概率恢复下载。ST-LINK Utility里连接选项的“Connect under reset”模式,就是靠硬件上的NRST引脚来实现的。量产时多引这一根线,你的烧录成功率能提升到99.9%以上。
6.2 固件文件的格式选择
前面提过hex和bin的区别,这里展开说一下。量产环境我建议统一用hex格式,原因是hex自带地址信息、不容易烧错位置。如果非要转成bin用,一定要搞明白你的固件链接地址是多少。比如STM32F103的Flash起始地址是0x08000000,如果程序里又定义了一个放在0x08010000的Bootloader,你烧bin文件时选错了偏移地址,就会把Bootloader或者主程序的代码写到错误位置,导致程序完全无法启动。从Keil的Output目录下直接拿hex文件是最保险的,不要自己手动转格式。
6.3 如何用ST-LINK Utility备份整颗芯片
有时候你拿到一台设备,想先把它现有固件完整备份出来,再做其他操作。这种场景用一个功能就够:点击“Read back”,设置读取的起始地址0x08000000,长度根据芯片Flash大小来,比如F103C8T6是64KB,填0x10000,然后点保存,就能把整个Flash倒成一个bin文件。
但这里有一个巨大的坑:如果芯片开了读保护(RDP Level 1),你是读不出来任何有效数据的。就算软件显示读取成功,你得到的也是一个全0xFF或随机数的文件,此时千万不要以为自己备份成功了,更不要在全片擦除之后才发现备份文件不能用,否则芯片里原来的程序就再也找不回来了。
所以在做任何“先备份再动刀”的操作之前,先检查选项字节里的RDP等级是不是Level 0,以及读取出来的文件大小和内容是否看起来正常(比如是否包含大量的非0xFF数据)。
6.4 关于工具的生命周期
前面提到ST官方现在主推STM32CubeProgrammer,ST-LINK Utility的更新已经基本停滞了。但这不代表它不能用了,实际上对于绝大多数STM32F0、F1、F4系列芯片,ST-LINK Utility的功能非常完善,不会因为官方出新工具就失效。不过如果你用的是STM32H7、G0这些比较新的系列,最好先试一下Utility能不能正常识别和烧录,发现不兼容就直接转STM32CubeProgrammer的CLI模式,别在死磕上浪费时间。
我个人现在的选择是:手头的老项目、中小批量产,继续用ST-LINK Utility的脚本,因为它稳、快、简单,同事上手也不需要培训。开发新项目或者遇到新芯片时,会用STM32CubeProgrammer。说到底,工具是死的,人是活的,能用最少的成本解决问题才是关键。
烧录这件事,看着简单,但真到了量产、维修的现场,工具的可靠性就是生命线。希望这篇东西能让你少走点弯路,尤其是那些我踩过的坑,你就不用再踩一遍了。