概述
目前本人在工作中使用的大多为STM32系列的MCU,该系列的MCU均可支持IAP升级。
对IAP升级不了解的同学可参考之前写的文章《IAP(In Application Program)在线应用编程》进行一些基础知识的了解。
实现思路
1.使用Bootloader和Application分区的方式进行升级,防止升级过程中掉电,导致无法恢复。
2. Bootloader一般在烧录后,固化到板子中,一般情况下不支持IAP方式升级Bootloader。
3. 减少重启过程,仅在升级结束后重启一次。
4. 数据传输完成后需要进行校验。防止传输或者写入错误导致整机启动异常。
升级流程
待补
- 跳转代码实现
typedef void (*pFunction)(void);
void vBooloader_load(void)
{
uint32_t JumpAddress;
pFunction Jump_To_Boot;
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (0x8000000 + 4);
Jump_To_Boot = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) 0x8000000);
Jump_To_Boot();
}
填过的坑
- Application的中断无法触发。
需要在Application的程序开启重定向MCU的中断向量表,将指到Application的首地址。
在编译器编译的时候,默认会将中断向量表变异到程序的起始位置,所以我们将中断向量表偏移到Application的烧录起始位置即可。 - Application跳转到bootloader后,系统直接跑飞,但是在断电后可正常升级。
在Application跳转前禁用了所有中断,但在Bootloader中开启中断后,之前暂存的中断标记不会自动清除,MCU会自动跳转寻找相应的中断处理函数,从而导致程序直接跑飞。
解决思路:
1.跳转到Bootloader前清除掉所有的中断状态寄存器,同步失能所有的中断。
2.在bootloader中不开启中断,所有的操作使用查询的方式进行。(目前采用该方案)
后续优化
- 增加对固件版本的加密和解密功能。
- 调高数据交互的效率。