问题背景
我要做一个boot,我想要将APP之前的一页flash的首半字作为判断APP是否完整的条件。于是在boot中用绝对定位指令(const uint32_t IAP_FLAG attribute((at(0x8004A38))) = 0xAAAA;)对该地址进行初始化,然后在我的boot更新完APP后擦掉这一页(太粗放,未经慎重思考)。我可以在APP中对这一页的首地址赋值0xAAAA以重新进入boot。然而代码并没有按我想象的方式工作,在我第一次更新完APP后,boot就再也不能正常工作了。
原因
经过查看boot的bin文件我发现在0x8004A38开是的那页flash跟我想象的不一样,开始的半字值为0xAAAA,但是在其后并不是全为0xFFFF。尽管在我不用绝对定位指令时该boot的大小不超过11K。也就是说在我擦除的这一页出现了程序。我擦除了一部分boot的程序,boot当然就运行不正常了。
MDK的链接程序并没有像我想象的那样把IAP_FLAG放在整个boot程序的末尾,在其后还放了其它程序。
解决方案
解决方案有三个
1.编写MDK链接脚本,也就是所谓的分散加载文件,人为地控制链接过程。
2.弃用绝对定位指令
3.不擦除一整页,该方案节约了近1K的flash