STM32 IAP 升級功能

IAP
In Application Programming
可經過USB,CAN,UART,I2C,SPI等接口實現app

IAP流程
Bootloader程序:接收升級程序,更新到flash指定地址;跳轉到指定地址執行
1
STM32設置
①:爲Bootloader預留0x10000空間
②:設置APP程序的起始地址
2
③:中斷向量表的偏移量設置
2
④:生成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);
   }
}
相關文章
相關標籤/搜索