ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

STM32WB一次性烧写FUS、STACK、APP完整指南

STM32WB一次性烧写FUS、STACK、APP完整指南 1. 先搞清楚FUS、STACK、APP三者是什么关系很多刚开始碰STM32WB系列的工程师第一反应都是这不就是个带蓝牙的M4单片机吗用ST-LINK把固件烧进去不就行了结果烧完发现蓝牙压根不工作或者芯片直接进入DFU模式一脸懵。这个场景我见过太多次了包括我第一次玩STM32WB55RG的时候也栽在这上面。STM32WB跟普通MCU最大的区别在于它内部有两个内核——一个Cortex-M4负责应用逻辑跑你的APP代码一个Cortex-M0负责无线协议栈跑蓝牙/BLE、Zigbee、Thread等协议栈。这两个核是独立运行的M4通过IPCC硬件邮箱和M0通信。问题来了M0上跑的协议栈不是出厂就烧好的需要你自己烧写而烧写协议栈的过程又跟普通固件完全不同它要经过**FUSFirmware Upgrade Services**这个系统服务来管理。这里我把三个名词解释清楚FUS固化在STM32WB系统存储区的一段bootloader服务负责管理无线协议栈的烧写、升级、删除。它本身也是固件可以升级比如从0.5.3升到0.5.4、0.5.5。STACK无线协议栈固件比如BLE协议栈的stm32wb5x_BLE_Stack_full_fw.bin运行在M0核上提供GAP、GATT、L2CAP等蓝牙协议API给M4调用。APP你自己写的应用固件运行在M4核上通过STM32CubeWB的中间件库调用协议栈API。了解这个背景后你就明白ST-LINK的直接烧写只能烧APP或者烧FUS本身但烧STACK必须通过FUS进行。如果你试图把STACK bin文件直接拖到ST-LINK里烧大概率会报错或者烧进去也不生效。还有一个容易忽略的点FUS和STACK是有版本匹配关系的。FUS版本太老可能不支持你手里的STACK版本STACK和FUS版本组合不对M0起来后APP调用API就会卡死或返回错误码。所以一次性烧写FUSSTACKAPP这个标题背后真正的核心是三个问题烧写顺序、版本匹配、工具链操作。2. 动手前的准备工作工具链和固件包在实际开始烧写之前我强烈建议先把工具链和固件材料备齐不然容易卡到一半发现缺东西。这里列一份我实测过、稳定的组合2.1 软件工具STM32CubeProgrammer简称STM32CubeProg这是必备工具。推荐用最新版比如2.14.0或更高。老版本对FUS烧写支持不够好特别是FUS版本升级功能我踩过2.12的坑烧写STACK时超时报错。STM32CubeMonitor-RF可选看RF参数用。第一次玩建议装上方便确认STACK是否激活成功。串口调试助手用于验证APP启动和蓝牙广播不是必须但建议备一个。2.2 固件文件去ST官网下载STM32CubeWB固件包比如en.stm32cubeWB对应你开发板用的版本。解压后你需要的文件分布如下STM32Cube_FW_WB_V1.18.0/ |-- Projects/ | -- NUCLEO-WB55RG/ | -- Applications/ | -- BLE/ | -- BLE_HeartRate/ | -- STM32CubeIDE/ | -- Release/ // APP的elf或bin或hex |-- Utilities/ | -- PC_Software/ | -- STM32CubeProg/ // 官方烧录脚本 |-- Middlewares/ | -- ST_Projects/ | -- STM32WB_Copro_Wireless_Binaries/ | |-- stm32wb5x_BLE_Stack_full_fw.bin // BLE全功能栈 | |-- stm32wb5x_BLE_HCILayer_fw.bin // HCI层栈某些场景用 | -- stm32wb5x_FUS_fw.bin // FUS更新固件我这里的路径是STM32CubeIDE编译出来的Release目录下的app固件如果你用其他IDE对应找输出文件即可。2.3 硬件准备NUCLEO-WB55RG开发板或者你自己画的板子推荐用带ST-LINK的板子省事。ST-LINK的SWD连接如果用板载ST-LINK直接USB连电脑即可。如果用外部ST-LINK注意PB13SWCLK、PB14SWDIO别接反。版本匹配经验STM32CubeFW_WB不同版本里STACK、FUS的版本号不同。比如我在V1.13.0里看到的是FUS 0.5.3 BLE栈1.13.0在V1.18.0里可能是FUS 0.5.5 BLE栈1.18.0。如果板子出厂是旧的FUS你拿新STACK直接烧有可能失败。稳妥做法是先烧新的FUS再烧STACK最后烧APP。这也是一次性烧写最不容易出错的路径。3. 一次性烧写的标准流程FUS→STACK→APP下面是我实践过很多次、稳定可靠的操作流程。我以NUCLEO-WB55RG STM32CubeIDE STM32CubeProg为例全程图形界面操作命令行方式后面讲。3.1 第一步擦除芯片清理出厂状态拿到新板子我建议第一步不是直接烧FUS而是先全芯片擦除把出厂自带的演示固件全部清掉包括FUS区。注意擦除FUS区需要特殊操作在STM32CubeProg中切换到Full chip erase然后在选项里勾选Force erase FUS。如果你只是普通地点击Full eraseFUS区会保留这倒不一定是坏事但为了从头走一遍完整流程我建议连FUS一起擦干净。操作步骤打开STM32CubeProgrammer选择ST-LINK连接。切换到Erasing Programming标签页选择Full chip erase。在下方Option Byte区域找到Force FUS erase之类的选项勾选不同版本叫法略有差异中文界面可能显示强制擦除FUS。点击擦除等待完成。这里有个细节擦除后芯片会进入空片状态此时连接速度会变慢因为芯片可能还停在Run模式。你可以在STM32CubeProg里选择Under reset连接模式或者把板子重新上电再连接。3.2 第二步烧写FUSFirmware Upgrade Services如果你从ST网站下载的CubeWB套件里带了FUS固件比如stm32wb5x_FUS_fw.bin此时可以把它烧进去。操作要点在STM32CubeProg的Erasing Programming页点击Download区域。文件选择stm32wb5x_FUS_fw.bin。设置起始地址为0x08000000没错FUS文件虽然会被放进系统区但烧录入口通常是Flash起始地址。勾选Verify programming。点击Download。这里有个非常关键的坑烧写FUS的时候不要勾选Run after programming。因为FUS烧完它不会退出bootloader你如果立刻运行它可能会以FUS模式启动导致你后续烧STACK时芯片状态不对。我一般在烧完FUS后手动点击Disconnect再重新连接一次。烧写成功后在Log里能看到类似信息Download in Progress: File download complete Start operation successful然后在底部状态栏能看到FUS版本号比如FUS version: 0.5.5。如果看到的是No FUS detected说明FUS没烧进去多半是地址或模式设置错了回到第一步重来。3.3 第三步烧写STACK无线协议栈FUS就绪后接下来烧STACK。这步不能再像烧FUS那样把bin随便拖进去必须通过FUS的无线升级机制。STM32CubeProg专门提供了一个接口确保板上电连接STM32CubeProg。切换到底部标签Firmware Upgrade Services在老版本叫FUS。在Operating Mode选择FUS upgrade还是Stack upgrade注意烧STACK要选Stack upgrade。在File里选择你的STACK文件stm32wb5x_BLE_Stack_full_fw.bin。点击Start Stack Upgrade。此时工具会通过FUS服务把STACK写入无线协议栈区0x08097000附近不同STM32WB系列稍不同。整个过程大约30秒到1分钟期间不要断电、不要断开ST-LINK。烧写成功的标志是Log中会有类似Start Stack Upgrade... Upgrade process success Stack version: BLE Stack 1.18.0如果你在Operating Mode里没看到Stack upgrade选项只有FUS upgrade说明当前的FUS版本太老不支持直接栈升级或者你选错了连接模式。遇到这种情况先升级FUS为最新版本用FUS upgrade模式烧stm32wb5x_FUS_fw.bin再做STACK升级。3.4 第四步烧写APP应用固件STACK烧好之后最后一步烧APP。这步就比较常规了跟普通STM32烧写一样切回Erasing Programming页。选择APP的bin或hex文件比如BSP工程编译出来的BLE_HeartRate.bin或.hex。起始地址填0x08000000如果你的工程链接脚本没有改偏移。注意如果APP工程里设置了蓝牙协议栈偏移比如APP_ADDRESS0x08000000则烧写地址就是0x08000000如果工程偏移是0x08040000之类的就填对应的地址。多数官方例程都是从0x08000000开始因为STACK存在后面独立的区不占APP空间。点击Download。烧完后把板子复位按一下NUCLEO板上的复位按钮或重新插拔USB。如果一切正常你的APP会通过蓝牙广播出来——比如HeartRate例程你在手机上用nRF Connect或BLE调试助手就能扫到HR_XXXX这样的设备。3.5 一条命令搞定命令行烧写方式图形界面适合新手但如果你要跑产线或者反复烧多个板子我更推荐用命令行。STM32CubeProg提供了CLI模式在安装目录下找到STM32_Programmer_CLI.exeWindows。我常用的烧写脚本如下STM32_Programmer_CLI.exe -c portSWD modeUR resetHWrst STM32_Programmer_CLI.exe -c portSWD modeUR -ob nBoot01 # 先擦除FUS区域这一步可选看情况一般不擦官方的FUS除非你要全套重来 STM32_Programmer_CLI.exe -c portSWD modeUR -fwupgrade FUS_filestm32wb5x_FUS_fw.bin first STM32_Programmer_CLI.exe -c portSWD modeUR -fwupgrade Stack_filestm32wb5x_BLE_Stack_full_fw.bin STM32_Programmer_CLI.exe -c portSWD modeUR -d app.bin 0x08000000 -v注意-fwupgrade后面的FUS_file... first表示先升级FUSStack_file...表示升级STACK。不同版本CLI参数变动不大但建议先看下help或官方手册确认。另外modeUR表示under reset如果你板子上的复位线没接可能失败那就换modeHOTPLUG。命令行方式最大的好处是可脚本化、可批量执行而且日志输出清晰方便集成到CI/CD或量产工具里。我实际用CLI烧过几百块板子稳定性很好。4. 常见问题与排查技巧实录这部分是我个人积累的踩坑合集几乎每个问题都在各大社区被反复问过。我按出现频率从高到低整理成一套速查表。4.1 烧写失败Error: Upgrade process error / FUS error code 0x40这大概是STM32WB烧写过程中遇到最多的错误。原因通常是FUS版本与STACK版本不匹配或者FUS区被破坏、芯片还有旧栈残留。排查步骤先用STM32CubeProg连接在底部状态栏看FUS版本号。如果看到的是No FUS说明FUS丢了先烧FUS。如果FUS版本非常老比如0.5.2先执行FUS升级-fwupgrade FUS_file... first再烧STACK。如果还是0x40可以尝试执行Remove stack操作在FUS标签页里选删除栈再重新烧STACK。我遇到过一次顽固的0x40最后是先全片擦除含强制FUS擦除再依次烧FUS→STACK→APP才解决。所以如果你赶时间直接按第3章的完整流程重来一遍90%的问题都能解决。4.2 STACK烧进去了但APP起来后蓝牙不工作烧写成功不等于无线正常工作。如果APP运行后扫描不到广播包或者调用BLE API时hardfault大概率是以下情况APP里选的无线固件类型和烧的不一致比如你烧了BLE_Stack_full_fw.bin但工程里配置的却是BLE_HCILayer_fw模式在stm32wbxx_hal_conf.h或app_conf.h里定义。这个不匹配会导致API调用地址错乱直接卡死。FUS区被APP覆盖如果你APP的链接地址设置成了0x08000000开始但烧写时误把整个Flash写了破坏了FUS。尤其注意不要用Page erase方式全片擦除后烧APP这会把FUS擦掉。M0核与M4核启动顺序问题STM32WB启动后默认M4先跑M0需要APP调SHCI_C2_BLE_Init()才会启动并加载STACK。如果你的APP初始化代码里没有正确调用这个函数STACK永远不会激活。排查方法很简单先用STM32CubeMonitor-RF连接或者直接在串口看APP日志确认是否看到STACK_READY之类的日志。没有的话查app_conf.h里的CFG_BLE_NUM_LINK、CFG_BLE_LL_ONLY等配置再对比官方demo。4.3 芯片无法连接ST-LINK报错Error: No STM32 target found这通常是芯片进入了低功耗模式、FUS的DFU模式或者SWD引脚被复用了。解决办法用Under reset模式连接STM32CubeProg连接参数选择modeUR按住复位键不放点连接再松开复位。如果这招不行给芯片执行一次connect under reset之后再全片擦除。检查你的板子是否把PB13/PB14SWD接到了别的东西上比如某些扩展板可能会占用SWD引脚。4.4 热词里的No stack trace available到底是什么意思这个词其实不完全属于STM32WB但很多人在嵌入式调试时碰到过。它出现在系统崩溃或异常但你没法从当前环境拿到堆栈回溯的时候。在STM32WB上常见于M0核崩溃比如协议栈跑飞或者M4访问了无效地址。它本身不是烧写错误而是运行期错误。当你看到No stack trace available时优先判断是烧的STACK版本不对还是APP里对STACK的调用越界。我自己遇到最典型的一次是用了STM32CubeIDE的旧版本编译APP但板子烧的是CubeFW新版的STACK两者协议版本不一致导致M0直接HardFault调试器只给出一句No stack trace available。解决方式APP和STACK最好来自同一个CubeWB版本不要混搭。如果混了先重新烧匹配版本的STACK再看APP是否要重新编译。4.5 FUS和STACK的版本组合速查我根据实测经验整理了一张常见的版本兼容性参考表以BLE_full栈为例注意具体版本号以ST官方Release Note为准FUS版本推荐的STACK版本范围实测表现0.5.31.12.0 ~ 1.14.0较老但稳定需注意部分新栈烧不进0.5.41.13.0 ~ 1.16.0兼容性较好0.5.51.13.0 ~ 1.18.0我目前主力组合稳定如果你的FUS版本太低直接用命令行烧新STACK开头时末尾的版本检查会直接拦下来。所以我一直建议拿到新板子先把FUS刷新到最新再烧STACK一劳永逸。5. 进阶技巧让一次性烧写更省心既然你看到了这里说明你对省事有追求。除了上面的标准流程我再分享几个实际生产中非常有用的进阶操作。5.1 利用STM32CubeProgrammer的批量烧录脚本如果你有10块板子每块都手动点界面不仅效率低还容易漏步骤。我通常在项目里放一个flash_all.bat内容大致如下echo off set STACK_FILEstm32wb5x_BLE_Stack_full_fw.bin set APP_FILERelease\BLE_HeartRate.bin set PROG_CLIC:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exe %PROG_CLI% -c portSWD modeUR resetHWrst %PROG_CLI% -c portSWD modeUR -fwupgrade FUS_filestm32wb5x_FUS_fw.bin first %PROG_CLI% -c portSWD modeUR -fwupgrade Stack_file%STACK_FILE% %PROG_CLI% -c portSWD modeUR -d %APP_FILE% 0x08000000 -v pause把文件路径替换成你的实际路径插上板子双击运行就行。实测下来包括连接、烧写、校验整个过程大约1分钟。注意中间不要拔插USB失败概率极低。5.2 如何设置FUS保护防止APP误擦FUS区STM32WB的Flash有一个FUS保护机制通过选项字节RDP读保护和PCROP代码保护配合实现。在你准备量产时需要开启合适的保护等级防止外部烧录器直接读走固件或意外擦除FUS。在STM32CubeProg的Option Bytes中重点关注RDPRead Out Protection建议设置为Level 10xC0或Level 20xCC。Level 2是永久性保护烧了就不能再解量产慎用。PCROP可以隔离指定Flash区域防止读取和篡改。你可以把FUS区和其他关键区域保护起来。WPR / WRPWrite Protection设置写保护防止APP在运行中误写Flash。我一般在量产前设置RDPLevel 1FUS区域写保护。这样做之后ST-LINK无法直接读Flash内容但可以继续通过STM32CubeProg做正常的烧写和栈升级。5.3 板子上电后自动运行APP的注意事项有些工程师发现烧完FUSSTACKAPP后板子上电后并没有自动运行APP而是停在DFU模式。原因多半是复位后Boot0引脚电平不对或者FUS的DFU模式优先级高于APP启动。排查思路检查Boot0引脚PA10是否有拉低电阻板子默认应该是低电平从Flash主区启动。在STM32CubeProg连接后手动点击Run按钮如果可以运行且广播正常说明代码没问题是启动入口的问题。检查工程里的链接脚本确认__initial_sp和Reset_Handler的中断向量表是否在0x08000000。NUCLEO板默认Boot0是低一般不会出问题。自己画板子的朋友建议把这个引脚仔细核对。5.4 无线固件可以换成Zigbee或Thread吗STM32WB不只支持BLE同一个芯片还支持Zigbee、Thread和基于802.15.4的私有协议。FUSSTACKAPP的烧写逻辑完全一样只是STACK文件不同。比如烧Zigbee的栈是stm32wb5x_Zigbee_Stack_full_fw.binThread的是stm32wb5x_Thread_Stack_full_fw.bin。有一点要注意不能同时烧BLE和Zigbee两个栈因为它们的协议栈区重叠。想切换协议需要先删除旧栈再烧新栈。删除栈的操作用FUS的Remove stack功能即可。如果你只用了BLE无需担心这点。如果你以后想玩多协议比如BLEZigbee并发那就是动态并发模式Dynamic Concurrent Mode需要单独烧一个特殊组合的栈固件这里不展开但烧写入口逻辑是一样的。6. 回到本质把一次性烧写理解成一套完整的启动链很多人对FUS、STACK、APP这三层感到困惑是因为把它们割裂开了。换个角度想STM32WB的启动流程其实是一条链芯片上电 → M4核跑Reset_Handler → 你的APP开始执行 → APP通过STM32CubeWB中间件库向M0发送启动协议栈的命令 → M0加载并启动STACK → STACK初始化蓝牙控制器/射频 → APP继续初始化GAP/GATT服务 → 蓝牙广播这条链上任何一环断掉最终表现都是蓝牙不工作。所以一次性烧写FUSSTACKAPP不只是一个烧录动作而是要保证这条链上的三个组件都处于正确的状态和匹配的版本。无论你是刚接触STM32WB的新手还是已经踩坑多次的工程师只要遵循先FUS、再STACK、最后APP的顺序并且保持固件版本来源一致就能避免绝大多数问题。如果在实际操作中遇到报错优先检查FUS版本和STACK版本的匹配关系别急着刷APP——FUS和STACK没搞定APP跑再欢也没用。我在批量烧录时有几个小习惯分享给你一是把STM32CubeProg的日志开成Verbose模式方便定位问题二是准备好一套固定的烧写脚本每次改版本只替换路径三是拿到新批次的芯片先烧一块完整的做测试确认无误再批量操作。这套流程我用了很久基本没有翻过车。最后分享一个小心得曾经有一个项目因为APP工程里改了VECT_TAB_OFFSET导致中断向量偏移结果每次上电都偶发跑飞查了半天最后发现根本不是烧写的问题而是APP本身偏移设置不对。所以如果你烧写完全没问题、但运行不稳定记得回头审视APP工程的链接脚本和启动配置——烧写工具只是个搬运工真正决定系统能不能跑起来的是这三层固件各自的正确性。希望这篇笔记能帮你少走点弯路。
返回列表