[STM32F4] 双引导加载程序

[复制链接]
HomeKit 发表于 2025-8-24 16:00 | 显示全部楼层 |阅读模式
我要在STM32Cube IDE中为不同的STM32微控制器实现双引导加载程序系统,
想法如下:
在闪存的开头有一个“预引导加载程序”。启动时,它会从指定的内存(闪存)区域获取一些数据:实际“真正的”引导加载程序的地址、大小和CRC(我们将此区域称为BL_DATA)。计算引导加载程序的CRC,与存储的值进行比较,如果正确,则跳转到该地址。

引导加载程序通过U(S)ART等待消息。如果收到的消息是刷新用户应用程序的命令,它会分块获取应用程序的二进制文件,经过一些验证后,将新的用户应用程序写入指定地址。

用户应用程序的地址、大小和CRC存储在BL_DATA中。刷新用户应用程序后,引导加载程序会更新用户应用程序的CRC和大小。用户应用程序的地址是固定的。

如果命令是刷新引导加载程序,它会将接收到的程序写入正确的地址:BL_DATA中存储了两个引导加载程序地址,新的引导加载程序地址是不同于当前引导加载程序地址的那个。写入闪存后,引导加载程序将当前引导加载程序地址设置为另一个地址(同时更新大小和计算出的CRC)。

如果没有消息在指定时间内到达,它会直接跳转到用户应用程序(在从BL_DATA读取其地址、CRC等信息后,就像预引导加载程序那样)。

我从实现跳转功能开始。它有效,但需要一些变通方法才能正常工作:

在预引导加载程序的调试配置中,我在启动选项卡中添加了引导加载程序。在预引导加载程序程序中,我检查BL_DATA中存储当前引导加载程序地址的位置,如果那里没有设置任何内容,我会将当前引导加载程序地址写入该位置,然后跳转到该地址。

第一个问题:是否可以通过链接器脚本链接二进制内容,使其存储在指定的内存区域?或者只是简单地执行这个“初始写入”更容易?

有必要将BL_DATA与闪存中的其他区域分开,因为当我想刷新新的引导加载程序或用户应用程序时,必须先擦除该区域。例如,对于STM32F767ZI,最小的擦除“扇区”是32K的扇区,因此在这种情况下,我必须为BL_DATA保留整个扇区。对吗?

引导加载程序在内存中的地址取决于BL_DATA中存储的当前引导加载程序地址。如何配置引导加载程序项目的链接器文件来实现这一点?



公羊子丹 发表于 2025-8-25 07:16 | 显示全部楼层
这思路挺复杂的,不过感觉像是在做“多级跳转”,你是不是考虑过直接用单引导+冗余区域?
周半梅 发表于 2025-8-25 07:17 | 显示全部楼层
我之前在F4上试过双boot,确实要为BL_DATA单独留一个sector,否则擦写的时候会把数据搞没。
帛灿灿 发表于 2025-8-25 07:18 | 显示全部楼层
链接器那边可以用不同的基址编译两个bootloader项目,比如0x08008000和0x08010000。
童雨竹 发表于 2025-8-25 07:19 | 显示全部楼层
初始写BL_DATA没问题,反正只做一次,但你要注意掉电情况,不然可能CRC全是0就跳不动了。
万图 发表于 2025-8-25 07:20 | 显示全部楼层
你考虑过把BL_DATA放到EEPROM或者BKPSRAM里吗?这样就不用浪费32K的扇区。
Wordsworth 发表于 2025-8-25 07:21 | 显示全部楼层
我感觉USART刷新的逻辑稳妥,唯一就是写flash的时候一定要搞好中断屏蔽,不然数据容易错。
Bblythe 发表于 2025-8-25 07:22 | 显示全部楼层
其实可以在预boot里加一个小函数:扫描两个bootloader地址,看哪个CRC正确,就直接跳。
Pulitzer 发表于 2025-8-25 07:22 | 显示全部楼层
配置链接器最简单就是建两个不同的工程,各自独立输出bin,然后预boot从BL_DATA选择跳转。
Uriah 发表于 2025-8-25 07:23 | 显示全部楼层
这种架构下,debug的时候可能比较痛苦,你是不是要加个强制进入boot的按键?
Clyde011 发表于 2025-8-25 07:25 | 显示全部楼层
多说一句,STM32F7扇区挺大,预boot可以很小,完全可以放在第一个sector里,把后面分区灵活利用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

43

帖子

0

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