收藏官网首页
查看: 10310|回复: 0

【官方】通过机智云OTA升级MCU固件

140

主题

418

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
12682
跳转到指定楼层
楼主
发表于 2020-2-7 12:43:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
校园创客福利

GAgent OTA教程

MCU OTA教程(2.0)

MCU OTA教程(3.0)

MCU OTA教程(3.1)

源文档及源参考代码下载


概述

MCU OTA可以对MCU程序进行无线远程升级。原本MCU程序软件版本号是01,想升级到02,但是设备已经量产了不可能再去一个一个设备重新烧录新的程序,这时候就需要用到MCU OTA.本文以MCU OTA教程(3.1)的基础上移植到STM32G071RBT6芯片。下载源文档及源参考代码


FLASH分区

STM32G071RBT6芯片Flash 空间划分出 4 个区域:Bootloader、FLAG、APP 分区、APPBAK 分区

  • Bootloader:存储 Bootloader 固件,MCU 上电后首先运行该固件。
  • FLAG:存储有关升级的相关标志位,Bootloader 和 APP 分区都需要操作该区域。

升级标志位(2B)

固件大小(4B)

MD5加密数据(16B)

  • APP 分区:存储用户程序固件。
  • APPBAK 分区:临时存储云端下发的新固件,升级固件的一个过渡存储区。


BOOTLOADER分区部分
Bootloader程序流程

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

Bootloader编译设置


APP分区部分固件接收流程

做好 BOOTLOADER 工作后,我们开始写 APP 分区的代码。APP 分区固件的编写要注意硬件版本号和软件版本号,软件版号作为升级迭代很重要的标志。

App编译设置




FLASH驱动编写

