编写背景:
       用户如果将开发了的产品发布上线销售,后期需要更新固件和程序,就需要用到远程OTA固件升级,就能对已发布的产品进行远程升级。
材料准备:
       1.机智云4G模组GC211
此模组采用中移模组ML302,需烧录机智云GAgent固件,支持网络,移动,联通,电信4G网络。

       2.秉火【F103开发板-指南者】

正文:
云端部署
创建新产品,可根据自己需求选择。

添加如下数据点,可根据自己需求

生成STM32F103代码下载备用

       简述STM32 启动
ARM7/ARM9 内核的控制器在复位后,CPU 会从存储空间的绝对地址0x000000 取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC =0x000000)同时中断向量表的位置并不是固定的。然而,Cortex-M3 内核启动有3 种情况:
1、通过boot 引脚设置可以将中断向量表定位于SRAM 区,即起始地址为0x2000000,同时复位后PC 指针位于0x2000000 处;
2、通过boot 引脚设置可以将中断向量表定位于FLASH 区,即起始地址为0x8000000,同时复位后PC 指针位于0x8000000 处;
3、通过boot 引脚设置可以将中断向量表定位于内置Bootloader 区;
Cortex-M3 内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断
入口向量地址,这样在Cortex-M3 内核复位后,会自动从起始地址的下一个32 位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9 内核,Cortex-M3 内核则是固定了中断向量表的位置而起始地址是可变化的。
总结一下STM32 的启动文件和启动过程。首先对栈和堆的大小进行定义,并在代码区的起始处建立中断向量表,其第一个表项是栈顶地址,第二个表项是复位中断服务入口地址。
然后在复位中断服务程序中跳转C/C++标准实时库的main 函数,完成用户堆栈等的初始化后,跳转.c 文件中的main 函数开始执行C 程序。假设STM32被设置为从内部FLASH 启动(这也是最常见的一种情况),中断向量表起始地位为0x8000000,则栈顶地址存放于0x8000000处,而复位中断服务入口地址存放于0x8000004 处。当STM32 遇到复位信号后,则从0x80000004 处取出复位中断服务入口地址,继而执行复位中断服务程序,然后跳转main函数,最后进入mian 函数。
分析下OTA 需求,我们将建立两个工程,分别是Bootloader 还有APP,我们将Bootloader下载到FLASH 空间0x8000000 地址处,那么STM32 启动后会首先执行我们的Bootloader 程序,然后就可以按照我们意愿实现OTA 了。
       FLASH 区间划分
       根据需求,我们将STM32F103VET6 这个芯片Flash 空间划分出4 个区域:Bootloader、FLAG、APP、APP_BAK。四个区间作用描述如下:
   Bootloader:存储Bootloader 固件,MCU 上电后首先运行该固件。
   FLAG:存储有关升级的相关标志位,Bootloader 和APP 都需要操作该区域。
              升级标志位(2B)
固件大小(4B)
MD5加密数据(16B)
   APP:存储用户程序固件。
   APPBAK:临时存储云端下发的新固件,升级固件的一个过渡存储区。
STM32F103VET6分区方案如下图所示:

BOOTLOADER分区部分
Bootloader程序流程
Bootloader 的主要职能是在有升级任务的时候将 APPBAK 分区里面的固件拷贝到 APP 区域。当然,这期间需要做很多的工作,比如升级失败的容错等等。具体的流程可以参考图示。需要注意的是,在校验 MD5 正确后开始搬运固件数据期间,MCU 出现故障(包括突然断电),MCU 应发生复位操作(FLAG 区域数据未破坏),复位后重新开始执行 Bootloader,从而避免 MCU 刷成板砖。

Bootloader程序配置
为了方便构架,此处我采用cubemx构建项目,生成keil工程。
创建STM32F103VE项目

配置外部时钟

配置时钟72M

配置debug为serisl wire

配置串口4为BootLoader的日志打印口。

生成keil代码添加驱动flash.c,gagent_md5.c和app.c以及对应的组,如何添加此处不过多介绍(基础的软件操作),只提供文件路径。





驱动文件的编写以及函数介绍我此处不过多介绍,可以在福建进行下载源文件,也可以在文章末尾复制代码。代码只讲重点部分。
Main.c添加头文件#include "app.h"

主函数添加APP_Process();

根据自己分区大小设置区域,我的是18K,2k,54k,54k

Bootloader编译设置
按照 Bootloader 流程编写好代码,需要我们对 KEIL 工程做相应配置,需要注意的是编译的 Bootloader 固件大小不超过最大可允许的 18KB。Keil 编译器需要设置如下:






APP程序分区部分
固件接收流程
做好 BOOTLOADER 工作后,我们开始写 APP 分区的代码。APP 分区固件的编写要注意硬件版本号和软件版本号,软件版号作为升级迭代很重要的标志。需要注意的是,中断向量地址偏移的定义,这个地方需要我们尤其注意,我在开发过程中在这个地方排查了好长时间。STM32 标准库默认中断向量地址偏移为0x0,但是我们APP 实际的偏移是0x5000。如果不修改,APP 也可以正常加载运行,但是不会相应中断。所以,我们需要根据实际APP 下载的起始地址,对中断向量地址偏移做定义。

