天天看點

STM32 IAP 更新功能

IAP

In Application Programming

可通過USB,CAN,UART,I2C,SPI等接口實作

IAP流程

Bootloader程式:接收更新程式,更新到flash指定位址;跳轉到指定位址執行

STM32 IAP 更新功能

STM32設定

①:為Bootloader預留0x10000空間

②:設定APP程式的起始位址

STM32 IAP 更新功能

③:中斷向量表的偏移量設定

STM32 IAP 更新功能

④:生成bin檔案

詳見:https://blog.csdn.net/zhangxuechao

⑤:代碼更新FLASH固件,執行FLASH代碼

舉例

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

繼續閱讀