Flash.c

  1. #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. /* MCU OTA */
  7. void flash_erase_page(uint8_t flashPage , uint32_t addr_base)
  8. {
  9.         HAL_FLASH_Unlock();

  10.     FLASH_EraseInitTypeDef f;
  11.     f.TypeErase = FLASH_TYPEERASE_PAGES;
  12.     f.Page = flashPage + (addr_base - SYS_Bootloader_SAVE_ADDR_BASE)/FLASH_PAGE_SIZE;
  13.     f.NbPages = 1;
  14.        
  15.     uint32_t PageError = 0;
  16.     HAL_FLASHEx_Erase(&f, &PageError);
  17.         HAL_FLASH_Lock();
  18. }
  19. void flash_erase(uint32_t size , uint32_t addr_base)
  20. {
  21.     uint32_t flashPageSum;
  22.                 uint32_t i;
  23.     /*如果小于2048做处理*/
  24.     if(size < FLASH_PAGE_SIZE)
  25.         size = FLASH_PAGE_SIZE;                                                                                                //
  26.     /* 计算需要擦写的Flash页 */
  27.     if((size % FLASH_PAGE_SIZE) == 0)
  28.     {
  29.         flashPageSum = size / FLASH_PAGE_SIZE;                                //小于一页擦除一页
  30.     }
  31.     else
  32.     {
  33.         flashPageSum = (size / FLASH_PAGE_SIZE) + 1;        //大于一页擦除n+1页
  34.     }
  35.     for(i = 0;i<flashPageSum;i++)
  36.     {
  37.                         flash_erase_page(i,addr_base);                                                                //基址累加擦除flash
  38.     }
  39. }

  40. void writeFlash(uint64_t * buf_to_save , uint16_t len , uint32_t wFlashAddr)
  41. {
  42.     uint16_t count=0;
  43.     if(wFlashAddr >= 0x08020000)
  44.     {
  45. #ifdef DEBUG
  46.         printf("Waring:Flash Write Addr Error\r\n");
  47. #endif
  48.         flashWriteOffset = SYS_APP_BAK_SAVE_ADDR_BASE;
  49.         return;
  50.     }
  51.         HAL_FLASH_Unlock();

  52.                 while(count < len)
  53.                 {
  54.                                 HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,(wFlashAddr + count*8),buf_to_save[count]); //вflashһٶַ֘дɫѫؖè16λé       
  55.                                 count ++;     
  56.                 }
  57.                 HAL_FLASH_Lock();
  58. }

  59. void readFlash(uint64_t * buf_to_get,uint16_t len , uint32_t readFlashAddr)
  60. {
  61.         uint16_t count=0;
  62.         while(count<len)
  63.         {
  64.                  buf_to_get[count]=*(uint64_t *)(readFlashAddr + count*8);
  65.                 count++;
  66.         }
  67. }
  68. /*写Flash,控制写长度,Flash地址偏移*/
  69. void wFlashData(uint8_t * buf_to_save , uint16_t len , uint32_t wFlashAddr)
  70. {
  71.     uint8_t WriteFlashTempBuf[PIECE_MAX_LEN];//写Flash临时缓冲区
  72.     uint16_t WriteFlashTempLen = 0;//写Flash长度
  73.         uint8_t rem;
  74.     memset(WriteFlashTempBuf,0xEE,sizeof(WriteFlashTempBuf));//写Flash临时缓冲区首先全部填充0xEE
  75.     memcpy(WriteFlashTempBuf,buf_to_save,len);//临时缓冲区
  76.     WriteFlashTempLen = len;
  77.     if(len%8 != 0)
  78.         {
  79.                 rem = len%8;
  80.                 WriteFlashTempLen = len +8 - rem;
  81.         }
  82.     writeFlash((uint64_t *)&WriteFlashTempBuf ,  WriteFlashTempLen/8 , wFlashAddr);
  83. }
  84. void rFlashData(uint8_t * buf_to_get , uint16_t len , uint32_t rFlashAddr)
  85. {
  86.     uint8_t ReadFlashTempBuf[PIECE_MAX_LEN];//读Flash临时缓冲区
  87.     uint16_t ReadFlashTempLen = 0;//读Flash长度
  88.     uint8_t rem;
  89.     if(len%8 == 0)
  90.     {
  91.         ReadFlashTempLen = len;
  92.         readFlash((uint64_t *)&ReadFlashTempBuf,ReadFlashTempLen/8 , rFlashAddr);
  93.         memcpy(buf_to_get,ReadFlashTempBuf,len);
  94.     }
  95.     else
  96.     {
  97.                 rem = len%8;
  98.         ReadFlashTempLen = len + 8 - rem;
  99.         readFlash((uint64_t *)&ReadFlashTempBuf,ReadFlashTempLen/8 , rFlashAddr);
  100.         memcpy(buf_to_get,ReadFlashTempBuf,len);
  101.     }
  102. }
复制代码

跳转到APP代码:

  1. typedef  void (*iapfun)(void);
  2. iapfun jump2app;
  3. uint16_t iapbuf[1024];   

  4. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
  5. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
  6. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

  7. //设置栈顶指针
  8. __asm void MSR_MSP(uint32_t addr)
  9. {
  10.     MSR MSP, r0                         //set Main Stack value
  11.     BX r14
  12. }
  13. void iap_load_app(uint32_t appxaddr)
  14. {
  15.         if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)
  16.         {
  17. #ifdef DEBUG
  18.                 printf("Stack Success!\r\n");
  19. #endif
  20.                 jump2app=(iapfun)*(vu32*)(appxaddr+4);
  21.                 MSR_MSP(*(vu32*)appxaddr);
  22.                 jump2app();
  23.         }
  24.         else
  25.         {
  26. #ifdef DEBUG
  27.                 printf("Stack Failed!\r\n");
  28. #endif
  29.         }
  30. }
复制代码

