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); } }