不积跬步,无以至千里
前言
公司项目中使用IAP升级,主控使用N32L40X系列。内部flash空间大小为128K,使用CST812T触摸IC,空板需要使用IIC在线升级导入配置文件。
以上为项目背景,主控资源紧张,对地址设置就比较抠搜 节省。测试发现升级后Boot搬运升级固件后跳转APP,程序直接挂掉,跑不起来。
原因分析
1、代码查验
IAP升级原理不做赘述,升级方式采用单区升级。下载固件存入downlad区,进入boot验证文件有效性后,搬运至APP中。一直在用的通用驱动,这次竟然出现问题了。查验相关代码也没发现问题。
1、设置向量表
void NVIC_Configuration(void)
{
#ifdef VECT_TAB_RAM
// Set the Vector Tab base at location at 0x20000000
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH, VECT_TAB_ADDRESS);
#endif
}
2、设置堆栈地址
__asm void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
3、iap跳转
void iap_load_app(u32 appxaddr)
{
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP.
}
}
2、升级文件查验
使用J-flash打开脚本升级文件,对照特定地址信息查验标志位、版本号、校验码、APP地址
郁闷的是,按逻辑流程发现也没有问题。调试中也发现boot中正常搬运至app,那就好办了,中断向量表偏移问题。
3、向量表查验
开始以为是犯了低级错误,偏移地址与设置地址不对应,查验之后发现也没有问题。这会儿有点挠头了,看着设置地址,突然想到
会不会是设置的偏移地址非法
跑去翻一番M4F内核指南,果然有问题
人家有规定对其方式,所以我设置的地址非法了。
简单来说我所使用的主控中断向量有86+16=102个,需要将其扩展为下一个2的整数次方,即128,则大小为128*4=512,得到0X200。也就是说新向量表的基地址需要以0X200对齐。
修改地址范围,以0X200进行向量表对齐,测试OK,记录一下,也确实没有注意到有这个坑。
总结
IAP升级原理不复杂,针对IAP升级异常的,按顺序分析就好了。文件下载是否正常、boot验证搬运是否正常、是否正常跳入boot。个人也调了不少IAP升级流程了,这个还是第一次注意到,记录一下。
如有错漏,敬请指正!