Flash.h

  1. #ifndef _FLASH_
  2. #define _FLASH_

  3. #include <stm32g0xx.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大小14KB
  14. /* 升级参数存储 */
  15. #define UPDATE_PARAM_SAVE_ADDR_BASE         0x08003800
  16. #define UPDATE_PARAM_MAX_SIZE               (2*1024)//支持参数大小2KB

  17. /* APP Flash首地址 */
  18. #define SYS_APP_SAVE_ADDR_BASE              0x08004000
  19. #define APP_DATA_MAX_SIZE                   (56*1024)//支持APP大小56KB
  20. /* APP BAK Flash首地址 */
  21. #define SYS_APP_BAK_SAVE_ADDR_BASE          0x08012000
  22. #define APP_BAK_DATA_MAX_SIZE               (56*1024)//支持APP_BAK大小56KB

  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. #define PIECE_MAX_LEN  256

  33. void save_param_to_flash(uint16_t * buf_to_save,uint16_t len );
  34. void read_param_from_flash(uint16_t * buf_to_get,uint16_t len);
  35. void set_flash_flag_to_updata(uint16_t crc_code);

  36. void rFlashData(uint8_t * buf_to_get , uint16_t len , uint32_t rFlashAddr);
  37. void wFlashData(uint8_t * buf_to_save , uint16_t len , uint32_t wFlashAddr);
  38. void iap_load_app(uint32_t appxaddr);
  39. void flash_erase(uint32_t size , uint32_t addr_base);
  40. #endif
复制代码

BOOTLOADER分区OTA功能代码移植通过CubMX新建工程

配置GPIO和UART4


配置时钟



生成代码



代码移植

添加Flash.c/h和GAgent_md5.c/h到工程中


