你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F051 IAP源码分享

[复制链接]
kaierwen 发布时间:2016-6-24 16:40

IAP需要有两个工程,第一个是Bootloader,第二个是Application

同时将这两份程序放在mcu的flash里的不同位置,启动时自动进入bootloader(可选择)进行iap,成功后跳转至application。


完整源码见最后内容,这里先瞎扯一点点:


那么IAP问题简化成三个步骤,

Step1:做Bootloader工程

Step2:做Application工程

Step3:烧进Flash的不同位置


Step1:需要做这些事情:

1:初始化IAP相关外设

2:下载文件(ymodem协议)

3: 写入Application程序存储空间

鸡:

     IAP_Init();

     SerialDownload();

具体实现:

  1. /**
  2.   *@brief  Initialize the Iap module(leddelay usart and unlock flash)
  3.   *@param  None
  4.   *@retval None
  5.   */  
  6. void IAP_Init(void)  
  7. {  
  8.   uint32_tt;  
  9. LEDInit();                  /*--Set up Led to Output signal  --*/  
  10. SysTickInit();                 /*-- Config System Tick for delay functions --*/  
  11. USART_Configuration();            /*-- Config usart to download .bin --*/  
  12. FLASH_If_Init();                     /*-- Unlock Flash --*/  
  13. for(t = 2000; t > 10; t >>= 1 )        /*-- LED1 blink 3 second indeicate IAPbegin--*/  
  14.   {  
  15.    LEDTogle(1); delayms(t);  
  16.   }  
  17. }  
  18.    
  19.    
  20. void SerialDownload(void)  
  21. {  
  22. uint8_t Number[10] = {0};  
  23. int32_t Size = 0;  
  24.    
  25.   SerialPutString("Waitingfor the file to be sent ... (press 'a' to abort)\n\r");  
  26. Size = Ymodem_Receive(&tab_1024[0]);  
  27.   if(Size > 0)  
  28.   {  
  29.    SerialPutString("\n\n\r Programming CompletedSuccessfully!\n\r--------------------------------\r\n Name: ");  
  30.    SerialPutString(FileName);  
  31.    Int2Str(Number, Size);  
  32.    SerialPutString("\n\r Size: ");  
  33.    SerialPutString(Number);  
  34.    SerialPutString(" Bytes\r\n");  
  35.    SerialPutString("-------------------\n");  
  36.   }  
  37. else if (Size == -1)  
  38.   {  
  39.    SerialPutString("\n\n\rThe image size is higher than the allowedspace memory!\n\r");  
  40.   }  
  41. else if (Size == -2)  
  42.   {  
  43.    SerialPutString("\n\n\rVerification failed!\n\r");  
  44.   }  
  45. else if (Size == -3)  
  46.   {  
  47.    SerialPutString("\r\n\nAborted by user.\n\r");  
  48.   }  
  49. else  
  50.   {  
  51.     SerialPutString("\n\rFailedto receive the file!\n\r");  
  52.   }  
  53. }  
复制代码

Step2:需要这样干:

在Application工程中程序运行的一开始加上如下中断拷贝即可

  1. void InterruptRemap(void)  
  2. {  
  3.        u8 i;  
  4.        u32 Data;  
  5.        u32 Address;  
  6.        for(i=1;i<48;i++)  
  7.        {  
  8.                Data =  *(__IOu32*)(0x08003000+i*4);  
  9.                Address = 0x20000000 + (i*4);  
  10.                 *(__IO u32*)Address= (u32)Data;  
  11.        }  
  12.        SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
  13. }  
复制代码

Step3:这就样

将两个工程分别烧在不同的flash地址段中

A:bootloader


1:点Project选项卡,然后点Optionsfor Target选项如图:

31.jpg

2:Target选项卡下有on-chip地址设置,bootloader放在0x8000000开头的0x3000空间内

如图:

32.jpg

然后正常手段烧入flash即可。


B:application

和上述设置手段一样,只不过in-chip的IROM1设置起始地址为0x8003000,Size为mcu的Flash大小减去0x3000即可(注意是16进制哦)

然后就祝你幸福了   0.0


完整源码:

Main.c

  1. /* Includes------------------------------------------------------------------*/  
  2. #include "stm32f0xx.h"  
  3. #include "flash.h"  
  4. #include "powerAPI.h"  
  5. #include "IAP_Bootloader.h"  
  6.    
  7.    
  8. /**
  9.   *@brief  Main program.
  10.   *@param  None
  11.   *@retval None
  12.   */  
  13. int main(void)  
  14. {  
  15. SystemPowerUp();               /*-- PowerUp && LoadSysMsg --*/  
  16. while (1)  
  17.   {  
  18.    if(FLASH_If_ReadWord((uint32_t)IAP_READY_FLAG_ADDRESS) == FLAG_READY)  
  19.     {  
  20.      IAP_Init();  
  21.      SerialDownload();  
  22.      IAP_End_Clear_Flag();  
  23.     }  
  24.    else  
  25.     {  
  26.      JumpToApp();  
  27.     }  
  28.   }  
  29. return 0;  
  30. }  
