IAP跳转的地址判断,为什么是0x2FFE0000 或者 0xFF000000 之类?
if(((*(vu32*)(app_addr+4))&0xFF000000)==0x08000000)
if(((*(vu32*)ck_addr)&0x2FFE0000)==0x20000000)
参看过ST官方文档或者原子的IAP大概都知道这个问题,做地址跳转前会有一个检查栈顶是否合法的条件判断。(sram rom 的地址空间段 根据实际取,这里例举的是st和gd的芯片)
1.首先FLASH的地址范围是0X08000000开始的。所以我们从内存上取出来的数据也应该是这个范围里,这里做检查程序地址是否合法。对于app_addr+4 , 结合图片一看,自然一目了然了。由于我们只需要判断是不是0x08000000,所以只需要 &0xFF000000 ,后面的地址会根据使用增长变化 ,但是它的最高位肯定是08 ,可以看看数据手册的flash空间大小起始地址等。因此最高位逻辑与的是FF。
2.st系列或者国内的大部分替代st芯片,其实内部的sram和rom地址都差不多,以st为128Kb为例,堆栈地址的空间是0x20000000 - 0x2001FFFF,所以我们逻辑与上0x2FFE0000是没问题的,本身最大就是0x2001FFF,(不用管SP的bit16 - 0,只需要检查bit27-17)如果判断出来超过了就有问题。另外如果你是512Kb的sram,那么就该写 0x2FF80000,512Kb的就是0x20000000 - 0x2007FFFF( 不用管SP的bit18 - 0,只需要检查bit27-19)
if(((*(vu32*)ck_addr)&0x2FF80000)==0x20000000)
64K一般就是对比 0x2FFF0000 (不用管SP的bit15 - 0,只需要检查bit27-16)
if(((*(vu32*)ck_addr)&0x2FFF0000)==0x20000000)
注1:查了下历史,ST32最早的时候内部ram的大小基本在128Kb以内,官方的IAP_DEMO也是写的
这一句,小于128的使用0x2FFE0000也基本没问题,就一直在沿用,也是为什么很多列子看
到的都是这个的原因。最好还是按照自己实际的修改。
注2:判断条件是((*(vu32*)ck_addr)&0x2FFE0000) 必须是栈地址没有超过128,而且堆
空间占用太大了的话,超了128,那么栈的地址也只能从128以后的位置开始,这种情况也必须修
改判断的条件值。(PS 用512Kb SRAM 的那位老兄也真是奢侈啊!!!),总之既要检查自己
代码的SRAM使用大小,也要检查芯片本身的SRAM大小,两者结合修改。