关于IAP程序做跳转的时候检查栈顶地址问题

发布于 2022-07-20  564 次阅读


u32 app_addr = QBOOT_APP_ADDR;
u32 stk_addr = *((__IO uint32_t *)app_addr);
app_func_t app_func = (app_func_t)(*((__IO uint32_t *)(app_addr + 4)));
//检查中断向量中,复位向量的地址是否在0x08000000以上(首地址偏移4字节为复位中断向量地址0x08010271)
(((u32)app_func & 0xff000000) != 0x08000000)
//检查app栈顶地址是否在0x20000000以上(首地址为栈顶地址0x20018b78)
((stk_addr & 0x2ff00000) != 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)


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。