复制代码
  1. /**
  2. ******************************************************************************
  3.   *@file      bootloader.c
  4.   *@brief     IAP module function
  5.   *@CPU       STM32F051
  6.   *@compiler  Keil uVision V4.74
  7.   *@author    MetalSeed
  8.   *@version   V1.0.0
  9.   *@date      18-Sept-2014
  10.   *@modifydate20-Sept-2014
  11. ******************************************************************************
  12.   *@attention
  13.   */  
  14. #include "stm32f0xx.h"   
  15. #include "IAP_Bootloader.h"  
  16. #include "uart.h"  
  17. #include "led.h"  
  18. #include "delay.h"  
  19. #include "flash.h"  
  20. #include "ymodem.h"  
  21.    
  22. /*================================================================
  23.         APPLICATION_ADDRESS   =   (uint32_t)0x08003000
  24.                         defined in flash
  25. ================================================================*/  
  26.    
  27. extern uint32_t IapReady;  
  28. uint8_t tab_1024[1024] ={ 0 };  
  29. uint8_t FileName[FILE_NAME_LENGTH];  
  30.    
  31.    
  32.    
  33.    
  34. /*================================================================
  35.                             About Jump              
  36. ================================================================*/  
  37. typedef void (*pFunction)(void); /*-- define a function type --*/  
  38.    
  39. uint32_t JumpAddress; /*-- define the usrapp's address --*/  
  40.    
  41. pFunction JumpToApplication; /*-- definethe function pointer which direct to usr app --*/  
  42.    
  43.    
  44. /**
  45.   *@brief  Jump to application
  46.   *@retval None
  47.   */  
  48. void JumpToApp(void)  
  49. {  
  50.    if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) ==0x20000000)/*-- check whether stack pointer legal --*/  
  51.     {  
  52.       
  53.      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);  
  54.      JumpToApplication = (pFunction) JumpAddress;  
  55.       
  56.      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); /*-- initialize theheap & stack pointer --*/  
  57.    
  58.      JumpToApplication();  
  59.     }  
  60. }  
  61.    
  62.    
  63.    
  64.    
  65. /*================================================================
  66.                     About IAP Download
  67. ================================================================*/  
  68. /**
  69.   *@brief  Initialize the Iap module(leddelay usart and unlock flash)
  70.   *@param  None
  71.   *@retval None
  72.   */  
  73. void IAP_Init(void)  
  74. {  
  75. uint32_t t;  
  76. LEDInit();                  /*--Set up Led to Output signal  --*/  
  77. SysTickInit();                 /*-- Config System Tick for delay functions --*/  
  78. USART_Configuration();             /*-- Config usart to download .bin --*/  
  79. FLASH_If_Init();                     /*-- Unlock Flash --*/  
  80. for(t = 2000; t > 10; t >>= 1 )        /*-- LED1 blink 3 second indeicate IAPbegin--*/  
  81.   {  
  82.    LEDTogle(1); delayms(t);  
  83.   }  
  84. }  
  85.    
  86.    
  87. /**
  88.   *@brief  IAP end, Clear Iap ready flag andoutput success signal
  89.   *@retval None
  90.   */  
  91. void IAP_End_Clear_Flag()  
  92. {  
  93. uint32_t i;  
  94. if(FLASH_If_WriteWord(IAP_READY_FLAG_ADDRESS, FLAG_UNREADY)  == 0)/*-- clear iap ready flag --*/  
  95.   {  
  96.    for(i = 0; i < 50; ++i) /*-- IAP end, Led1 and Led2 blink in turnlast 2.5 second --*/  
  97.     {  
  98.      LEDTogle(1); delayms(50); LEDTogle(2);  
  99.     }  
  100.   }  
  101. LED1ON;                  /*-- IAPend, Led1 and Led2 turn ON last 3 second --*/  
  102. LED2ON;  
  103. delayms(3000);  
  104. }  
  105.    
  106.    
  107. /**
  108.   *@brief  In App Program by Serial
  109.   *@retval None
  110.   */  
  111. void SerialDownload(void)  
  112. {  
  113. uint8_t Number[10] = {0};  
  114. int32_t Size = 0;  
  115.    
  116. SerialPutString("Waiting for the file to be sent ... (press 'a' toabort)\n\r");  
  117. Size = Ymodem_Receive(&tab_1024[0]);  
  118.   if(Size > 0)  
  119.   {  
  120.    SerialPutString("\n\n\r Programming CompletedSuccessfully!\n\r--------------------------------\r\n Name: ");  
  121.    SerialPutString(FileName);  
  122.    Int2Str(Number, Size);  
  123.    SerialPutString("\n\r Size: ");  
  124.    SerialPutString(Number);  
  125.    SerialPutString(" Bytes\r\n");  
  126.    SerialPutString("-------------------\n");  
  127.   }  
  128. else if (Size == -1)  
  129.   {  
  130.    SerialPutString("\n\n\rThe image size is higher than the allowedspace memory!\n\r");  
  131.   }  
  132. else if (Size == -2)  
  133.   {  
  134.    SerialPutString("\n\n\rVerification failed!\n\r");  
  135.   }  
  136. else if (Size == -3)  
  137.   {  
  138.    SerialPutString("\r\n\nAborted by user.\n\r");  
  139.   }  
  140. else  
  141.   {  
  142.    SerialPutString("\n\rFailed to receive the file!\n\r");  
  143.   }  
  144. }  
  145.    
  146.    
  147. /**
  148.   *@brief  Upload a file via serial port.
  149.   *@param  None
  150.   *@retval None
  151.   */  
  152. void SerialUpload(void)  
  153. {  
  154. uint8_t status = 0 ;  
  155.    
  156. SerialPutString("\n\n\rSelect Receive File\n\r");  
  157.    
  158.   if(GetKey() == CRC16)  
  159.   {  
  160.    /* Transmit the flash image through ymodem protocol */  
  161.    status = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (constuint8_t*)"UploadedFlashImage.bin", USER_FLASH_SIZE);  
  162.    
  163.    if (status != 0)  
  164.     {  
  165.      SerialPutString("\n\rError Occurred while TransmittingFile\n\r");  
  166.     }  
  167.    else  
  168.     {  
  169.      SerialPutString("\n\rFile uploaded successfully \n\r");  
  170.     }  
  171.   }  
  172. }
