STM32 IAP入门示例

一、IAP介绍

IAP(In applicating Programing)即应用编程。可以实现在使用过程中,通过串口等直接对程序进行更新,而不需要使用烧写器。

以下是找到的一个可以使用的IAP demo(Ymode传输模式)

https://github.com/dong930623/IAP

使用时注意以下几点

1.APP需要设置偏移,这里使用的是STMF103RBT6芯片,所以偏移设置10000 所以IROM为0x8010000

2.初始化中也要进行偏移的设置

   SCB->VTOR = FLASH_BASE | 0x10000;

3.编写bin文件

   使用IAP升级时,需要使用二进制文件,即.bin文件

有IAP时,程序运行的流程图

二、IAP的实现

//接收到IAP更新标志,进行更新
  1 /**
  2   * Íùij¸öµØÖ·ÇøÓòдÈëÊý¾Ý
  3   * iAddress ÆðʼµØÖ· buf Êý×éÖ¸Õë iNbrToRead ÐèҪдÈëÊý×éµÄ³¤¶È´óС  
  4   */
  5 uint16_t Flash_Write_Without_check(uint32_t iAddress, uint8_t *buf, uint16_t iNumByteToWrite) {
  6     uint16_t i;
  7     volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
  8     i = 0;
  9     
 10 //    FLASH_UnlockBank1();
 11     while((i < iNumByteToWrite) && (FLASHStatus == FLASH_COMPLETE))
 12     {
 13       FLASHStatus = FLASH_ProgramHalfWord(iAddress, *(uint16_t*)buf);
 14       i = i+2;
 15       iAddress = iAddress + 2;
 16       buf = buf + 2;
 17     }
 18     
 19     return iNumByteToWrite;
 20 }
 21 /**
 22   * Íùij¸öµØÖ·ÇøÓòдÈëÊý¾Ý
 23   * iAddress ÆðʼµØÖ· buf Êý×éÖ¸Õë iNbrToRead ÐèҪдÈëÊý×éµÄ³¤¶È´óС  
 24   */
 25 int Flash_Write(uint32_t iAddress, uint8_t *buf, uint32_t iNbrToWrite) {
 26                 /* Unlock the Flash Bank1 Program Erase controller */
 27         volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
 28         uint32_t secpos;
 29         uint32_t iNumByteToWrite = iNbrToWrite;
 30         uint16_t secoff;
 31         uint16_t secremain;  
 32           uint16_t i = 0;    
 33         uint8_t tmp[PAGE_SIZE];
 34         
 35         FLASH_UnlockBank1();
 36         secpos=iAddress & (~(PAGE_SIZE -1 )) ;//ÉÈÇøµØÖ· 
 37         secoff=iAddress & (PAGE_SIZE -1);     //ÔÚÉÈÇøÄÚµÄÆ«ÒÆ
 38         secremain=PAGE_SIZE-secoff;           //ÉÈÇøÊ£Óà¿Õ¼ä´óС 
 39         
 40         
 41         if(iNumByteToWrite<=secremain) secremain = iNumByteToWrite;//²»´óÓÚ4096¸ö×Ö½Ú
 42         
 43         while( 1 ) {
 44             Flash_Read(secpos, tmp, PAGE_SIZE);   //¶Á³öÕû¸öÉÈÇø
 45             for(i=0;i<secremain;i++) {       //УÑéÊý¾Ý
 46                    if(tmp[secoff+i]!=0XFF)break;       //ÐèÒª²Á³ý 
 47                }
 48             if(i<secremain) {  //ÐèÒª²Á³ý
 49                 FLASHStatus = FLASH_ErasePage(secpos); //²Á³ýÕâ¸öÉÈÇø
 50                 if(FLASHStatus != FLASH_COMPLETE)
 51                   return -1;
 52                 for(i=0;i<secremain;i++) {   //¸´ÖÆ
 53                         tmp[i+secoff]=buf[i];   
 54                 }
 55                 Flash_Write_Without_check(secpos ,tmp ,PAGE_SIZE);//дÈëÕû¸öÉÈÇø  
 56             } else {
 57                 Flash_Write_Without_check(iAddress,buf,secremain);//дÒѾ­²Á³ýÁ˵Ä,Ö±½ÓдÈëÉÈÇøÊ£ÓàÇø¼ä.
 58             }
 59             
 60             if(iNumByteToWrite==secremain) //дÈë½áÊøÁË
 61                 break;
 62             else {
 63                 secpos += PAGE_SIZE;
 64                 secoff = 0;//Æ«ÒÆλÖÃΪ0 
 65                 buf += secremain;  //Ö¸ÕëÆ«ÒÆ
 66                 iAddress += secremain;//дµØÖ·Æ«ÒÆ    
 67                 iNumByteToWrite -= secremain;  //×Ö½ÚÊýµÝ¼õ
 68                 if(iNumByteToWrite>PAGE_SIZE) secremain=PAGE_SIZE;//ÏÂÒ»¸öÉÈÇø»¹ÊÇд²»Íê
 69                 else secremain = iNumByteToWrite;  //ÏÂÒ»¸öÉÈÇø¿ÉÒÔдÍêÁË
 70             }  
 71          }  
 72         FLASH_LockBank1();
 73         return iNbrToWrite; 
 74 }
 75 
 76 /**
 77   * ´Óij¸öµØÖ·ÇøÓò¶Á³öÊý¾Ý
 78   * iAddress ÆðʼµØÖ· buf ´æ·ÅµÄÊý×éÖ¸Õë iNbrToRead ÐèÒª¶Á³öµÄ³¤¶È´óС  
 79   */
 80 int Flash_Read(uint32_t iAddress, uint8_t *buf, int32_t iNbrToRead) {
 81             int i = 0;
 82             while(i < iNbrToRead ) {
 83                *(buf + i) = *(__IO uint8_t*) iAddress++;
 84                i++;
 85             }
 86             return i;
 87 }
 88 
 89 /*******************************************************************************  * 
 90 Function Name  : SystemReset 
 91  * Description    : Configures the port pin connected to the push button. GPIO_D_4 
 92  * Input          : None * Output         : None 
 93  * Return         : None  ********************************************************
 94  ***********************/ 
 95   __asm void SystemReset(void) 
 96   {   MOV R0, #1           //;    
 97   MSR FAULTMASK, R0    //; 清除FAULTMASK 禁止一切中断产生
 98   LDR R0, =0xE000ED0C  //;  
 99   LDR R1, =0x05FA0004  //;    
100   STR R1, [R0]         //; 系统软件复位
101    }

void downfile(){ uint8_t key = 1; if((mGPSSend.GPSSendBuf[mGPSSend.TailPoint].Buf[0] == '$') && (mGPSSend.GPSSendBuf[mGPSSend.TailPoint].Buf[1] == '1') && (mGPSSend.GPSSendBuf[mGPSSend.TailPoint].Buf[2] == '2') && (mGPSSend.GPSSendBuf[mGPSSend.TailPoint].Buf[3] == '3') && (mGPSSend.GPSSendBuf[mGPSSend.TailPoint].Buf[4] == '4') ){ USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); Flash_Write(IsDownLoadFlagAddress, &key,1); RTC_ITConfig(RTC_IT_SEC, DISABLE); SystemReset(); while(1); } }

  

 三、IAP具体更新流程

1.正常运行下

2.输入特定标识,进入IAP更新

3.在SecureCRT选择Transfer中Send Ymodem 选择生成的bin文件,Add然后点击OK

传输完成

 更新后,重新启动的程序

原文地址:https://www.cnblogs.com/-Donny/p/7647507.html