CUBEMX部署
解压云端生成的代码,由于生成的代码是STM32F103c8的,我们需要通过CUBEMX转换成STM32F103VET6的代码来适应我们的秉火开发板,创建一个新的cubeMX项目,导入自动代码的CUBEMX工程.

目录保存在解压代码所在的路径。

修改时钟树为72M,注意需要同BootLoader时钟。

根据项目需求以及我们自己创建的数据点,我们需要控制RGB灯,蜂鸣器,DHT11,在此处我们需要对引脚进行初始化。

配置RGB灯,采用定时器输出PWM控制。

有源蜂鸣器,和默认代码按键2冲突,修改按键2的GPIO为PB15

配置温湿度传感器DHT11
为每个单独的文件生成.C.H文件,方便调用头文件

生成KEIL的代码

到此我们就完成了项目的构建。
编译器设置
       因为硬件FLASH 空间限定,我们需要对APP 的固件大小做严格的限制。本方案,
针对秉火开发板 我们可允许的最大固件为54KB。需要升级的新固件同样最大可支持54KB。
1、设置FLASH 固件下载地址

2、配置中断向量偏移地址设置

3.重新构建工程,添加相关头文件。

4.添加flash.h,flash.h, gagent_md5.c, gagent_md5.h, app.c文件到项目

5. 在mian.c里面添加一下头文件

在main.c里面添加如下代码

       6.在gizwits_protocol.h里面添加如下代码
- /************************************ 
- * OTA 
- ************************************/ 
- #define PIECE_MAX_LEN 256 
- #define FILE_MD5_MAX_LEN 32 
- //#define SSL_MAX_LEN (FILE_MD5_MAX_LEN/2) 
- #define UPDATE_IS_HEX_FORMAT 0 // Piece Send Format 0,nohex; 1,hex 
- typedef enum 
- { 
- HEX = 0, 
- BIN, 
- } otaDataType; 
- __packed typedef struct 
- { 
- uint16_t piecenum; 
- uint16_t piececount; 
- uint8_t piececontent[PIECE_MAX_LEN]; 
- } updataPieceData_TypeDef; 
- typedef struct 
- { 
- uint16_t rom_statue; 
- uint32_t rom_size; 
- uint8_t ssl_data[SSL_MAX_LEN]; 
- } updateParamSave_t; 
- typedef struct 
- { 
- uint8_t otaBusyModeFlag; 
- uint32_t updateFileSize; //Rom Size 
- MD5_CTX ctx; 
- updateParamSave_t update_param;//Save Update Param 
- } mcuOTA_t; 
- int8_t Pro_W2D_UpdateDataHandle(uint8_t *inData , uint32_t dateLen , otaDataType formatType); 
- int8_t Pro_D2W_UpdateReady(uint8_t *md5Data , uint16_t md5Len); 
- int8_t Pro_W2D_UpdateCmdHandle(uint8_t *inData,uint32_t dataLen); 
- void Pro_D2W_UpdateSuspend(void); 
- void Pro_D2W_Ask_Module_Reboot(void); 


7. 在gizwits_protocol.c里面添加相应的代码,此处不一一例举,只截图详细,详细代码请看附件代码(注意修改gizwitsHandle函数,此处不做截图)。

       8.在gizwits_prduct.h修改这个参数可改变版本号,当前版本需要大于上一个版本。

       9.将代码下载到对应的地址,前面已配置好地址。后面需要生成bin文件才能进行推送(机智云最新版本的升级界面支持hex),在配置里面修改生成bin文件。


       10.在产品的OTA界面进行固件升级,升级配置如下,手动推送需要主动更新,静默推送自动更新,其余按照要求配置即可。

       到此本教程结束,如有疑问联系机智云技术支持,15120205205(QQ,微信,电话同号)
