STM32 IAP升级主要是几个步骤:
IAP升级的本质就是将固件文件(.bin文件)写入到flash区域的某个地方,便于程序PC指针能够访问到代码数据。
注意有以下几点:
1.需要类似于BootLoader的一段程序。作用是将下载到备份区域的固件数据,从备份区域复制到APP运行区域。
实现:
- ①需要实现flash读写驱动,用于复制读写在flash区域中的固件数据
- ②需要跳转程序
BootLoader-->APP
运行 - ③需要在跳转的过程中,将所用的外设全部
deinit
- ④设置栈指针,并跳转:
(部分代码) /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
JumpToApplication();
}
2.APP程序作用是将远程固件通过某种通信方式获取下来(一般是串口,或者是基于串口的网络通信方式;或者是网口等)。将获取下来的固件写入到指定的flash区域中,并设置升级标记,使BootLoader能够知道并且复制固件。
实现:
- ①需要通过串口获取固件数据。使用Ymodem协议,协议中有整一套的数据传输校验和可靠逻辑。我们仅仅需要实现串口驱动API和flash读写API即可 ②固件写入完成后,需要重启系统,使之能够运行BootLoader程序,对备份区的固件进行复制。
- ③也是APP中最重要的一点,需要再APP—main函数一开始的位置就设置中断向量表偏移值:
SCB->VTOR = FLASH_BASE | 0x00004000; /* Vector Table Relocation in Internal FLASH */
。
0x00004000为人为指定的偏移值(可以根据自己的APP和BootLoader程序的大小进行合理的选择,但是要注意此值必须要是0x200的整数倍,STM32源码中有说明,请注意。否则跳转不成功)。
3.Keil的设置:
- ①BootLoader项目工程需要将target里面的IROM1设置为
0x8000000
- ②APP项目中需要将target里面的IROM1设置为
0x8004000
(也就是你设置的实际偏移值,但是基础都是以0x8000000
为主,然后|
上偏移值)
4.关于Ymodem协议要注意一点:
- ①协议中这行代码
Serial_PutByte(CRC16);
在Serial_PutByte(ACK);
之后,建议将CRC16
这行代码删除,有时候会造成协议错乱。
(这个我也调试了很久,坑死了哈哈哈!!!)。
整个传输的过程使用的是串口轮询方式发送和接收,所以要注意轮询的阻塞时间,根据实际情况调整。
5.建议几点:
- ①BootLoader中不要有重试和死循环,出现异常后直接跳转到APP正常运行,等待下一次升级请求
- ②APP中需要有标记位用于和BootLoader通信,让BootLoader知道是否需要升级和升级信息相关。
- ③BootLoader跳转的时候一定要注意将其他外设deinit。(如果用到某些应用类型的中断可以尝试关闭调试一下。我的代码在跳转程序过程中并没有关闭中断,仅仅将外设deinit)
相关文件可点击链接 知乎:https://zhuanlan.zhihu.com/p/81133050