[STM32L0] STM32L072CZ通过软件跳转进入 DFU Bootloader

[复制链接]
50|2
codekid 发表于 2026-10-27 10:06 | 显示全部楼层 |阅读模式

我想把 STM32F072 项目迁移到 STM32L072。
在原来 F072 项目中,我可以通过一段放在SystemInit之前的函数,用软件方式跳转到 DFU Bootloader。
我把这段代码移植到 L072,将 Bootloader 程序地址修改为0x1FF00004,但是无法正常工作。
是双存储区的原因吗?有没有办法实现F072的这个功能?

spicy 发表于 2026-10-27 11:08 | 显示全部楼层
地址改成 0x1FF00004 本身没错,但只改地址不够。STM32L0 在跳转前需要设置 SYSCFG->CFGR1 的 remap 位,把 System Memory 映射到 0x00000000,否则 bootloader 的向量表取址会出错。
麻花油条 发表于 2026-10-27 11:21 | 显示全部楼层
跳转函数的实现位置很重要,不能放在可能被编译器优化掉或位于即将被擦除的Flash扇区中,最好将该函数定义为RAM函数或确保其在跳转过程中不被覆盖。
classroom 发表于 2026-10-27 11:41 | 显示全部楼层
双存储区确实是关键差异。L072 的 bootloader 带双 Bank 启动检查逻辑,只要 Bank1 或 Bank2 中有有效用户代码(栈指针指向 SRAM),bootloader 就会直接跳回用户程序,根本不进 DFU。
cr315 发表于 2026-10-27 14:12 | 显示全部楼层
有人通过逆向找到一个绕过地址 0x1FF00369,跳过 bootloader 的 Bank 检查直接进入 DFU 流程。但这是 hack 手段,ST 随时可能在后续版本改掉,不适合量产。
duo点 发表于 2026-10-27 15:09 | 显示全部楼层
更稳妥的做法是走“标记+复位”路径:在 RAM 里写一个 magic word,然后触发 NVIC_SystemReset(),在启动早期检查该标记,满足条件就配置好 VTOR 和 MSP 再跳转。F072 上那种直接在 SystemInit 里跳的方式在 L0 上容易被 bootloader 的启动逻辑拦截。
jcky001 发表于 2026-10-27 16:15 | 显示全部楼层
测试是否真正进入了 DFU,不要只看代码有没有跑飞。用 USB 分析仪或串口发 0x7F,如果收到 0x79 回复,才说明 bootloader 在正常响应。
flycamelaaa 发表于 2026-10-27 16:20 | 显示全部楼层
如果坚持用直接跳转,除了设置 remap 位,还要关闭所有外设时钟、禁用 PLL、关中断并清除挂起中断。bootloader 不会替你清理这些状态,残留配置可能导致 USB 无法枚举。
onlycook 发表于 2026-10-27 16:56 | 显示全部楼层
另一个思路是干脆不用软件跳转 DFU。把 BOOT0 引脚通过 GPIO 或跳线控制,配合复位操作进入 System Memory,虽然多一个引脚动作,但行为完全由硬件保证,不受 bootloader 版本影响。
probedog 发表于 2026-10-27 18:12 | 显示全部楼层
有人提到在 BOOT0 接地的情况下,即使跳进了 System Bootloader,它仍然会检查 BOOT0 和双 Bank 状态,然后跑回用户程序。这说明 L0 的 bootloader 进入条件是硬件和选项字节共同决定的,不是单纯跳地址就能覆盖。
solty 发表于 2026-10-27 19:35 | 显示全部楼层
如果选择擦除用户 Flash 首字来让 bootloader 认为“无有效代码”,操作要非常小心。这相当于暂时让设备失去可运行的程序,一旦 DFU 过程失败或断电,设备就变砖了,必须有恢复手段。
spicy 发表于 2026-10-27 19:45 | 显示全部楼层
L072 的 bootloader 占用 System Memory 从 0x1FF00000 开始,向量表在 0x1FF00000,复位向量在 0x1FF00004。跳转函数应该先 __set_MSP(*(uint32_t*)0x1FF00000),再跳 0x1FF00004,直接跳后者而忽略 MSP 设置在某些状态下会栈溢出。
stormwind123 发表于 2026-10-27 20:13 | 显示全部楼层
双存储区功能本身是为 FOTA 设计的,AN4767 里提到了用 SYSCFG_CFGR1 的 UFB 位做 Bank 交换。如果项目本身就需要现场升级,可以考虑把 DFU 逻辑整合进双 Bank 切换流程,而不是硬跳 ST 的 ROM bootloader。
内政奇才 发表于 2026-10-27 20:28 | 显示全部楼层
有人实测发现 ST 更新过 L0 的 bootloader,新版本只要任一 Bank 有有效栈指针就跳回用户代码。这意味着基于旧版 bootloader 逆向出来的绕过方法,在新批次的芯片上可能直接不工作。做技术选型时要把这个风险算进去。
七毛钱 发表于 2026-10-27 20:57 | 显示全部楼层
迁移 F0 到 L0 时,AN2606 明确写了:带 Dual Bank Boot 的器件,从用户代码跳 System Memory 之前必须先用 SYSCFG 把 bootloader 重映射到 0x00000000。很多人移植失败就是漏了这一步,只改了地址。
今天会画卧蚕吗 发表于 2026-10-27 21:30 | 显示全部楼层
如果产品对可靠性要求高,建议放弃“纯软件跳 ROM DFU”的方案。要么用自定义 IAP(自己写 bootloader 放在 Flash 开头),要么用双 Bank 自更新。依赖 ROM bootloader 的未文档化行为,换一个芯片批次或固件版本就可能失效。
又见江南雨 发表于 2026-10-28 10:21 | 显示全部楼层
STM32L072的系统Bootloader起始地址确实是0x1FF00000,但跳转时必须指向该地址处的复位向量表第二个字,即0x1FF00004,这点与F0系列逻辑一致,地址本身没有填错。
在海边聆听 发表于 2026-10-28 11:07 | 显示全部楼层
仅修改跳转地址是不够的,STM32L0系列在从应用代码跳转到系统Bootloader前,必须手动关闭所有外设中断并清除NVIC中的挂起标志,否则USB枚举会因中断干扰而失败。
才没有脸红 发表于 2026-10-28 11:49 | 显示全部楼层
L072芯片内部包含EEPROM和双Bank Flash结构,但这不影响系统Bootloader的入口地址,跳转失败通常与存储区架构无关,而是与跳转前的现场清理工作有关。
故里说长安 发表于 2026-10-28 14:22 | 显示全部楼层
在调用跳转函数前,必须执行__disable_irq()全局关中断,并且要确保Deinit所有已初始化的外设,特别是USB和时钟配置,恢复到复位默认状态。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

82

主题

853

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部