之前做ARM IAP在线更新的程序,发现传统的都是区分高低区,每次下载前要确认当前程序的运行位置,且确认这一步是在上位机实行的。为了减少操作人员的操作难度,我想了个办法,上位机只要点击下载,而不用判断当前程序的运行位置去选择下载文件。
传统IAP特征如下:
1.生成的HEX文件是高区还是低区使用,由分散加载文件中的地址决定
2.用户程序需要中断向量重映射,重映射地址为当前程序开始位置。
我的实现方式是由下位机的bootloader根据当前程序运行位置,修改接收的更新文件,不管接收的文件是高区还是低区的,根据程序标志区的值,强制修改接收的更新文件。
思路如下:
1.相同程序的高低区中断向量表是一样的,只是因为地址不同,其中的个别值不同,且是跟地址相关的
以我的程序为例:
startup.s中的指令LDR R1,=Vectorsaaa (大家做过iap的话,对这条指令应该比较熟悉)
如果低区地址为Vectorsaaa=0x00008000,则HEX文件第0x8100位置的值为801CA0E3(因为0x0008000地址在16位范围内,所以hex文件起始地址为0x8000)
而高区地址为Vectorsaaa=0x00040000的话,hex文件第0x0100位置的值为401aa0e3
(因为0x00040000这个地址超过16位了,所以hex文件的段地址为4,而16位基址以0为起点)
可见只要把801c和401a替换就可实现高低区变换了
同理,只要下位机能找到这些位置,把值替换掉,就可以实现不区分高低区的程序下载了
当然,这样做也牺牲了一些代价,比如如果程序中有使用绝对地址指针对Flash或者Ram等操作
其实也没关系,只是绝对地址要设计成相对地址另外 |