- #include "flash.h" 
- 2. #include <stdio.h> 
- 3. #include <string.h> 
- 4. volatile uint32_t flashWriteOffset = SYS_APP_BAK_SAVE_ADDR_BASE; 
- 5. volatile uint32_t flashReadOffset = SYS_APP_BAK_SAVE_ADDR_BASE; 
- 6. /* Exported types ------------------------------------------------------------*/ 
- 7. /** @defgroup FLASH_Exported_Types FLASH Exported Types 
- 8. * @{ 
- 9. */ 
- 10. /* MCU OTA */ 
- 11. void flash_erase_page(uint8_t flashPage , uint32_t addr_base) 
- 12. { 
- 13. HAL_FLASH_Unlock(); 
- 14. FLASH_EraseInitTypeDef f; 
- 15. f.TypeErase = FLASH_TYPEERASE_PAGES; 
- 16. f.PageAddress = flashPage + (addr_base - SYS_Bootloader_SAVE_ADDR_BASE)/FLASH_PAGE_SIZE; 
- 17. f.NbPages = 1; 
- 18. 
- 19. uint32_t PageError = 0; 
- 20. HAL_FLASHEx_Erase(&f, &PageError); 
- 21. HAL_FLASH_Lock(); 
- 22. } 
- 23. void flash_erase(uint32_t size , uint32_t addr_base) 
- 24. { 
- 25. uint32_t flashPageSum; 
- 26. uint32_t i; 
- 27. /*如果小于2048做处理*/ 
- 28. if(size < FLASH_PAGE_SIZE) 
- 29. size = FLASH_PAGE_SIZE; // 
- 30. /* 计算需要擦写的Flash页 */ 
- 31. if((size % FLASH_PAGE_SIZE) == 0) 
- 32. { 
- 33. flashPageSum = size / FLASH_PAGE_SIZE; //小于一页擦除一页 
- 34. } 
- 35. else 
- 36. { 
- 37. flashPageSum = (size / FLASH_PAGE_SIZE) + 1; //大于一页擦除n+1页 
- 38. } 
- 39. for(i = 0;i<flashPageSum;i++) 
- 40. { 
- 41. flash_erase_page(i,addr_base); //基址累加擦除flash 
- 42. } 
- 43. } 
- 44. 
- 45. void writeFlash(uint64_t * buf_to_save , uint16_t len , uint32_t wFlashAddr) 
- 46. { 
- 47. uint16_t count=0; 
- 48. if(wFlashAddr >= 0x08020000) 
- 49. { 
- 50. #ifdef DEBUG 
- 51. printf("Waring:Flash Write Addr Error\r\n"); 
- 52. #endif 
- 53. flashWriteOffset = SYS_APP_BAK_SAVE_ADDR_BASE; 
- 54. return; 
- 55. } 
- 56. HAL_FLASH_Unlock(); 
- 57. 
- 58. while(count < len) 
- 59. { 
- 60. HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,(wFlashAddr + count*8),buf_to_save[count]); //вflashһٶַ֘дɫѫؖè16λé 
- 61. count ++; 
- 62. } 
- 63. HAL_FLASH_Lock(); 
- 64. } 
- 65. 
- 66. void readFlash(uint64_t * buf_to_get,uint16_t len , uint32_t readFlashAddr) 
- 67. { 
- 68. uint16_t count=0; 
- 69. while(count<len) 
- 70. { 
- 71. buf_to_get[count]=*(uint64_t *)(readFlashAddr + count*8); 
- 72. count++; 
- 73. } 
- 74. } 
- 75. /*写Flash,控制写长度,Flash地址偏移*/ 
- 76. void wFlashData(uint8_t * buf_to_save , uint16_t len , uint32_t wFlashAddr) 
- 77. { 
- 78. uint8_t WriteFlashTempBuf[PIECE_MAX_LEN];//写Flash临时缓冲区 
- 79. uint16_t WriteFlashTempLen = 0;//写Flash长度 
- 80. uint8_t rem; 
- 81. memset(WriteFlashTempBuf,0xEE,sizeof(WriteFlashTempBuf));//写Flash临时缓冲区首先全部填充0xEE 
- 82. memcpy(WriteFlashTempBuf,buf_to_save,len);//临时缓冲区 
- 83. WriteFlashTempLen = len; 
- 84. if(len%8 != 0) 
- 85. { 
- 86. rem = len%8; 
- 87. WriteFlashTempLen = len +8 - rem; 
- 88. } 
- 89. writeFlash((uint64_t *)&WriteFlashTempBuf , WriteFlashTempLen/8 , wFlashAddr); 
- 90. } 
- 91. void rFlashData(uint8_t * buf_to_get , uint16_t len , uint32_t rFlashAddr) 
- 92. { 
- 93. uint8_t ReadFlashTempBuf[PIECE_MAX_LEN];//读Flash临时缓冲区 
- 94. uint16_t ReadFlashTempLen = 0;//读Flash长度 
- 95. uint8_t rem; 
- 96. if(len%8 == 0) 
- 97. { 
- 98. ReadFlashTempLen = len; 
- 99. readFlash((uint64_t *)&ReadFlashTempBuf,ReadFlashTempLen/8 , rFlashAddr); 
- 100. memcpy(buf_to_get,ReadFlashTempBuf,len); 
- 101. } 
- 102. else 
- 103. { 
- 104. rem = len%8; 
- 105. ReadFlashTempLen = len + 8 - rem; 
- 106. readFlash((uint64_t *)&ReadFlashTempBuf,ReadFlashTempLen/8 , rFlashAddr); 
- 107. memcpy(buf_to_get,ReadFlashTempBuf,len); 
- 108. } 
- 109. } 
- 110. /***IAP****/ 
- 111. typedef void (*iapfun)(void); 
- 112. iapfun jump2app; 
- 113. uint16_t iapbuf[1024]; 
- 114. 
- 115. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
- 116. #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) 
- 117. #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) 
- 118. 
- 119. 
- 120. /*#define iar 
- 121. #ifdef iar 
- 122. //设置栈顶地址 
- 123. //addr:栈顶地址 
- 124. 
- 125. void MSR_MSP(uint32_t addr) 
- 126. { 
- 127. asm("MSR MSP, r0 "); 
- 128. asm("BX r14"); 
- 129. } 
- 130. #else 
- 131. __asm void MSR_MSP(uint32_t addr) 
- 132. { 
- 133. MSR MSP, r0 //set Main Stack value 
- 134. BX r14 
- 135. } 
- 136. #endif 
- 137. */ 
- 138. __asm void MSR_MSP(uint32_t addr) 
- 139. { 
- 140. MSR MSP, r0 //set Main Stack value 
- 141. BX r14 
- 142. } 
- 143. 
- 144. 
- 145. void iap_load_app(uint32_t appxaddr) 
- 146. { 
- 147. if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) 
- 148. { 
- 149. #ifdef DEBUG 
- 150. printf("Stack Success!\r\n"); 
- 151. #endif 
- 152. jump2app=(iapfun)*(vu32*)(appxaddr+4); 
- 153. MSR_MSP(*(vu32*)appxaddr); 
- 154. /* Relocate vector table */ 
- 155. SCB->VTOR = (uint32_t)(appxaddr - SYS_Bootloader_SAVE_ADDR_BASE); 
- 156. jump2app(); 
- 157. } 
- 158. else 
- 159. { 
- 160. #ifdef DEBUG 
- 161. printf("Stack Failed!\r\n"); 
- 162. #endif 
- 163. } 
- 164. } 
- #ifndef _FLASH_ 
- 2. #define _FLASH_ 
- 3. #include "stm32f1xx_hal.h" 
- 4. //#define DEBUG 
- 5. //#define PROTOCOL_DEBUG 
- 6. typedef uint32_t u32; 
- 7. typedef uint16_t u16; 
- 8. typedef uint8_t u8; 
- 9. typedef __IO uint32_t vu32; 
- 10. typedef __IO uint16_t vu16; 
- 11. typedef __IO uint8_t vu8; 
- 12. /* BootLoader Flash首地址 */ 
- 13. #define SYS_Bootloader_SAVE_ADDR_BASE 0x08000000//Bootloader首地址//支持Bootloader大小18KB 
- 14. /* 升级参数存储 */ 
- 15. #define UPDATE_PARAM_SAVE_ADDR_BASE 0x08004800 
- 16. #define UPDATE_PARAM_MAX_SIZE (2*1024)//支持参数大小2KB 
- 17. /* APP Flash首地址 */ 
- 18. #define SYS_APP_SAVE_ADDR_BASE 0x08005000 
- 19. #define APP_DATA_MAX_SIZE (54*1024)//支持APP大小54KB 
- 20. /* APP BAK Flash首地址 */ 
- 21. #define SYS_APP_BAK_SAVE_ADDR_BASE 0x08012800 
- 22. #define APP_BAK_DATA_MAX_SIZE (54*1024)//支持APP_BAK大小54KB 
- 23. /* 升级参数 */ 
- 24. #define PIECE_MAX 256 
- 25. #define SSL_MAX_LEN 16 
- 26. typedef struct 
- 27. { 
- 28. uint16_t rom_statue; 
- 29. uint32_t rom_size; 
- 30. uint8_t ssl_data[SSL_MAX_LEN]; 
- 31. }update_param_def; 
- 32. /* FLASH页大小 */ 
- 33. //#define FLASH_PAGE_SIZE 0x400 //1KB 
- 34. /* 大数据分片大小 */ 
- 35. //#define BIGDATA_PIECE_MAX 200 //支持的最大数据分片即大数据最大传输单元,200B 
- 36. #define PIECE_MAX_LEN 256 
- 37. void save_param_to_flash(uint16_t * buf_to_save,uint16_t len ); 
- 38. void read_param_from_flash(uint16_t * buf_to_get,uint16_t len); 
- 39. void set_flash_flag_to_updata(uint16_t crc_code); 
- 40. void rFlashData(uint8_t * buf_to_get , uint16_t len , uint32_t rFlashAddr); 
- 41. void wFlashData(uint8_t * buf_to_save , uint16_t len , uint32_t wFlashAddr); 
- 42. void iap_load_app(uint32_t appxaddr); 
- 43. void flash_erase(uint32_t size , uint32_t addr_base); 
- 44. #endif 
- /** 
- 2. **************************************************** 
- 3. * @file : main.c 
- 4. * @brief : Main program body 
- 5. **************************************************** 
- 6. * @attention 
- 7. * 
- 8. * <h2><center>© Copyright (c) 2019 STMicroelectronics. 
- 9. * All rights reserved.</center></h2> 
- 10. * 
- 11. * This software component is licensed by ST under BSD 3-Clause license, 
- 12. * the "License"; You may not use this file except in compliance with the 
- 13. * License. You may obtain a copy of the License at: 
- 14. * opensource.org/licenses/BSD-3-Clause 
- 15. * 
- 16. **************************************************** 
- 17. */ 
- 18. /* Includes ------------------------------------------------------------------*/ 
- 19. #include "app.h" 
- 20. #include "../Src/md5/gagent_md5.h" 
- 21. #include "../Hal/flash.h" 
- 22. #include "usart.h" 
- 23. 
- 24. /*Global Variable*/ 
- 25. /** 
- 26. * @brief Main program. 
- 27. * @param None 
- 28. * @retval None 
- 29. */ 
- 30. update_param_def update_param; 
- 31. uint8_t md5_calc[SSL_MAX_LEN]; 
- 32. MD5_CTX ctx; 
- 33. void mcu_restart() 
- 34. { 
- 35. //__set_FAULTMASK(1); 
- 36. NVIC_SystemReset(); 
- 37. } 
- 38. int8_t ROM_MD5_Check(uint32_t sys_size , uint32_t FlashAddr , uint8_t *ssl) 
- 39. { 
- 40. uint8_t update_data_tmp[PIECE_MAX]; 
- 41. uint32_t load_loop = 0; 
- 42. uint32_t remaind_data_len = sys_size; 
- 43. uint32_t valid_data_len = 0; 
- 44. 
- 45. GAgent_MD5Init(&ctx); 
- 46. if(0 == sys_size%PIECE_MAX) 
- 47. { 
- 48. load_loop = sys_size / PIECE_MAX; 
- 49. } 
- 50. else 
- 51. { 
- 52. load_loop = sys_size / PIECE_MAX + 1; 
- 53. } 
- 54. #ifdef DEBUG 
- 55. printf("Check New Sys ...loop = %d\r\n",load_loop); 
- 56. #endif 
- 57. for(uint32_t i = 0;i<load_loop;i++) 
- 58. { 
- 59. if(remaind_data_len > PIECE_MAX) 
- 60. { 
- 61. valid_data_len = PIECE_MAX; 
- 62. } 
- 63. else 
- 64. { 
- 65. valid_data_len = remaind_data_len; 
- 66. } 
- 67. memset(update_data_tmp,0,PIECE_MAX); 
- 68. rFlashData(update_data_tmp, valid_data_len, FlashAddr + i*PIECE_MAX); 
- 69. GAgent_MD5Update(&ctx, update_data_tmp, valid_data_len); 
- 70. remaind_data_len = remaind_data_len - valid_data_len; 
- 71. #ifdef DEBUG 
- 72. printf("*"); 
- 73. #endif 
- 74. } 
- 75. #ifdef DEBUG 
- 76. printf("\r\n"); 
- 77. #endif 
- 78. GAgent_MD5Final(&ctx, md5_calc); 
- 79. #ifdef DEBUG 
- 80. printf("MD5 Calculate Success \r\n "); 
- 81. #endif 
- 82. if(memcmp(ssl, md5_calc, SSL_MAX_LEN) != 0) 
- 83. { 
- 84. #ifdef DEBUG 
- 85. printf("Md5_Cacl Check Faild ,MCU OTA Faild\r\n "); 
- 86. #endif 
- 87. #ifdef PROTOCOL_DEBUG 
- 88. printf("MD5: "); 
- 89. for(uint16_t i=0; i<SSL_MAX_LEN; i++) 
- 90. { 
- 91. printf("%02x ", md5_calc[i]); 
- 92. } 
- 93. printf("\r\n"); 
- 94. #endif 
- 95. return -1; 
- 96. } 
- 97. else 
- 98. { 
- 99. #ifdef DEBUG 
- 100. printf("MD5 Check Success ,MCU OTA Success\r\n "); 
- 101. #endif 
- 102. return 0; 
- 103. } 
- 104. } 
- 105. uint8_t update_new_system(uint32_t sys_size) 
- 106. { 
- 107. uint8_t update_data_tmp[PIECE_MAX]; 
- 108. uint32_t load_loop = 0; 
- 109. uint32_t remaind_data_len = sys_size; 
- 110. uint32_t valid_data_len = 0; 
- 111. 
- 112. if(0 == sys_size%PIECE_MAX) 
- 113. { 
- 114. load_loop = sys_size / PIECE_MAX; 
- 115. } 
- 116. else 
- 117. { 
- 118. load_loop = sys_size / PIECE_MAX + 1; 
- 119. } 
- 120. #ifdef DEBUG 
- 121. printf("Copy New Sys ...loop = %d\r\n",load_loop); 
- 122. #endif 
- 123. 
- 124. flash_erase(update_param.rom_size , SYS_APP_SAVE_ADDR_BASE); 
- 125. #ifdef DEBUG 
- 126. printf("Copy New Sys\r\n"); 
- 127. #endif 
- 128. for(uint32_t i = 0;i<load_loop;i++) 
- 129. { 
- 130. if(remaind_data_len > PIECE_MAX) 
- 131. { 
- 132. valid_data_len = PIECE_MAX; 
- 133. } 
- 134. else 
- 135. { 
- 136. valid_data_len = remaind_data_len; 
- 137. } 
- 138. memset(update_data_tmp,0,PIECE_MAX); 
- 139. rFlashData(update_data_tmp, valid_data_len, SYS_APP_BAK_SAVE_ADDR_BASE + i*PIECE_MAX); 
- 140. 
- 141. wFlashData(update_data_tmp , valid_data_len , SYS_APP_SAVE_ADDR_BASE + i*PIECE_MAX); 
- 142. remaind_data_len = remaind_data_len - valid_data_len; 
- 143. #ifdef DEBUG 
- 144. printf("."); 
- 145. #endif 
- 146. } 
- 147. #ifdef DEBUG 
- 148. printf("\r\n"); 
- 149. printf("Copy Success , Wait to Check... \r\n"); 
- 150. #endif 
- 151. 
- 152. if(0 == ROM_MD5_Check(update_param.rom_size , SYS_APP_SAVE_ADDR_BASE , update_param.ssl_data)) 
- 153. { 
- 154. #ifdef DEBUG 
- 155. printf("New ROM Check Success , Wait to Load New Systerm \r\n"); 
- 156. #endif 
- 157. flash_erase(sizeof(update_param_def), UPDATE_PARAM_SAVE_ADDR_BASE); 
- 158. mcu_restart(); 
- 159. } 
- 160. else 
- 161. { 
- 162. #ifdef DEBUG 
- 163. printf("New ROM Check Faild , Update Faild , MCU Try To Update Again ,MCU Restart... \r\n"); 
- 164. #endif 
- 165. mcu_restart(); 
- 166. } 
- 167. 
- 168. return 0; 
- 169. } 
- 170. void APP_Process(void) 
- 171. { 
- 172. memset((uint8_t *)&update_param, 0 , sizeof(update_param_def)); 
- 173. rFlashData((uint8_t *)&update_param, sizeof(update_param_def), UPDATE_PARAM_SAVE_ADDR_BASE); 
- 174. if(0xEEEE == update_param.rom_statue) 
- 175. { 
- 176. #ifdef DEBUG 
- 177. printf("Update Task ,Sys Will Load New Sys..Wait For A Moment \r\n"); 
- 178. printf("Update Size [%d] \r\n",update_param.rom_size); 
- 179. #endif 
- 180. if(0 == ROM_MD5_Check(update_param.rom_size , SYS_APP_BAK_SAVE_ADDR_BASE , update_param.ssl_data)) 
- 181. { 
- 182. update_new_system(update_param.rom_size); 
- 183. } 
- 184. else 
- 185. { 
- 186. #ifdef DEBUG 
- 187. printf("Check Faild , Go to Old Systerm\r\n"); 
- 188. #endif 
- 189. flash_erase(sizeof(update_param_def), UPDATE_PARAM_SAVE_ADDR_BASE); 
- 190. if(((*(vu32*)(SYS_APP_SAVE_ADDR_BASE + 4)) & 0xFF000000) == 0x08000000) 
- 191. { 
- 192. #ifdef DEBUG 
- 193. printf("Sys Will Load APP.....\r\n"); 
- 194. #endif 
- 195. iap_load_app(SYS_APP_SAVE_ADDR_BASE); 
- 196. } 
- 197. else 
- 198. { 
- 199. #ifdef DEBUG 
- 200. printf("Start APP Failed!\r\n"); 
- 201. #endif 
- 202. } 
- 203. } 
- 204. 
- 205. } 
- 206. else 
- 207. { 
- 208. #ifdef DEBUG 
- 209. printf("No Update Task , Go To APP ....%04X\r\n",update_param.rom_statue); 
- 210. #endif 
- 211. if(((*(vu32*)(SYS_APP_SAVE_ADDR_BASE + 4)) & 0xFF000000) == 0x08000000) 
- 212. { 
- 213. #ifdef DEBUG 
- 214. printf("Sys Will Load APP.....\r\n"); 
- 215. #endif 
- 216. iap_load_app(SYS_APP_SAVE_ADDR_BASE); 
- 217. } 
- 218. else 
- 219. { 
- 220. #ifdef DEBUG 
- 221. printf("Start APP Failed!\r\n"); 
- 222. 
- 223. #endif 
- 224. 
- 225. } 
- 226. } 
- 227. } 
- /** 
- 2. **************************************************** 
- 3. * File Name : gpio.h 
- 4. * Description : This file contains all the functions prototypes for 
- 5. * the gpio 
- 6. **************************************************** 
- 7. ** This notice applies to any and all portions of this file 
- 8. * that are not between comment pairs USER CODE BEGIN and 
- 9. * USER CODE END. Other portions of this file, whether 
- 10. * inserted by the user or by software development tools 
- 11. * are owned by their respective copyright owners. 
- 12. * 
- 13. * COPYRIGHT(c) 2019 STMicroelectronics 
- 14. * 
- 15. * Redistribution and use in source and binary forms, with or without modification, 
- 16. * are permitted provided that the following conditions are met: 
- 17. * 1. Redistributions of source code must retain the above copyright notice, 
- 18. * this list of conditions and the following disclaimer. 
- 19. * 2. Redistributions in binary form must reproduce the above copyright notice, 
- 20. * this list of conditions and the following disclaimer in the documentation 
- 21. * and/or other materials provided with the distribution. 
- 22. * 3. Neither the name of STMicroelectronics nor the names of its contributors 
- 23. * may be used to endorse or promote products derived from this software 
- 24. * without specific prior written permission. 
- 25. * 
- 26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
- 27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
- 28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- 29. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
- 30. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
- 31. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- 32. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
- 33. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
- 34. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- 35. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- 36. * 
- 37. **************************************************** 
- 38. */ 
- 39. 
- 40. /* Define to prevent recursive inclusion -------------------------------------*/ 
- 41. #ifndef __app_H 
- 42. #define __app_H 
- 43. #ifdef __cplusplus 
- 44. extern "C" { 
- 45. #endif 
- 46. 
- 47. /* Includes ------------------------------------------------------------------*/ 
- 48. #include "main.h" 
- 49. #include <stdio.h> 
- 50. #include <string.h> 
- 51. 
- 52. 
- 53. void APP_Process(void); 
- 54. 
- 55. #ifdef __cplusplus 
- 56. } 
- 57. #endif 
- 58. #endif /*__ pinoutConfig_H */ 
- 59. 
- 60. /** 
- 61. * @} 
- 62. */ 
- 63. 
- 64. /** 
- 65. * @} 
- 66. */ 
- 67. 
- 68. /**************** (C) COPYRIGHT STMicroelectronics ****END OF FILE***/ 
- #include <string.h> 
- 2. #include "gagent_md5.h" 
- 3. unsigned char PADDING[] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
- 4. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
- 5. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
- 6. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
- 7. void GAgent_MD5Init(MD5_CTX *context) 
- 8. { 
- 9. context->count[0] = 0; 
- 10. context->count[1] = 0; 
- 11. context->state[0] = 0x67452301; 
- 12. context->state[1] = 0xEFCDAB89; 
- 13. context->state[2] = 0x98BADCFE; 
- 14. context->state[3] = 0x10325476; 
- 15. } 
- 16. void GAgent_MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen) 
- 17. { 
- 18. unsigned int i = 0, index = 0, partlen = 0; 
- 19. index = (context->count[0] >> 3) & 0x3F; 
- 20. partlen = 64 - index; 
- 21. context->count[0] += inputlen << 3; 
- 22. if (context->count[0] < (inputlen << 3)) 
- 23. context->count[1]++; 
- 24. context->count[1] += inputlen >> 29; 
- 25. if (inputlen >= partlen) 
- 26. { 
- 27. memcpy(&context->buffer[index], input, partlen); 
- 28. GAgent_MD5Transform(context->state, context->buffer); 
- 29. for (i = partlen; i + 64 <= inputlen; i += 64) 
- 30. GAgent_MD5Transform(context->state, &input[i]); 
- 31. index = 0; 
- 32. } 
- 33. else 
- 34. { 
- 35. i = 0; 
- 36. } 
- 37. memcpy(&context->buffer[index], &input[i], inputlen - i); 
- 38. } 
- 39. void GAgent_MD5Final(MD5_CTX *context, unsigned char digest[16]) 
- 40. { 
- 41. unsigned int index = 0, padlen = 0; 
- 42. unsigned char bits[8]; 
- 43. index = (context->count[0] >> 3) & 0x3F; 
- 44. padlen = (index < 56) ? (56 - index) : (120 - index); 
- 45. GAgent_MD5Encode(bits, context->count, 8); 
- 46. GAgent_MD5Update(context, PADDING, padlen); 
- 47. GAgent_MD5Update(context, bits, 8); 
- 48. GAgent_MD5Encode(digest, context->state, 16); 
- 49. } 
- 50. void GAgent_MD5Encode(unsigned char *output, unsigned int *input, unsigned int len) 
- 51. { 
- 52. unsigned int i = 0, j = 0; 
- 53. while (j < len) 
- 54. { 
- 55. output[j] = input[i] & 0xFF; 
- 56. output[j + 1] = (input[i] >> 8) & 0xFF; 
- 57. output[j + 2] = (input[i] >> 16) & 0xFF; 
- 58. output[j + 3] = (input[i] >> 24) & 0xFF; 
- 59. i++; 
- 60. j += 4; 
- 61. } 
- 62. } 
- 63. void GAgent_MD5Decode(unsigned int *output, unsigned char *input, unsigned int len) 
- 64. { 
- 65. unsigned int i = 0, j = 0; 
- 66. while (j < len) 
- 67. { 
- 68. output[i] = (input[j]) | 
- 69. (input[j + 1] << 8) | 
- 70. (input[j + 2] << 16) | 
- 71. (input[j + 3] << 24); 
- 72. i++; 
- 73. j += 4; 
- 74. } 
- 75. } 
- 76. void GAgent_MD5Transform(unsigned int state[4], unsigned char block[64]) 
- 77. { 
- 78. unsigned int a = state[0]; 
- 79. unsigned int b = state[1]; 
- 80. unsigned int c = state[2]; 
- 81. unsigned int d = state[3]; 
- 82. unsigned int x[64]; 
- 83. GAgent_MD5Decode(x, block, 64); 
- 84. FF(a, b, c, d, x[0], 7, 0xd76aa478); /* 1 */ 
- 85. FF(d, a, b, c, x[1], 12, 0xe8c7b756); /* 2 */ 
- 86. FF(c, d, a, b, x[2], 17, 0x242070db); /* 3 */ 
- 87. FF(b, c, d, a, x[3], 22, 0xc1bdceee); /* 4 */ 
- 88. FF(a, b, c, d, x[4], 7, 0xf57c0faf); /* 5 */ 
- 89. FF(d, a, b, c, x[5], 12, 0x4787c62a); /* 6 */ 
- 90. FF(c, d, a, b, x[6], 17, 0xa8304613); /* 7 */ 
- 91. FF(b, c, d, a, x[7], 22, 0xfd469501); /* 8 */ 
- 92. FF(a, b, c, d, x[8], 7, 0x698098d8); /* 9 */ 
- 93. FF(d, a, b, c, x[9], 12, 0x8b44f7af); /* 10 */ 
- 94. FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ 
- 95. FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ 
- 96. FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ 
- 97. FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ 
- 98. FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ 
- 99. FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ 
- 100. 
- 101. /* Round 2 */ 
- 102. GG(a, b, c, d, x[1], 5, 0xf61e2562); /* 17 */ 
- 103. GG(d, a, b, c, x[6], 9, 0xc040b340); /* 18 */ 
- 104. GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ 
- 105. GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); /* 20 */ 
- 106. GG(a, b, c, d, x[5], 5, 0xd62f105d); /* 21 */ 
- 107. GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */ 
- 108. GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ 
- 109. GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); /* 24 */ 
- 110. GG(a, b, c, d, x[9], 5, 0x21e1cde6); /* 25 */ 
- 111. GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ 
- 112. GG(c, d, a, b, x[3], 14, 0xf4d50d87); /* 27 */ 
- 113. GG(b, c, d, a, x[8], 20, 0x455a14ed); /* 28 */ 
- 114. GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ 
- 115. GG(d, a, b, c, x[2], 9, 0xfcefa3f8); /* 30 */ 
- 116. GG(c, d, a, b, x[7], 14, 0x676f02d9); /* 31 */ 
- 117. GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ 
- 118. 
- 119. /* Round 3 */ 
- 120. HH(a, b, c, d, x[5], 4, 0xfffa3942); /* 33 */ 
- 121. HH(d, a, b, c, x[8], 11, 0x8771f681); /* 34 */ 
- 122. HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ 
- 123. HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ 
- 124. HH(a, b, c, d, x[1], 4, 0xa4beea44); /* 37 */ 
- 125. HH(d, a, b, c, x[4], 11, 0x4bdecfa9); /* 38 */ 
- 126. HH(c, d, a, b, x[7], 16, 0xf6bb4b60); /* 39 */ 
- 127. HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ 
- 128. HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ 
- 129. HH(d, a, b, c, x[0], 11, 0xeaa127fa); /* 42 */ 
- 130. HH(c, d, a, b, x[3], 16, 0xd4ef3085); /* 43 */ 
- 131. HH(b, c, d, a, x[6], 23, 0x4881d05); /* 44 */ 
- 132. HH(a, b, c, d, x[9], 4, 0xd9d4d039); /* 45 */ 
- 133. HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ 
- 134. HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ 
- 135. HH(b, c, d, a, x[2], 23, 0xc4ac5665); /* 48 */ 
- 136. 
- 137. /* Round 4 */ 
- 138. II(a, b, c, d, x[0], 6, 0xf4292244); /* 49 */ 
- 139. II(d, a, b, c, x[7], 10, 0x432aff97); /* 50 */ 
- 140. II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ 
- 141. II(b, c, d, a, x[5], 21, 0xfc93a039); /* 52 */ 
- 142. II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ 
- 143. II(d, a, b, c, x[3], 10, 0x8f0ccc92); /* 54 */ 
- 144. II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ 
- 145. II(b, c, d, a, x[1], 21, 0x85845dd1); /* 56 */ 
- 146. II(a, b, c, d, x[8], 6, 0x6fa87e4f); /* 57 */ 
- 147. II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ 
- 148. II(c, d, a, b, x[6], 15, 0xa3014314); /* 59 */ 
- 149. II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ 
- 150. II(a, b, c, d, x[4], 6, 0xf7537e82); /* 61 */ 
- 151. II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ 
- 152. II(c, d, a, b, x[2], 15, 0x2ad7d2bb); /* 63 */ 
- 153. II(b, c, d, a, x[9], 21, 0xeb86d391); /* 64 */ 
- 154. state[0] += a; 
- 155. state[1] += b; 
- 156. state[2] += c; 
- 157. state[3] += d; 
- 158. } 
- #ifndef _GAGENT_MD5_H 
- 2. #define _GAGENT_MD5_H 
- 3. 
- 4. typedef struct 
- 5. { 
- 6. unsigned int count[2]; 
- 7. unsigned int state[4]; 
- 8. unsigned char buffer[64]; 
- 9. } MD5_CTX; 
- 10. #define F(x,y,z) ((x & y) | (~x & z)) 
- 11. #define G(x,y,z) ((x & z) | (y & ~z)) 
- 12. #define H(x,y,z) (x^y^z) 
- 13. #define I(x,y,z) (y ^ (x | ~z)) 
- 14. #define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) 
- 15. #define FF(a,b,c,d,x,s,ac) \ 
- 16. { \ 
- 17. a += F(b,c,d) + x + ac; \ 
- 18. a = ROTATE_LEFT(a,s); \ 
- 19. a += b; \ 
- 20. } 
- 21. #define GG(a,b,c,d,x,s,ac) \ 
- 22. { \ 
- 23. a += G(b,c,d) + x + ac; \ 
- 24. a = ROTATE_LEFT(a,s); \ 
- 25. a += b; \ 
- 26. } 
- 27. #define HH(a,b,c,d,x,s,ac) \ 
- 28. { \ 
- 29. a += H(b,c,d) + x + ac; \ 
- 30. a = ROTATE_LEFT(a,s); \ 
- 31. a += b; \ 
- 32. } 
- 33. #define II(a,b,c,d,x,s,ac) \ 
- 34. { \ 
- 35. a += I(b,c,d) + x + ac; \ 
- 36. a = ROTATE_LEFT(a,s); \ 
- 37. a += b; \ 
- 38. } 
- 39. void GAgent_MD5Init(MD5_CTX *context); 
- 40. void GAgent_MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen); 
- 41. void GAgent_MD5Final(MD5_CTX *context, unsigned char digest[16]); 
- 42. void GAgent_MD5Transform(unsigned int state[4], unsigned char block[64]); 
- 43. void GAgent_MD5Encode(unsigned char *output, unsigned int *input, unsigned int len); 
- 44. void GAgent_MD5Decode(unsigned int *output, unsigned char *input, unsigned int len); 
- 45. #endif 

 
					
				
 
			
			
			
						
			 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