复制代码
  1. FLASH.c  
  2. /**
  3. ******************************************************************************
  4.   *@file      flash.c
  5.   *@brief     XXX function
  6.   *@CPU       STM32F051
  7.   *@compiler  Keil uVision V4.74
  8.   *@author    MetalSeed
  9.   *@version    V1.0.0
  10.   *@date      18-Sept-2014
  11.   *@modifydate20-Sept-2014
  12. ******************************************************************************
  13.   *@attention
  14.   */  
  15.    
  16. /* Includes ------------------------------------------------------------------*/  
  17.    
  18. #include "stm32f0xx.h"  
  19. #include "flash.h"  
  20. #include "uart.h"  
  21.    
  22. /** @addtogroup STM32F0xx_IAP
  23.   *@{
  24.   */  
  25.    
  26. /**
  27.   *@brief  Unlocks Flash for write access
  28.   *@param  None
  29.   *@retval None
  30.   */  
  31. void FLASH_If_Init(void)  
  32. {  
  33.   /*Unlock the Program memory */  
  34. FLASH_Unlock();  
  35.    
  36.   /*Clear all FLASH flags */   
  37. FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR |FLASH_FLAG_BSY);   
  38. }  
  39.    
  40. /**
  41.   *@brief  This function does an erase of alluser flash area
  42.   *@param  StartSector: start of user flasharea
  43.   *@retval 0: user flash area successfully erased
  44. *         1: error occurred
  45.   */  
  46. uint32_t FLASH_If_Erase(uint32_tStartSector)  
  47. {  
  48. uint32_t flashaddress;  
  49.    
  50. flashaddress = StartSector;  
  51.    
  52. while (flashaddress <= (uint32_t) USER_FLASH_LAST_PAGE_ADDRESS)  
  53.   {  
  54.    if (FLASH_ErasePage(flashaddress) == FLASH_COMPLETE)  
  55.     {  
  56.      flashaddress += FLASH_PAGE_SIZE;  
  57.     }  
  58.    else  
  59.     {  
  60.      /* Error occurred while page erase */  
  61.      return (1);  
  62.     }  
  63.   }  
  64. return (0);  
  65. }  
  66.    
  67. /**
  68.   *@brief  Read uint32_t int
  69.   *@param  FlashAddress: address to be read
  70.   *@retval Read value  
  71.   */  
  72. uint32_t FLASH_If_ReadWord(__IO uint32_tFlashAddress)  
  73. {  
  74. return *(uint32_t*)FlashAddress;  
  75. }  
  76.    
  77. /**
  78.   *@brief  Erase flash by one page
  79.   *@param  SectorNum: page number
  80.   *@retval None
  81.   */  
  82. uint32_t FLASH_If_ErasePage(uint32_tSectorNum)  
  83. {  
  84. uint32_t flashaddress;  
  85.    
  86. flashaddress = SectorNum;  
  87.   if(FLASH_ErasePage(flashaddress) == FLASH_COMPLETE)  
  88.   {  
  89.    return 0;  
  90.   }  
  91. else  
  92.   {  
  93.    /* Error occurred while page erase */  
  94.    return (1);  
  95.   }  
  96. }  
  97.    
  98. /**
  99.   *@brief  Write uint32_t int
  100.   *@param  FlashAddress: address to write
  101.   *@param  Data: data to be write
  102.   *@retval 0: Write success  
  103.   *@retval 1: Write error  
  104.   *@retval 2: read error  
  105.   */  
  106. uint32_t FLASH_If_WriteWord(uint32_tFlashAddress, uint32_t Data)  
  107. {  
  108.   if(FLASH_ProgramWord(FlashAddress, Data) == FLASH_COMPLETE)  
  109.   {  
  110.    /*Check the written value */  
  111.    if (*(uint32_t*)FlashAddress != Data)  
  112.     {  
  113.      /* Flash content doesn't match SRAM content */  
  114.      return(2);  
  115.     }  
  116.    return 0;  
  117.   }  
  118. else  
  119.   {  
  120.    /* Error occurred while writing data in Flash memory */  
  121.    return (1);  
  122.   }  
  123. }  
  124.    
  125.    
  126. /**
  127.   *@brief  This function writes a databuffer in flash (data are 32-bit aligned).
  128.   *@note   After writing data buffer, theflash content is checked.
  129.   *@param  FlashAddress: start address forwriting data buffer
  130.   *@param  Data: pointer on data buffer
  131.   *@param  DataLength: length of data buffer(unit is 32-bit word)   
  132.   *@retval 0: Data successfully written to Flash memory
  133. *         1: Error occurred whilewriting data in Flash memory
  134. *         2: Written Data in flashmemory is different from expected one
  135.   */  
  136.    
  137. uint32_t FLASH_If_Write(__IO uint32_t*FlashAddress, uint32_t* Data ,uint16_t DataLength)  //ÐèÒª½«Á½¸öµØÖ·¸³Öµ¹ýÀ´¡£°´Êý¾Ý³¤¶È½«Êý¾ÝдÈëflash  
  138. {  
  139. uint32_t i = 0;  
  140.   for(i = 0; (i < DataLength) && (*FlashAddress <=(USER_FLASH_END_ADDRESS-4)); i++)  
  141.   {  
  142.    /* the operation will be done by word */  
  143.    if (FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data+i)) ==FLASH_COMPLETE)  
  144.     {  
  145.     /* Check the written value */  
  146.      if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i))  
  147.      {  
  148.        /* Flash content doesn't match SRAM content */  
  149.        return(2);  
  150.      }  
  151.      /* Increment FLASH destination address */  
  152.      *FlashAddress += 4;  
  153.     }  
  154.    else  
  155.     {  
  156.      /* Error occurred while writing data in Flash memory */  
  157.      return (1);  
  158.     }  
  159.   }  
  160.    
  161. return (0);  
  162. }  
  163. /**
  164.   *@brief  Disables the write protection ofuser desired pages
  165.   *@param  None
  166.   *@retval 0: Write Protection successfully disabled
  167. *         1: Error: Flash writeunprotection failed
  168. *         2: Flash memory is not writeprotected
  169.   */  
  170. uint32_tFLASH_If_DisableWriteProtection(void)  
  171. {  
  172. uint32_t UserMemoryMask = 0, WRPR = 0;  
  173. FLASH_Status status = FLASH_BUSY;  
  174.    
  175.   /*Clear all FLASH flags */   
  176. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR |FLASH_FLAG_BSY);  
  177.    
  178.   /*Get Write protection */  
  179. WRPR = FLASH_OB_GetWRP();  
  180.    
  181.   /*Test if user memory is write protected */  
  182.   if(FLASH_If_GetWriteProtectionStatus() != 0x00)  
  183.   {  
  184.     /* Enable the FLASH option byte access */  
  185.    FLASH_OB_Unlock();   
  186.    
  187.    /* Erase option bytes */  
  188.    status = FLASH_OB_Erase();  
  189.    
  190.    /* Compute the User_Mask */  
  191.    UserMemoryMask = FLASH_PROTECTED_PAGES | WRPR;  
  192.      
  193.    if (UserMemoryMask != 0xFFFFFFFF)  
  194.     {  
  195.    /* Disable Write protection */  
  196.    status = FLASH_OB_EnableWRP((uint32_t)~UserMemoryMask);  
  197.     }  
  198.      
  199.    if (status == FLASH_COMPLETE)  
  200.     {  
  201.      /* Write Protection successfully disabled */  
  202.      return (0);  
  203.     }  
  204.    else  
  205.     {  
  206.      /* Error: Flash write unprotection failed */  
  207.      return (1);  
  208.     }  
  209.   }  
  210. else  
  211.   {  
  212.     /* Flash memory is not write protected */  
  213.     return(2);  
  214.   }  
  215. }  
  216.    
  217. /**
  218.   *@brief  Returns the write protectionstatus of user flash area.
  219.   *@param  None
  220.   *@retval If the sector is write-protected, the corresponding bit in returned
  221. *         value is set.
  222. *         If the sector isn'twrite-protected, the corresponding bit in returned
  223. *         value is reset.
  224.   */  
  225. uint32_t FLASH_If_GetWriteProtectionStatus(void)  
  226. {  
  227. return(~FLASH_OB_GetWRP() & FLASH_PROTECTED_PAGES);  
  228. }  
  229.    
  230.    
  231. /**
  232.   *@}
  233.   */  
  234.    
  235.    
  236. /************************ (C) COPYRIGHTSTMicroelectronics *****END OF FILE****/
