我使用S记录文件通过引导程序更新STM32L4R5的MCU固件应用程序。文件中S记录的大多数行地址位于闪存行的16字节偏移处(例如0x08010010、0x08010020、0x08010030(,但也有一些位于8字节和12位偏移处,如以下所示:
s3150808f7200000000000c0153f00000000dcfd135feS30D0808F730E416F87F0100000049s3090808f738e50108c8S3090808F73CC1010108E8S3150808F740000000010002001000040100002004000E0
Bootloader按照接收S记录的顺序将16字节闪存行作为双字写入,用0xFF填充空白以保持它们未编程。在这种情况下,写入地址0x0808F730的闪存行发生三次,如下所示:
0808F730 E416F87F01000000FFFFFFFFFFFFF0808F7300808F730 FFFFFFFFFFFF FFFFFF C1010108
但是,地址0x0808F730读回为:
0808F730 E416F87F01000000FFFFFFFFFFFFF
因此,应用程序不会启动,而是进入错误处理程序。我转储了用调试器编程的操作应用程序和用Bootloader编程的这个应用程序的闪存。此行显示了唯一的区别。
有人知道闪存行是否只接受对闪存行的一次写入吗?这是怎么回事,我遗漏了什么吗?
更新S记录文件以仅使用16字节对齐写入
为了降低引导加载程序的复杂性,引导加载程序在写入闪存时只接受对16字节对齐地址的写入,这并不罕见。解决方案是对S记录进行后处理,将所有未对齐的写入合并为每个对齐地址的单个写入。
合并3写入1
因此,对于地址0x0808F730
,将3个S记录合并为1个S记录
0808F730 E416F87F01000000FFFFFFFFFFFFFFFF
0808F730 FFFFFFFFFFFFFFFFE5010108FFFFFFFF
0808F730 FFFFFFFFFFFFFFFFFFFFFFFFC1010108
----------------------------------------- merge
0808F730 E416F87F01000000E5010108C1010108
Bootloader按照接收S记录的顺序将16字节闪存行作为双字写入,并用0xFF填充空白以保持它们未编程。在这种情况下,对地址0x0808F730处的闪存行的写入发生三次,如下所示:0808F730 e416f87f01000000ffffffffff
如果您在编程一次后请求写入地址0x0808F730,则在再次编程之前,双字区域需要处于擦除状态(0xFFFFFFFFFFFFFFFF(。只需将数据打包到缓冲区中,然后以两个字为增量进行写入。
我发现了这个问题的原因。看起来Flash行只能写入一次。这可能与ECC有关。我所做的是将S记录中的三个短单词组合成一个16字节的单词,并立即写入该行。