STM32L4R5 Bootloader刷写S-record时闪存写入异常问题咨询
STM32L4R5 Bootloader闪存写入问题解答
问题描述
我正在通过Bootloader使用S-record文件更新STM32L4R5的MCU固件应用。文件中大部分S-record行的地址处于闪存行的16字节偏移位置(如0x08010010、0x08010020、0x08010030),但存在部分处于8字节和12字节偏移的记录,例如:
S3150808F7200000000000C0153F00000000DCCFD135FE S30D0808F730E416F87F0100000049 S3090808F738E5010108C8 S3090808F73CC1010108E8 S3150808F74000000010002001000040100002004000E0
Bootloader按接收S-record的顺序以双字为单位写入16字节闪存行,空位置填充0xFF以保持未编程状态。在此场景下,地址0x0808F730所在的闪存行被写入三次,具体如下:
0808F730 E416F87F01000000FFFFFFFFFFFFFFFF 0808F730 FFFFFFFFFFFFFFFFE5010108FFFFFFFF 0808F730 FFFFFFFFFFFFFFFFFFFFFFFFC1010108
但读回地址0x0808F730的数据为:
0808F730 E416F87F01000000FFFFFFFFFFFFFFFF
这导致应用无法启动,进入错误处理程序。对比调试器刷写的可运行应用与Bootloader刷写的闪存镜像,发现仅该行存在差异。
请问闪存行是否仅支持单次写入?此场景下正确的操作方式是什么,我是否遗漏了关键要点?
解答
1. STM32闪存的核心特性
STM32的闪存并非只能单次写入,但仅支持从0xFF向0x00修改,无法反向修改已置0的位。也就是说,一旦某个闪存位被编程为0,后续的普通编程操作无法将其改回1(包括0xFF对应的全1状态)。
你的问题中,第一次写入时已经将0x0808F730开始的8字节设置为非0xFF值,后续两次写入尝试修改这些已置0的位时,操作会直接失效,因此读回数据仍保留第一次写入的结果。
2. 问题根源
Bootloader的写入逻辑存在缺陷:按S-record接收顺序逐块写入,每次写入时填充空白为0xFF,但没有考虑闪存的位修改限制。后续写入的内容中,与已编程位置重叠的部分无法覆盖原有数据,导致最终闪存内容不完整。
3. 正确操作方式
- 预先合并同一页的所有数据:先解析所有S-record记录,按地址排序,将同一闪存页内的所有数据合并为完整的页数据(未指定的位置保持
0xFF)。 - 先擦除再写入:STM32闪存擦除是以页为单位(STM32L4R5的闪存页大小为2KB),擦除后整页数据变为
0xFF。对每个需要更新的页,先执行擦除操作,再一次性写入合并后的完整页数据。 - 避免分块重复写入同一页:不要按S-record的接收顺序逐块写入,而是确保每个页只被擦除一次,然后写入所有需要的数据。
内容的提问来源于stack exchange,提问作者Shadow
相关产品推荐
相关产品推荐