新建app.c


  1. #include "app.h"
  2. #include "../Src/md5/gagent_md5.h"
  3. #include "flash.h"
  4. #include "usart.h"

  5. /*Global Variable*/
  6. /**
  7.   * @brief  Main program.
  8.   * @param  None
  9.   * @retval None
  10.   */
  11. update_param_def update_param;
  12. uint8_t md5_calc[SSL_MAX_LEN];
  13. MD5_CTX ctx;
  14. void mcu_restart()
  15. {
  16.     //__set_FAULTMASK(1);
  17.     NVIC_SystemReset();
  18. }
  19. int8_t ROM_MD5_Check(uint32_t sys_size , uint32_t FlashAddr , uint8_t *ssl)
  20. {
  21.     uint8_t update_data_tmp[PIECE_MAX];
  22.     uint32_t load_loop = 0;
  23.     uint32_t remaind_data_len = sys_size;
  24.     uint32_t valid_data_len = 0;
  25.        
  26.     GAgent_MD5Init(&ctx);
  27.     if(0 == sys_size%PIECE_MAX)
  28.     {
  29.         load_loop = sys_size / PIECE_MAX;
  30.     }
  31.     else
  32.     {
  33.         load_loop = sys_size / PIECE_MAX + 1;
  34.     }
  35. #ifdef DEBUG
  36.     printf("Check New Sys ...loop = %d\r\n",load_loop);
  37. #endif
  38.     for(uint32_t i = 0;i<load_loop;i++)
  39.     {
  40.         if(remaind_data_len > PIECE_MAX)
  41.         {
  42.             valid_data_len = PIECE_MAX;
  43.         }
  44.         else
  45.         {
  46.             valid_data_len = remaind_data_len;
  47.         }
  48.         memset(update_data_tmp,0,PIECE_MAX);
  49.         rFlashData(update_data_tmp, valid_data_len, FlashAddr + i*PIECE_MAX);
  50.         GAgent_MD5Update(&ctx, update_data_tmp, valid_data_len);
  51.         remaind_data_len = remaind_data_len - valid_data_len;
  52. #ifdef DEBUG
  53.         printf("*");
  54. #endif
  55.     }
  56. #ifdef DEBUG
  57.     printf("\r\n");
  58. #endif
  59.     GAgent_MD5Final(&ctx, md5_calc);
  60. #ifdef DEBUG
  61.     printf("MD5 Calculate Success \r\n ");
  62. #endif
  63.     if(memcmp(ssl, md5_calc, SSL_MAX_LEN) != 0)
  64.     {
  65. #ifdef DEBUG
  66.         printf("Md5_Cacl Check Faild ,MCU OTA Faild\r\n ");
  67. #endif
  68. #ifdef PROTOCOL_DEBUG
  69.         printf("MD5: ");
  70.         for(uint16_t i=0; i<SSL_MAX_LEN; i++)
  71.         {
  72.             printf("x ", md5_calc[i]);
  73.         }
  74.         printf("\r\n");
  75. #endif
  76.         return -1;
  77.     }
  78.     else
  79.     {
  80. #ifdef DEBUG
  81.         printf("MD5 Check Success ,MCU OTA Success\r\n ");
  82. #endif
  83.         return 0;
  84.     }
  85. }
  86. uint8_t update_new_system(uint32_t sys_size)
  87. {
  88.     uint8_t update_data_tmp[PIECE_MAX];
  89.     uint32_t load_loop = 0;
  90.     uint32_t remaind_data_len = sys_size;
  91.     uint32_t valid_data_len = 0;
  92.        
  93.     if(0 == sys_size%PIECE_MAX)
  94.     {
  95.         load_loop = sys_size / PIECE_MAX;
  96.     }
  97.     else
  98.     {
  99.         load_loop = sys_size / PIECE_MAX + 1;
  100.     }
  101. #ifdef DEBUG
  102.     printf("Copy New Sys ...loop = %d\r\n",load_loop);
  103. #endif

  104.     flash_erase(update_param.rom_size , SYS_APP_SAVE_ADDR_BASE);
  105. #ifdef DEBUG
  106.     printf("Copy New Sys\r\n");
  107. #endif
  108.     for(uint32_t i = 0;i<load_loop;i++)
  109.     {
  110.         if(remaind_data_len > PIECE_MAX)
  111.         {
  112.             valid_data_len = PIECE_MAX;
  113.         }
  114.         else
  115.         {
  116.             valid_data_len = remaind_data_len;
  117.         }
  118.         memset(update_data_tmp,0,PIECE_MAX);
  119.         rFlashData(update_data_tmp, valid_data_len, SYS_APP_BAK_SAVE_ADDR_BASE + i*PIECE_MAX);
  120.         
  121.         wFlashData(update_data_tmp , valid_data_len , SYS_APP_SAVE_ADDR_BASE + i*PIECE_MAX);
  122.         remaind_data_len = remaind_data_len - valid_data_len;
  123. #ifdef DEBUG
  124.         printf(".");
  125. #endif
  126.     }
  127. #ifdef DEBUG
  128.     printf("\r\n");
  129.     printf("Copy Success , Wait to Check... \r\n");
  130. #endif

  131.     if(0 == ROM_MD5_Check(update_param.rom_size , SYS_APP_SAVE_ADDR_BASE , update_param.ssl_data))
  132.     {
  133. #ifdef DEBUG
  134.         printf("New ROM Check Success , Wait to Load New Systerm \r\n");
  135. #endif
  136.         flash_erase(sizeof(update_param_def), UPDATE_PARAM_SAVE_ADDR_BASE);
  137.         mcu_restart();
  138.     }
  139.     else
  140.     {
  141. #ifdef DEBUG
  142.         printf("New ROM Check Faild , Update Faild , MCU Try To Update Again ,MCU Restart... \r\n");
  143. #endif
  144.         mcu_restart();
  145.     }

  146.     return 0;
  147. }
  148. void APP_Process(void)
  149. {       
  150.         memset((uint8_t *)&update_param, 0 , sizeof(update_param_def));
  151.         rFlashData((uint8_t *)&update_param, sizeof(update_param_def), UPDATE_PARAM_SAVE_ADDR_BASE);
  152.     if(0xEEEE == update_param.rom_statue)
  153.     {
  154. #ifdef DEBUG
  155.         printf("Update Task ,Sys Will Load New Sys..Wait For A Moment \r\n");
  156.         printf("Update Size [%d] \r\n",update_param.rom_size);
  157. #endif
  158.         if(0 == ROM_MD5_Check(update_param.rom_size , SYS_APP_BAK_SAVE_ADDR_BASE , update_param.ssl_data))
  159.         {
  160.             update_new_system(update_param.rom_size);
  161.         }
  162.         else
  163.         {
  164. #ifdef DEBUG
  165.             printf("Check Faild , Go to Old Systerm\r\n");
  166. #endif
  167.             flash_erase(sizeof(update_param_def), UPDATE_PARAM_SAVE_ADDR_BASE);
  168.             if(((*(vu32*)(SYS_APP_SAVE_ADDR_BASE + 4)) & 0xFF000000) == 0x08000000)
  169.             {
  170. #ifdef DEBUG
  171.                 printf("Sys Will Load APP.....\r\n");
  172. #endif
  173.                 iap_load_app(SYS_APP_SAVE_ADDR_BASE);
  174.             }
  175.             else
  176.             {
  177. #ifdef DEBUG
  178.                 printf("Start APP Failed!\r\n");
  179. #endif
  180.             }
  181.         }
  182.         
  183.     }
  184.     else
  185.     {
  186. #ifdef DEBUG
  187.                 printf("No Update Task , Go To APP ....X\r\n",update_param.rom_statue);
  188. #endif
  189.                 if(((*(vu32*)(SYS_APP_SAVE_ADDR_BASE + 4)) & 0xFF000000) == 0x08000000)
  190.                 {
  191. #ifdef DEBUG
  192.             printf("Sys Will Load APP.....\r\n");
  193. #endif
  194.                         iap_load_app(SYS_APP_SAVE_ADDR_BASE);
  195.                 }
  196.                 else
  197.                 {
  198. #ifdef DEBUG
  199.                         printf("Start APP Failed!\r\n");
  200.                        
  201. #endif
  202.                        
  203.                 }
  204.     }
  205. }