复制代码

Ymodem.c

  1. /**
  2. ******************************************************************************
  3.   *@file    STM32F0xx_IAP/src/ymodem.c
  4.   *@author  MCD Application Team
  5.   *@version V1.0.0
  6.   *@date    29-May-2012
  7.   *@brief   Main program body
  8. ******************************************************************************
  9.   *@attention
  10.   *
  11.   *<h2><center>© COPYRIGHT 2012STMicroelectronics</center></h2>
  12.   *
  13.   *Licensed under MCD-ST Liberty SW License Agreement V2, (the"License");
  14.   *You may not use this file except in compliance with the License.
  15.   *You may obtain a copy of the License at:
  16.   *
  17. *       http://www.st.com/software_license_agreement_liberty_v2
  18.   *
  19.   *Unless required by applicable law or agreed to in writing, software
  20.   *distributed under the License is distributed on an "AS IS" BASIS,
  21.   *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22.   *See the License for the specific language governing permissions and
  23.   *limitations under the License.
  24.   *
  25. ******************************************************************************
  26.   */  
  27. /* Includes------------------------------------------------------------------*/  
  28.    
  29. #include "ymodem.h"  
  30. #include "uart.h"  
  31. #include "string.h"  
  32. #include "flash.h"  
  33.    
  34.    
  35. /** @addtogroup STM32F0xx_IAP
  36.   *@{
  37.   */  
  38.    
  39. /* Private typedef-----------------------------------------------------------*/  
  40. /* Private define------------------------------------------------------------*/  
  41. /* Private macro-------------------------------------------------------------*/  
  42. /* Private variables---------------------------------------------------------*/  
  43. extern uint8_t FileName[];  
  44.    
  45. /* Private function prototypes-----------------------------------------------*/  
  46. /* Private functions---------------------------------------------------------*/  
  47.    
  48. /**
  49.   *@brief  Receive byte from sender
  50.   *@param  c: Character
  51.   *@param  timeout: Timeout
  52.   *@retval 0: Byte received
  53. *         -1: Timeout
  54.   */  
  55. static int32_t Receive_Byte (uint8_t *c, uint32_t timeout)  
  56. {  
  57. while (timeout-- > 0)  
  58.   {  
  59.    if (SerialKeyPressed(c) == 1)  
  60.     {  
  61.      return 0;  
  62.     }  
  63.   }  
  64. return -1;  
  65. }  
  66.    
  67. /**
  68.   *@brief  Send a byte
  69.   *@param  c: Character
  70.   *@retval 0: Byte sent
  71.   */  
  72. static uint32_t Send_Byte (uint8_t c)  
  73. {  
  74. SerialPutChar(c);  
  75. return 0;  
  76. }  
  77.    
  78. /**
  79.   *@brief  Update CRC16 for input byte
  80.   *@param  CRC input value
  81.   *@param  input byte
  82.   *@retval Updated CRC value
  83.   */  
  84. uint16_t UpdateCRC16(uint16_t crcIn,uint8_t byte)  
  85. {  
  86. uint32_t crc = crcIn;  
  87. uint32_t in = byte|0x100;  
  88.    
  89.   do  
  90.   {  
  91.    crc <<= 1;  
  92.    in <<= 1;  
  93.    
  94.    if(in&0x100)  
  95.     {  
  96.       ++crc;  
  97.     }  
  98.      
  99.    if(crc&0x10000)  
  100.     {  
  101.      crc ^= 0x1021;  
  102.     }  
  103. }while(!(in&0x10000));  
  104.    
  105. return (crc&0xffffu);  
  106. }  
  107.    
  108. /**
  109.   *@brief  Cal CRC16 for YModem Packet
  110.   *@param  data
  111.   *@param  length
  112.   *@retval CRC value
  113.   */  
  114. uint16_t Cal_CRC16(const uint8_t* data,uint32_t size)  
  115. {  
  116. uint32_t crc = 0;  
  117. const uint8_t* dataEnd = data+size;  
  118.    
  119. while(data<dataEnd)  
  120.   {  
  121.    crc = UpdateCRC16(crc,*data++);  
  122.   }  
  123.   crc= UpdateCRC16(crc,0);  
  124.   crc= UpdateCRC16(crc,0);  
  125.    
  126. return (crc&0xffffu);  
  127. }  
  128.    
  129. /**
  130.   *@brief  Cal Check sum for YModem Packet
  131.   *@param  data
  132.   *@param  length
  133.   *@retval None
  134.   */  
  135. uint8_t CalChecksum(const uint8_t* data,uint32_t size)  
  136. {  
  137. uint32_t sum = 0;  
  138. const uint8_t* dataEnd = data+size;  
  139.    
  140. while(data < dataEnd)  
  141.   {  
  142.    sum += *data++;  
  143.   }  
  144.    
  145. return (sum&0xffu);  
  146. }  
  147.    
  148. /**
  149.   *@brief  Receive a packet from sender
  150.   *@param  data
  151.   *@param  length
  152.   *@param  timeout
  153. *          0: end of transmission
  154. *          -1: abort by sender
  155. *          >0: packet length
  156.   *@retval 0: normally return
  157. *         -1: timeout or packeterror
  158. *         1: abort by user
  159.   */  
  160. static int32_t Receive_Packet (uint8_t*data, int32_t *length, uint32_t timeout)  
  161. {  
  162. uint16_t i, packet_size, computedcrc;  
  163. uint8_t c;  
  164. *length = 0;  
  165.   if(Receive_Byte(&c, timeout) != 0)  
  166.   {  
  167.    return -1;  
  168.   }  
  169. switch (c)  
  170.   {  
  171.    case SOH:  
  172.      packet_size = PACKET_SIZE;  
  173.      break;  
  174.    case STX:  
  175.      packet_size = PACKET_1K_SIZE;  
  176.      break;  
  177.    case EOT:  
  178.      return 0;  
  179.    case CA:  
  180.      if ((Receive_Byte(&c, timeout) == 0) && (c == CA))  
  181.      {  
  182.        *length = -1;  
  183.        return 0;  
  184.      }  
  185.      else  
  186.      {  
  187.        return -1;  
  188.      }  
  189.    case ABORT1:  
  190.    case ABORT2:  
  191.      return 1;  
  192.    default:  
  193.      return -1;  
  194.   }  
  195. *data = c;  
  196.   for(i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)  
  197.   {  
  198.    if (Receive_Byte(data + i, timeout) != 0)  
  199.     {  
  200.      return -1;  
  201.     }  
  202.   }  
  203.   if(data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) &0xff))  
  204.   {  
  205.    return -1;  
  206.   }  
  207.    
  208.   /*Compute the CRC */  
  209. computedcrc = Cal_CRC16(&data[PACKET_HEADER],(uint32_t)packet_size);  
  210.   /*Check that received CRC match the already computed CRC value
  211.     data[packet_size+3]<<8) | data[packet_size+4] contains thereceived CRC
  212.     computedcrc contains the computed CRC value */  
  213.   if(computedcrc != (uint16_t)((data[packet_size+3]<<8) |data[packet_size+4]))  
  214.   {  
  215.    /* CRC error */  
  216.    return -1;  
  217.   }  
  218.    
  219. *length = packet_size;  
  220. return 0;  
  221. }  
  222.    
  223. /**
  224.   *@brief  Receive a file using the ymodemprotocol
  225.   *@param  buf: Address of the first byte
  226.   *@retval The size of the file
  227.   */  
  228. int32_t Ymodem_Receive (uint8_t *buf)  
  229. {  
  230. uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD],file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;  
  231. int32_t i, packet_length, session_done, file_done, packets_received,errors, session_begin, size = 0;  
  232. uint32_t flashdestination, ramsource;  
  233.    
  234.   /*Initialize flashdestination variable */  
  235. flashdestination = APPLICATION_ADDRESS;  
  236.    
  237.   for(session_done = 0, errors = 0, session_begin = 0; ;)  
  238.   {  
  239.    for (packets_received = 0, file_done = 0, buf_ptr = buf; ;)  
  240.     {  
  241.      switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))  
  242.      {  
  243.        case 0:  
  244.          errors = 0;  
  245.          switch (packet_length)  
  246.          {  
  247.            /* Abort by sender */  
  248.            case - 1:  
  249.               Send_Byte(ACK);  
  250.               return 0;  
  251.            /* End of transmission */  
  252.            case 0:  
  253.               Send_Byte(ACK);  
  254.               file_done = 1;  
  255.               break;  
  256.            /* Normal packet Õý³£Çé¿öϵİü*/  
  257.            default:  
  258.               if((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))  
  259.               {  
  260.                 Send_Byte(NAK);  
  261.               }  
  262.               else  
  263.               {  
  264.                 if (packets_received == 0)  
  265.                 {  
  266.                   /* Filename packet */  
  267.                   if(packet_data[PACKET_HEADER] != 0)  
  268.                   {  
  269.                     /* Filename packet hasvalid data */  
  270.                     for (i = 0, file_ptr =packet_data + PACKET_HEADER; (*file_ptr != 0) && (i <FILE_NAME_LENGTH);)  
  271.                     {  
  272.                       FileName[i++] =*file_ptr++;  
  273.                     }  
  274.                     FileName[i++] = '\0';  
  275.                     for (i = 0, file_ptr ++;(*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));)  
  276.                     {  
  277.                       file_size[i++] =*file_ptr++;  
  278.                     }  
  279.                     file_size[i++] = '\0';  
  280.                     Str2Int(file_size,&size);  
  281.    
  282.                     /* Test the size of theimage to be sent */  
  283.                     /* Image size is greaterthan Flash size */  
  284.                     if (size >(USER_FLASH_SIZE + 1))  
  285.                     {  
  286.                       /* End session */  
  287.                       Send_Byte(CA);  
  288.                       Send_Byte(CA);  
  289.                       return -1;  
  290.                     }  
  291.                     /* erase user applicationarea */  
  292.                     FLASH_If_Erase(APPLICATION_ADDRESS);  
  293.                     Send_Byte(ACK); // ACK  and 'C' ?  
  294.                     Send_Byte(CRC16);  
  295.                   }  
  296.                   /* Filename packet is empty,end session */  
  297.                   else  
  298.                   {  
  299.                     Send_Byte(ACK);  
  300.                     file_done = 1;  
  301.                     session_done = 1;  
  302.                     break;  
  303.                   }  
  304.                 }  
  305.                 /* Data packet */  
  306.                 else   //Õý³£Çé¿öϽøÈë  
  307.                 {  
  308.                   memcpy(buf_ptr, packet_data +PACKET_HEADER, packet_length);  
  309.                   ramsource =(uint32_t)buf;   //bufÊÇÒ»¸öÖ¸Õë  
  310.    
  311.                   /* Write received data inFlash */  
  312.                   if(FLASH_If_Write(&flashdestination, (uint32_t*) ramsource, (uint16_t)packet_length/4)  == 0)  //½«Êý¾ÝдÈëflash  
  313.                   {  
  314.                     Send_Byte(ACK);  //дÍêÒ»Ö¡Êý¾ÝÖ®ºó·¢ËÍÏìÓ¦  
  315.                   }  
  316.                   else /* An error occurredwhile writing to Flash memory */  
  317.                   {  
  318.                     /* End session */  
  319.                     Send_Byte(CA);  
  320.                     Send_Byte(CA);  
  321.                     return -2;  
  322.                   }  
  323.                 }  
  324.                 packets_received ++;  //°üÊý+1  
  325.                 session_begin = 1;  
  326.               }  
  327.          }  
  328.          break;  
  329.        case 1:  
  330.          Send_Byte(CA);  
  331.          Send_Byte(CA);  
  332.          return -3;  
  333.        default:  
  334.          if (session_begin > 0) //½ÓÊÕÒѾ­¿ªÊ¼£¬µ«ÊÇReceive_Packet(packet_data, &packet_length,NAK_TIMEOUT)¸Ãº¯Êý·µ»Ø´íÎó¡£  
  335.          {  
  336.            errors ++;  
  337.          }  
  338.          if (errors > MAX_ERRORS)  
  339.          {  
  340.            Send_Byte(CA);  
  341.            Send_Byte(CA);  
  342.            return 0;  
  343.          }  
  344.          Send_Byte(CRC16); // the start C!!  
  345.          break;  
  346.      }  
  347.      if (file_done != 0)  
  348.      {  
  349.        break;  
  350.      }  
  351.     }  
  352.    if (session_done != 0)  
  353.     {  
  354.      break;  
  355.     }  
  356.   }  
  357. return (int32_t)size;  
  358. }  
  359.    
  360. /**
  361.   *@brief  check response using the ymodemprotocol
  362.   *@param  buf: Address of the first byte
  363.   *@retval The size of the file
  364.   */  
  365. int32_t Ymodem_CheckResponse(uint8_t c)  
  366. {  
  367. return 0;  
  368. }  
  369.    
  370. /**
  371.   *@brief  Prepare the first block
  372.   *@param  timeout
  373.   *@retval None
  374.   */  
  375. void Ymodem_PrepareIntialPacket(uint8_t*data, const uint8_t* fileName, uint32_t *length)  
  376. {  
  377. uint16_t i, j;  
  378. uint8_t file_ptr[10];  
  379.    
  380.   /*Make first three packet */  
  381. data[0] = SOH;  
  382. data[1] = 0x00;  
  383. data[2] = 0xff;  
  384.    
  385.   /*Filename packet has valid data */  
  386.   for(i = 0; (fileName[i] != '\0') && (i < FILE_NAME_LENGTH);i++)  
  387.   {  
  388.     data[i + PACKET_HEADER] = fileName[i];  
  389.   }  
  390.    
  391. data[i + PACKET_HEADER] = 0x00;  
  392.    
  393. Int2Str (file_ptr, *length);  
  394.   for(j =0, i = i + PACKET_HEADER + 1; file_ptr[j] != '\0' ; )  
  395.   {  
  396.     data[i++] = file_ptr[j++];  
  397.   }  
  398.    
  399.   for(j = i; j < PACKET_SIZE + PACKET_HEADER; j++)  
  400.   {  
  401.    data[j] = 0;  
  402.   }  
  403. }  
  404.    
  405. /**
  406.   *@brief  Prepare the data packet
  407.   *@param  timeout
  408.   *@retval None
  409.   */  
  410. void Ymodem_PreparePacket(uint8_t*SourceBuf, uint8_t *data, uint8_t pktNo, uint32_t sizeBlk)  
  411. {  
  412. uint16_t i, size, packetSize;  
  413. uint8_t* file_ptr;  
  414.    
  415.   /*Make first three packet */  
  416. packetSize = sizeBlk >= PACKET_1K_SIZE ? PACKET_1K_SIZE :PACKET_SIZE;  
  417. size = sizeBlk < packetSize ? sizeBlk :packetSize;  
  418.   if(packetSize == PACKET_1K_SIZE)  
  419.   {  
  420.     data[0] = STX;  
  421.   }  
  422. else  
  423.   {  
  424.     data[0] = SOH;  
  425.   }  
  426. data[1] = pktNo;  
  427. data[2] = (~pktNo);  
  428. file_ptr = SourceBuf;  
  429.    
  430.   /*Filename packet has valid data */  
  431.   for(i = PACKET_HEADER; i < size + PACKET_HEADER;i++)  
  432.   {  
  433.     data[i] = *file_ptr++;  
  434.   }  
  435.   if( size  <= packetSize)  
  436.   {  
  437.    for (i = size + PACKET_HEADER; i < packetSize + PACKET_HEADER; i++)  
  438.     {  
  439.      data[i] = 0x1A; /* EOF (0x1A) or 0x00 */  
  440.     }  
  441.   }  
  442. }  
  443.    
  444. /**
  445.   *@brief  Transmit a data packet using theymodem protocol
  446.   *@param  data
  447.   *@param  length
  448.   *@retval None
  449.   */  
  450. void Ymodem_SendPacket(uint8_t *data,uint16_t length)  
  451. {  
  452. uint16_t i;  
  453.   i =0;  
  454. while (i < length)  
  455.   {  
  456.    Send_Byte(data[i]);  
  457.    i++;  
  458.   }  
  459. }  
  460.    
  461. /**
  462.   *@brief  Transmit a file using the ymodemprotocol
  463.   *@param  buf: Address of the first byte
  464.   *@retval The size of the file
  465.   */  
  466. uint8_t Ymodem_Transmit (uint8_t *buf,const uint8_t* sendFileName, uint32_t sizeFile)  
  467. {  
  468. uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];  
  469. uint8_t FileName[FILE_NAME_LENGTH];  
  470. uint8_t *buf_ptr, tempCheckSum ;  
  471. uint16_t tempCRC, blkNumber;  
  472. uint8_t receivedC[2], CRC16_F = 0, i;  
  473. uint32_t errors = 0, ackReceived = 0, size = 0, pktSize;  
  474.    
  475.   for(i = 0; i < (FILE_NAME_LENGTH - 1); i++)  
  476.   {  
  477.    FileName[i] = sendFileName[i];  
  478.   }  
  479. CRC16_F = 1;  
  480.    
  481.   /*Prepare first block */  
  482. Ymodem_PrepareIntialPacket(&packet_data[0], FileName,&sizeFile);  
  483.    
  484.   do  
  485.   {  
  486.    /* Send Packet */  
  487.    Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);  
  488.      
  489.    /* Send CRC or Check Sum based on CRC16_F */  
  490.    if (CRC16_F)  
  491.     {  
  492.       tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);  
  493.       Send_Byte(tempCRC >> 8);  
  494.       Send_Byte(tempCRC & 0xFF);  
  495.     }  
  496.    else  
  497.     {  
  498.       tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE);  
  499.       Send_Byte(tempCheckSum);  
  500.     }  
  501.    
  502.     /*Wait for Ack and 'C' */  
  503.    if (Receive_Byte(&receivedC[0], 1000000) == 0)   
  504.     {  
  505.      if (receivedC[0] == ACK)  
  506.      {  
  507.        /* Packet transfered correctly */  
  508.        ackReceived = 1;  
  509.      }  
  510.     }  
  511.    else  
  512.     {  
  513.        errors++;  
  514.     }  
  515. }while (!ackReceived && (errors < 0x0A));  
  516.    
  517.   if(errors >=  0x0A)  
  518.   {  
  519.    return errors;  
  520.   }  
  521. buf_ptr = buf;  
  522. size = sizeFile;  
  523. blkNumber = 0x01;  
  524.    
  525.   /*Here 1024 bytes package is used to send the packets */  
  526. while (size)  
  527.   {  
  528.    /* Prepare next packet */  
  529.    Ymodem_PreparePacket(buf_ptr, &packet_data[0], blkNumber, size);  
  530.    ackReceived = 0;  
  531.    receivedC[0]= 0;  
  532.    errors = 0;  
  533.    do  
  534.     {  
  535.      /* Send next packet */  
  536.      if (size >= PACKET_1K_SIZE)  
  537.      {  
  538.        pktSize = PACKET_1K_SIZE;  
  539.          
  540.      }  
  541.      else  
  542.      {  
  543.        pktSize = PACKET_SIZE;  
  544.      }  
  545.      Ymodem_SendPacket(packet_data, pktSize + PACKET_HEADER);  
  546.      /* Send CRC or Check Sum based on CRC16_F */  
  547.      if (CRC16_F)  
  548.      {  
  549.         tempCRC = Cal_CRC16(&packet_data[3], pktSize);  
  550.         Send_Byte(tempCRC >> 8);  
  551.         Send_Byte(tempCRC & 0xFF);  
  552.      }  
  553.      else  
  554.      {  
  555.        tempCheckSum = CalChecksum (&packet_data[3], pktSize);  
  556.        Send_Byte(tempCheckSum);  
  557.      }  
  558.       
  559.      /* Wait for Ack */  
  560.      if (Receive_Byte(&receivedC[0], 1000000) == 0)   
  561.      {    if (receivedC[0] == ACK)  
  562.      {  
  563.        ackReceived = 1;   
  564.        if (size > pktSize)  
  565.        {  
  566.           buf_ptr += pktSize;   
  567.           size -= pktSize;  
  568.           if (blkNumber == (USER_FLASH_SIZE/1024))  
  569.           {  
  570.             return 0xFF; /*  error */  
  571.           }  
  572.           else  
  573.           {  
  574.               blkNumber++;  
  575.           }  
  576.        }  
  577.        else  
  578.        {  
  579.           buf_ptr += pktSize;  
  580.           size = 0;  
  581.        }  
  582.      }  
  583.      }  
  584.      else  
  585.      {  
  586.        errors++;  
  587.      }  
  588.    }while(!ackReceived && (errors < 0x0A));  
  589.      
  590.    /* Resend packet if NAK  for acount of 10 else end of commuincation */  
  591.    if (errors >=  0x0A)  
  592.     {  
  593.      return errors;  
  594.     }  
  595.      
  596.   }  
  597. ackReceived = 0;  
  598. receivedC[0] = 0x00;  
  599. receivedC[1] = 0x00;  
  600. errors = 0;  
  601.   do  
  602.   {  
  603.    Send_Byte(EOT);   
  604.    /* Send (EOT); */  
  605.    /* Wait for Ack */  
  606.    receivedC[0] = USART_ReceiveData(USART1);  
  607.    if (receivedC[0] == ACK)  
  608.     {  
  609.      ackReceived = 1;  
  610.      }  
  611.      
  612.    else  
  613.     {  
  614.      errors++;  
  615.     }  
  616.    /* Clear Overrun flag of the USART2 */  
  617.    USART_ClearFlag(USART1, USART_FLAG_ORE);  
  618. }while (!ackReceived && (errors < 0x0A));  
  619.      
  620.   if(errors >=  0x0A)  
  621.   {  
  622.    return errors;  
  623.   }  
  624.    
  625.   /*Last packet preparation */  
  626. ackReceived = 0;  
  627. receivedC[0] = 0x00;  
  628. receivedC[1] = 0x00;  
  629. errors = 0;  
  630.    
  631. packet_data[0] = SOH;  
  632. packet_data[1] = 0;  
  633. packet_data [2] = 0xFF;  
  634.    
  635.   for(i = PACKET_HEADER; i < (PACKET_SIZE + PACKET_HEADER); i++)  
  636.   {  
  637.     packet_data [i] = 0x00;  
  638.   }  
  639.    
  640.   do  
  641.   {  
  642.    /* Send Packet */  
  643.    Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);  
  644.    
  645.    /* Send CRC or Check Sum based on CRC16_F */  
  646.     tempCRC = Cal_CRC16(&packet_data[3],PACKET_SIZE);  
  647.    Send_Byte(tempCRC >> 8);  
  648.    Send_Byte(tempCRC & 0xFF);  
  649.    
  650.    /* Wait for Ack and 'C' */  
  651.    if (Receive_Byte(&receivedC[1], 1000000) == 0)   
  652.     {  
  653.      if (receivedC[1] == ACK)  
  654.      {  
  655.        /* Packet transfered correctly */  
  656.        ackReceived = 1;  
  657.      }  
  658.     }  
  659.    else  
  660.     {  
  661.      errors++;  
  662.     }  
  663. }while (!ackReceived && (errors < 0x0A));  
  664.    
  665.   /*Resend packet if NAK  for a count of10  else end of commuincation */  
  666.   if(errors >=  0x0A)  
  667.   {  
  668.    return errors;  
  669. }   
  670. receivedC[0] = 0x00;  
  671.   do  
  672.   {  
  673.    Send_Byte(EOT);   
  674.    /* Send (EOT); */  
  675.    /* Wait for Ack */  
  676.    if ((Receive_Byte(&receivedC[0], 1000000) == 0)  && receivedC[0] == ACK)  
  677.     {  
  678.      ackReceived = 1;   
  679.     }  
  680.      
  681.    else  
  682.     {  
  683.      errors++;  
  684.     }  
  685.    /* Clear Overrun flag of the USART2 */  
  686.    USART_ClearFlag(USART1, USART_FLAG_ORE);  
  687. }while (!ackReceived && (errors < 0x0A));  
  688.      
  689.   if(errors >=  0x0A)  
  690.   {  
  691.    return errors;  
  692.   }  
  693. return 0; /* file trasmitted successfully */  
  694. }  
  695.    
  696. /**
  697.   *@}
  698.   */  
  699.    
  700. /************************ (C) COPYRIGHTSTMicroelectronics *****END OF FILE****/
复制代码

然后就没有然后了,如果你还要然后可以博客下载完整工程看看。。(BY MetalSeed)


收藏 3 评论7 发布时间:2016-6-24 16:40

举报

7个回答
风子 回答时间:2016-6-24 18:05:03
谢谢分享,,这就是官方库的工程吧
yklstudent 回答时间:2016-6-24 20:14:54
官方的东西,久不能搞点有新意的;炒冷饭
stary666 回答时间:2016-6-25 15:45:50
sin63 回答时间:2016-6-29 21:59:19
刚入门,正好用
谢谢版主提供教程资料!
waters1006-1793 回答时间:2019-5-10 12:34:39
源码呢
幻影21 回答时间:2019-5-10 23:30:50
谢谢分享
cainiaoxi 回答时间:2020-11-23 15:45:41
请问一下,到哪下官方的IAP例程

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版