IAP
In Application Programming
可经过USB,CAN,UART,I2C,SPI等接口实现app
IAP流程
Bootloader程序:接收升级程序,更新到flash指定地址;跳转到指定地址执行
STM32设置
①:为Bootloader预留0x10000空间
②:设置APP程序的起始地址
③:中断向量表的偏移量设置
④:生成bin文件
详见:https://blog.csdn.net/zhangxuechao
⑤:代码更新FLASH固件,执行FLASH代码url
举例.net
//appxaddr:应用程序的起始地址 //appbuf:应用程序CODE. //appsize:应用程序大小(字节). void iap_write_appbin(u32 appxaddr, u8 *appbuf, u32 appsize) { u32 t; u16 i = 0; u32 temp; u32 fwaddr = appxaddr; //当前写入的地址 u8 *dfu = appbuf; for(t = 0; t < appsize; t += 4) { temp = (u32)dfu[3] << 24; temp |= (u32)dfu[2] << 16; temp |= (u32)dfu[1] << 8; temp |= (u32)dfu[0]; dfu += 4; //偏移4个字节 iapbuf[i++] = temp; if(i == 512) { i = 0; STMFLASH_Write(fwaddr, iapbuf, 512); fwaddr += 2048; //偏移2048 512*4=2048 } } if(i) { STMFLASH_Write(fwaddr, iapbuf, i); //将最后的一些内容字节写进去. } } //跳转到应用程序段 //appxaddr:用户代码起始地址. void iap_load_app(u32 appxaddr) { if(((*(vu32 *)appxaddr) & 0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法. { jump2app = (iapfun) * (vu32 *)(appxaddr + 4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32 *)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); //跳转到APP. } else { printf("iap_load_app error 0x%x\r\n", *(vu32 *)appxaddr); } } //执行FLASH代码 void iap_load_flash(void) { if((*(vu32 *)(FLASH_APP_ADDR + 4) & 0xFF000000) == 0x08000000) //判断是否为0X08XXXXXX. { iap_load_app(FLASH_APP_ADDR);//执行FLASH APP代码 } else { printf("iap_load_flash error 0x%x\r\n", *(vu32 *)FLASH_APP_ADDR); } } //更新FLASH固件 void update_flash(u8 *appbuf, u32 appsize) { if(appbuf == NULL) { return; } if((*(vu32 *)(appbuf + 4) & 0xFF000000) == 0x08000000) //判断是否为0X08XXXXXX. { iap_write_appbin(FLASH_APP_ADDR, appbuf, appsize); //更新FLASH代码 printf("固件更新完成!\r\n"); } else { printf("update_flash error 0x%x\r\n", *(vu32 *)appbuf); } }