复制代码
更改主代码main.c



APP分区OTA功能代码移植代码移植

添加Flash.c/h和gagent_md5.c/h到工程中


中断向量偏移地址修改:



app.c


gizwits_protocol.h




gizwits_protocol.c



尾部添加以下代码:

  1. /**
  2. * @brief Pro_W2D_UpdateCmdHandle

  3. * Handle OTA Ask , Transform MD5 Char2Hex

  4. * @param[in]  :
  5. * @param[out] :
  6. * @return  0,Update Ask Handle Success , Send Ready Success
  7. *                                        -1,Input Param Illegal
  8. *                                        -2,Update Ask Handle Success , Send Ready Faild
  9. *
  10. */
  11. int8_t Pro_W2D_UpdateCmdHandle(uint8_t *inData,uint32_t dataLen)
  12. {
  13.     uint8_t k = 0;
  14.     int8_t ret = 0;

  15.     uint8_t  fileMD5value[FILE_MD5_MAX_LEN];
  16.     uint16_t fileMD5len;                        //MD5 Length

  17.     if(NULL == inData)
  18.     {
  19.         return -1;
  20.     }

  21.     romUpdate.updateFileSize = ((uint32_t)(inData[0]<<24))|((uint32_t)(inData[1]<<16))|((uint32_t)(inData[2]<<8))|((uint32_t)(inData[3]));

  22.     //judge flash size
  23.     if(romUpdate.updateFileSize > APP_BAK_DATA_MAX_SIZE)
  24.     {
  25.         GIZWITS_LOG("UpdateFileSize Error ,Update Failed ,fileSize = %d \n",romUpdate.updateFileSize);
  26.         return -1;
  27.     }
  28.     else
  29.     {
  30.         GIZWITS_LOG("UpdateFileSize Legal ,size = %d \n",romUpdate.updateFileSize);
  31.         romUpdate.update_param.rom_size = romUpdate.updateFileSize;
  32.         flash_erase(APP_BAK_DATA_MAX_SIZE,SYS_APP_BAK_SAVE_ADDR_BASE);
  33.                         GIZWITS_LOG("flash erase finished!!\n");
  34.     }

  35.     fileMD5len = inData[4]*256 + inData[5];
  36.     GIZWITS_LOG("FileMD5len  = %d ", fileMD5len);

  37.     memcpy(fileMD5value,&inData[6],fileMD5len);
  38. #ifdef PROTOCOL_DEBUG
  39.     GIZWITS_LOG("MD5: ");
  40.     for(uint16_t i=0; i<32; i++)
  41.     {
  42.         GIZWITS_LOG("x ", fileMD5value[i]);
  43.     }
  44.     GIZWITS_LOG("\r\n");
  45. #endif

  46.     for(uint16_t j = 0; j<SSL_MAX_LEN; j++)
  47.     {
  48.         romUpdate.update_param.ssl_data[j] = char2hex(fileMD5value[k],fileMD5value[k+1]);
  49.         k += 2;
  50.     }
  51. #ifdef PROTOCOL_DEBUG
  52.     GIZWITS_LOG("MD5_Hex: ");
  53.     for(uint16_t i=0; i<SSL_MAX_LEN; i++)
  54.     {
  55.         GIZWITS_LOG("x ", romUpdate.update_param.ssl_data[i]);
  56.     }
  57.     GIZWITS_LOG("\r\n");
  58. #endif

  59.     GIZWITS_LOG("GAgent_MD5Init \n");
  60.     GAgent_MD5Init(&romUpdate.ctx);

  61.     //send ready
  62.     ret = Pro_D2W_UpdateReady(fileMD5value,fileMD5len);
  63.     if(0 != ret)
  64.     {
  65.         GIZWITS_LOG("Pro_D2W_UpdateReady Error ,Error Code = %d \n",ret);
  66.         return -2;
  67.     }

  68.     return 0;
  69. }

  70. /**
  71. * @brief Pro_D2W_UpdateReady

  72. * MCU Send Update Ready

  73. * @param[in]  md5Data: Input md5 char data
  74. * @param[in]  md5Len : Input md5 length
  75. * @param[out] :
  76. * @return  0,Update Ask Handle Success , Send Ready Success
  77. *                                        -1,Input Param Illegal
  78. *                                        -2,Uart Send Faild
  79. *
  80. */
  81. int8_t Pro_D2W_UpdateReady(uint8_t *md5Data , uint16_t md5Len)
  82. {
  83.     int8_t ret = 0;
  84.     uint8_t txBuf[100];
  85.                 memset(txBuf,0,100);
  86.     uint8_t *pTxBuf = txBuf;
  87.     if(NULL == md5Data)
  88.     {
  89.         return -1;
  90.     }

  91.     uint16_t dataLen = sizeof(protocolCommon_t) + 2 + md5Len + 2 - 4 ;
  92.     *pTxBuf ++= 0xFF;
  93.     *pTxBuf ++= 0xFF;
  94.     *pTxBuf ++= (uint8_t)(dataLen>>8);
  95.     *pTxBuf ++= (uint8_t)(dataLen);
  96.     *pTxBuf ++= CMD_BIGDATA_READY;
  97.     *pTxBuf ++= gizwitsProtocol.sn++;

  98.     *pTxBuf ++= 0x00;//flag
  99.     txBuf[7] |= UPDATE_IS_HEX_FORMAT<<0;//TERRY WARNING
  100.     pTxBuf += 1;

  101.     *pTxBuf ++= (uint8_t)(md5Len>>8);//len
  102.     *pTxBuf ++= (uint8_t)(md5Len);

  103.     memcpy(&txBuf[8 + 2],md5Data,md5Len);
  104.     pTxBuf += md5Len;

  105.     *pTxBuf ++= (uint8_t)(PIECE_MAX_LEN>>8);//len
  106.     *pTxBuf ++= (uint8_t)(PIECE_MAX_LEN);
  107.     *pTxBuf ++= gizProtocolSum(txBuf , (dataLen+4));

  108.     ret = uartWrite(txBuf , (dataLen+4));
  109.     if(ret < 0)
  110.     {
  111.         GIZWITS_LOG("ERROR: uart write error %d \n", ret);
  112.         return -2;
  113.     }
  114.     GIZWITS_LOG("MCU Ready To Update ROM \n");
  115.     return 0;
  116. }

  117. /**
  118. * @brief Pro_W2D_UpdateDataHandle

  119. * update Piece Handle ,  Judge Last Piece

  120. * @param[in] indata   : Piece Data
  121. * @param[in] dataLen    : Piece Length
  122. * @param[in] formatType : Piece Data Format
  123. * @param[out]
  124. * @return  0,Handle Success
  125. *                                        -1,Input Param Illegal
  126. *                                        -2,Last Piece , MD5 Check Faild
  127. *
  128. */
  129. int8_t Pro_W2D_UpdateDataHandle(uint8_t *inData , uint32_t dataLen , otaDataType formatType)
  130. {
  131.     uint16_t piecenum = 0;
  132.     uint16_t piececount = 0;
  133.     uint32_t tempWFlashAddr = 0;
  134.     updataPieceData_TypeDef pieceData;
  135.     uint8_t md5_calc[SSL_MAX_LEN];//MD5 Calculate Fact

  136.     if(NULL == inData)
  137.     {
  138.         return -1;
  139.     }

  140.     memcpy((uint8_t *)&pieceData, inData, dataLen);

  141.     piecenum = exchangeBytes(pieceData.piecenum);
  142.     piececount = exchangeBytes(pieceData.piececount);

  143.     GIZWITS_LOG("****piecenum = %d , piececount = %d, pieceSize = %d****** \r\n",piecenum,piececount,dataLen - 4);


  144.     tempWFlashAddr = SYS_APP_BAK_SAVE_ADDR_BASE + (piecenum-1) * PIECE_MAX_LEN;
  145.     wFlashData((uint8_t *)pieceData.piececontent , dataLen - 4, tempWFlashAddr);

  146.     GAgent_MD5Update(&romUpdate.ctx, (uint8_t *)pieceData.piececontent, dataLen - 4);

  147.     /*updata package data ,ack*/
  148.     if(piecenum == piececount)
  149.     {
  150.         memset(md5_calc,0,SSL_MAX_LEN);
  151.         GAgent_MD5Final(&romUpdate.ctx, md5_calc);
  152.         GIZWITS_LOG("MD5 Calculate Success , Will Check The MD5 ..\n ");

  153.         if(0 != memcmp(romUpdate.update_param.ssl_data, md5_calc, SSL_MAX_LEN))
  154.         {
  155.             GIZWITS_LOG("Md5_Cacl Check Faild ,MCU OTA Faild\r\n ");
  156. #ifdef PROTOCOL_DEBUG
  157.             GIZWITS_LOG("Calc MD5: ");
  158.             for(uint16_t i=0; i<SSL_MAX_LEN; i++)
  159.             {
  160.                 GIZWITS_LOG("x ", md5_calc[i]);
  161.             }
  162.             GIZWITS_LOG("\r\n");
  163. #endif
  164. #ifdef PROTOCOL_DEBUG
  165.             GIZWITS_LOG("SSL MD5: ");
  166.             for(uint16_t i=0; i<SSL_MAX_LEN; i++)
  167.             {
  168.                 GIZWITS_LOG("x ", romUpdate.update_param.ssl_data[i]);
  169.             }
  170.             GIZWITS_LOG("\r\n");
  171. #endif
  172.             memset((uint8_t *)&romUpdate.update_param,0,sizeof(updateParamSave_t));

  173.             return -2;
  174.         }
  175.         else
  176.         {
  177.             GIZWITS_LOG("MD5 Check Success ,Storage  ROM Success , Write Update Flag\n ");
  178.             flash_erase(sizeof(updateParamSave_t) , UPDATE_PARAM_SAVE_ADDR_BASE);

  179.             romUpdate.update_param.rom_statue = 0xEEEE;
  180.             wFlashData((uint8_t *)&romUpdate.update_param, sizeof(updateParamSave_t), UPDATE_PARAM_SAVE_ADDR_BASE);
  181.                                                 //romUpdate.update_param.rom_statue = 0x1234;
  182.                                                 //printf("\n\romUpdate.update_param.rom_statue = X \r\n\n",romUpdate.update_param.rom_statue);
  183.                                                 //memset((uint8_t *)&romUpdate, 0 , sizeof(romUpdate));
  184.                                                 //rFlashData((uint8_t *)&romUpdate, sizeof(romUpdate), UPDATE_PARAM_SAVE_ADDR_BASE);
  185.                                                 //printf("\n\romUpdate.update_param.rom_statue = X \r\n\n",romUpdate.update_param.rom_statue);
  186.                                        
  187.             GIZWITS_LOG("System Will Restart... \n");
  188.             /*******************MCU RESTART*******************/
  189.             mcuRestart();
  190.             /****************************************************/
  191.             //last package , updata ok
  192.             //MD5 checkout :Failed clear updata,Success , write flash ,begin updata
  193.         }
  194.     }
  195.     return 0;
  196. }

  197. /**
  198. * @brief Pro_D2W_UpdateSuspend

  199. * Data Receiver

  200. * @param[in]    : Void
  201. * @param[out]         :
  202. * @return                          : Void
  203. *
  204. */
  205. void Pro_D2W_UpdateSuspend()
  206. {
  207.     int32_t ret = 0;
  208.     protocolCommon_t protocolCommon;
  209.     memset(&protocolCommon, 0, sizeof(protocolCommon_t));
  210.     gizProtocolHeadInit((protocolHead_t *)&protocolCommon);
  211.     protocolCommon.head.len = exchangeBytes(sizeof(protocolCommon_t)-4);
  212.     protocolCommon.head.cmd = CMD_D_STOP_BIGDATA_SEND;
  213.     protocolCommon.head.sn = gizwitsProtocol.sn++;
  214.     protocolCommon.sum = gizProtocolSum((uint8_t *)&protocolCommon, sizeof(protocolCommon_t));

  215.     ret = uartWrite((uint8_t *)&protocolCommon,sizeof(protocolCommon_t));
  216.     if(ret < 0)
  217.     {
  218.         GIZWITS_LOG("ERROR: uart write error %d \n", ret);
  219.     }

  220.     gizProtocolWaitAck((uint8_t *)&protocolCommon,sizeof(protocolCommon_t));

  221. }

  222. /**
  223. * @brief Pro_D2W_Ask_Module_Reboot

  224. * Ask Module Reboot

  225. * @param[in]    : Void
  226. * @param[out]         :
  227. * @return                          : Void
  228. *
  229. */
  230. void Pro_D2W_Ask_Module_Reboot()
  231. {
  232.     int32_t ret = 0;
  233.     protocolCommon_t protocolCommon;
  234.     memset(&protocolCommon, 0, sizeof(protocolCommon_t));
  235.     gizProtocolHeadInit((protocolHead_t *)&protocolCommon);
  236.     protocolCommon.head.len = exchangeBytes(sizeof(protocolCommon_t)-4);
  237.     protocolCommon.head.cmd = CMD_REBOOT_MODULE;
  238.     protocolCommon.head.sn = gizwitsProtocol.sn++;
  239.     protocolCommon.sum = gizProtocolSum((uint8_t *)&protocolCommon, sizeof(protocolCommon_t));

  240.     ret = uartWrite((uint8_t *)&protocolCommon,sizeof(protocolCommon_t));
  241.     if(ret < 0)
  242.     {
  243.         GIZWITS_LOG("ERROR: uart write error %d \n", ret);
  244.     }

  245.     gizProtocolWaitAck((uint8_t *)&protocolCommon,sizeof(protocolCommon_t));

  246. }
复制代码

更改软件版本号,更改后的版本号要比原先版本号大

gizwits_product.h


MCU OTA验证

第一次用stlink烧录boot和app代码后,mcu日志如图


准备OTA,先让设备连上机智云






OTA成功










您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表