OTA升级方案
1 框架
BootLoader(带有APP) + APP +BACKUP
BootLoader(带有APP):引导程序,并带有出厂最低版本APP,升级失败会进入该APP,防止变砖。
APP:升级后的应用程序,如果有升级需要,BootLoader从BACKUP区域复制过来,中间有MD5校验。然后跳转执行。
BACKUP:接收到的*.bin文件,包括MD5,文件大小,升级标志。
2 流程图
3 关键代码
struct AppFlashHead_t
{
char md5[33];
uint32_t appsize;
uint32_t otaflag;
}__attribute__((packed));
void IAP_Jump(uint32_t appaddr)
{
if(((*(u32*)appaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.64K
{
__set_MSP(*(u32*)appaddr); //初始化APP堆栈指针
((void(*)(void))(*(u32*)(appaddr+4)))(); //跳转到APP
}
}
void OTA_Boot(void)
{
#if (ISBOOTLOADER_APP==1)//bootloader
char md5output[33];
uint32_t appsize;
if(IS_OTA_FLAG)
{
appsize = ((struct AppFlashHead_t*)BACKUP_MD5_SIZE_ADDR)->appsize;
if(appsize<2048*70)
{
MD5_Get((char*)BACKUP_ADDR,appsize,md5output);
if(strcmp(md5output,((struct AppFlashHead_t*)BACKUP_MD5_SIZE_ADDR)->md5)==0)
{
Flash_ProgramByWord(APP_ADDR,(uint32_t*)BACKUP_ADDR,((struct AppFlashHead_t*)BACKUP_MD5_SIZE_ADDR)->appsize);
Flash_ProgramByWord(APP_MD5_SIZE_ADDR,(uint32_t*)BACKUP_MD5_SIZE_ADDR,sizeof(struct AppFlashHead_t));
}
}
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(BACKUP_MD5_SIZE_ADDR);
FLASH_Lock();
}
appsize = ((struct AppFlashHead_t*)APP_MD5_SIZE_ADDR)->appsize;
if(appsize<2048*70)
{
MD5_Get((char*)APP_ADDR,appsize,md5output);
if(strcmp(md5output,((struct AppFlashHead_t*)APP_MD5_SIZE_ADDR)->md5)==0)
{
IAP_Jump(APP_ADDR);
}
}
#else
SCB->VTOR = APP_ADDR; //APP
#endif
}