OpenClaw系列032:Bootloader设计——从Flash加载到固件升级
一、一次现场升级失败的血泪史
去年冬天,某客户现场设备批量变砖。现象很统一:上电后LED狂闪三次,然后死寂。远程抓日志,发现Bootloader在CRC校验阶段直接跳到了错误处理——0x1FFF0000的复位向量被读成了全0xFF。拆机量Flash供电,3.3V正常,但用编程器读Flash内容,发现前4KB全是干净的0xFF,后面数据完好。问题出在哪?客户反馈说升级过程中意外断电了,但我们的Bootloader明明有备份区啊。
查了两天,真相让人哭笑不得:Bootloader在擦写主程序区时,把存放自身中断向量表的Flash扇区也擦掉了。因为芯片Flash扇区大小是4KB,而Bootloader代码刚好占满前两个扇区,第三个扇区起始就是主程序区。升级时为了省事,直接擦除了从0x08004000开始的连续8个扇区——恰好把Bootloader自己的中断向量表所在的0x08000000~0x08000FFF给覆盖了。断电那一刻,Bootloader自己把自己阉了。
这个教训让我重新审视Bootloader设计的每一个细节。今天这篇笔记,就从Flash加载、分区规划、升级协议到异常恢复,把踩过的坑一一摊开。
二、Flash分区:别把鸡蛋放在一个篮子里
先看一个典型的Cortex-M3/M4芯片Flash布局。以STM32F103为例,Flash起始0x08000000,大小512KB,扇区大小不均匀(前4个16KB,后面64KB)。设