基于机智云物联网平台MCU模式基础教程及远程OTA-Arduino中文社区 - Powered by Discuz! Archiver

机智小子 发表于 2021-1-26 18:19

基于机智云物联网平台MCU模式基础教程及远程OTA


编写背景:
       用户如果将开发了的产品发布上线销售,后期需要更新固件和程序,就需要用到远程OTA固件升级,就能对已发布的产品进行远程升级。

材料准备:
       1.机智云4G模组GC211,此模组采用中移模组ML302,需烧录机智云GAgent固件,可在机智云淘宝店铺购买或者联系商务获取,此模组支持网络,移动,联通,电信4G网络,可前往机智云官方和淘宝店铺购买。https://shop159680395.taobao.com/
https://club.gizwits.com/data/attachment/forum/202101/26/142603xtioxv9n62xmvoz0.png.thumb.jpg

       2.秉火【F103开发板-指南者】
https://club.gizwits.com/data/attachment/forum/202101/26/142604r6lffgqgg13a1659.jpg.thumb.jpg


正文:
云端部署
创建新产品,可根据自己需求选择。
https://club.gizwits.com/data/attachment/forum/202101/26/142604ceep1868iei8orop.png.thumb.jpg

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

https://club.gizwits.com/data/attachment/forum/202101/26/142605p3y6e3n3z6c3c6ec.png.thumb.jpg
生成STM32F103代码下载备用
https://club.gizwits.com/data/attachment/forum/202101/26/142605ldjjkc3qzqoicpqk.png.thumb.jpg

       简述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分区方案如下图所示:
https://club.gizwits.com/data/attachment/forum/202101/26/143637em7l8qqm54m88d9d.png.thumb.jpg

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

Bootloader程序配置
为了方便构架,此处我采用cubemx构建项目,生成keil工程。
创建STM32F103VE项目
https://club.gizwits.com/data/attachment/forum/202101/26/142606mk4sgksjjm11lboi.png.thumb.jpg

配置外部时钟
https://club.gizwits.com/data/attachment/forum/202101/26/142607o7vb5pzukvjkxrsx.png.thumb.jpg

配置时钟72M
https://club.gizwits.com/data/attachment/forum/202101/26/142607ezsu0uu8d1s3susc.png.thumb.jpg

配置debug为serisl wire
https://club.gizwits.com/data/attachment/forum/202101/26/142607ne1wuz99pt8pzupt.png.thumb.jpg

配置串口4为BootLoader的日志打印口。
https://club.gizwits.com/data/attachment/forum/202101/26/142608efj5ikyrr8nj55f1.png.thumb.jpg

生成keil代码添加驱动flash.c,gagent_md5.c和app.c以及对应的组,如何添加此处不过多介绍(基础的软件操作),只提供文件路径。
https://club.gizwits.com/data/attachment/forum/202101/26/142608z784p1781irk2k7z.png.thumb.jpg
https://club.gizwits.com/data/attachment/forum/202101/26/142608jvbpbl0eneepgdqe.png.thumb.jpg
https://club.gizwits.com/data/attachment/forum/202101/26/142609np31mmp4vf3dxbvb.png.thumb.jpg
https://club.gizwits.com/data/attachment/forum/202101/26/142609y7qeejwx3z07q7gv.png.thumb.jpg
https://club.gizwits.com/data/attachment/forum/202101/26/142609lu57u25077887edc.png.thumb.jpg





驱动文件的编写以及函数介绍我此处不过多介绍,可以在福建进行下载源文件,也可以在文章末尾复制代码。代码只讲重点部分。
Main.c添加头文件#include "app.h"
https://club.gizwits.com/data/attachment/forum/202101/26/142610oylyetoldwe1ez2y.png.thumb.jpg

主函数添加APP_Process();https://club.gizwits.com/data/attachment/forum/202101/26/142610hbthbickjvjk8i1m.png.thumb.jpg

根据自己分区大小设置区域,我的是18K,2k,54k,54k
https://club.gizwits.com/data/attachment/forum/202101/26/142611t55vhzerk24p5kap.png.thumb.jpg

Bootloader编译设置
按照 Bootloader 流程编写好代码,需要我们对 KEIL 工程做相应配置,需要注意的是编译的 Bootloader 固件大小不超过最大可允许的 18KB。Keil 编译器需要设置如下:
https://club.gizwits.com/data/attachment/forum/202101/26/142611lijjfizhi0nnnp0w.png.thumb.jpg

Flash 烧写地址设置有效https://club.gizwits.com/data/attachment/forum/202101/26/142611ssna2ss08m1dcg0m.png.thumb.jpg
设置ST-LINK按块擦除 FLASH 区间和烧写程序https://club.gizwits.com/data/attachment/forum/202101/26/142611ndgdrahoygya1rjd.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202101/26/142612vrpfri5hrphtfs5f.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202101/26/142612smggcgc7fjlwgrj4.png.thumb.jpg


编译烧录程序,到此BootLoader编写烧录完成。https://club.gizwits.com/data/attachment/forum/202101/26/142612x3noxspyzpyioogv.png.thumb.jpg

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

CUBEMX部署
解压云端生成的代码,由于生成的代码是STM32F103c8的,我们需要通过CUBEMX转换成STM32F103VET6的代码来适应我们的秉火开发板,创建一个新的cubeMX项目,导入自动代码的CUBEMX工程.
https://club.gizwits.com/data/attachment/forum/202101/26/142613k5o5gzg1s0gvqyvs.png.thumb.jpg

目录保存在解压代码所在的路径。
https://club.gizwits.com/data/attachment/forum/202101/26/142613p5lb95ht16gg6gg1.png.thumb.jpg

修改时钟树为72M,注意需要同BootLoader时钟。
https://club.gizwits.com/data/attachment/forum/202101/26/142614cg70e094ezhgg46d.png.thumb.jpg

根据项目需求以及我们自己创建的数据点,我们需要控制RGB灯,蜂鸣器,DHT11,在此处我们需要对引脚进行初始化。
https://club.gizwits.com/data/attachment/forum/202101/26/142614xzsbffsim4q833qd.png.thumb.jpg
配置RGB灯,采用定时器输出PWM控制。
https://club.gizwits.com/data/attachment/forum/202101/26/142614k17oqfxd7wdf734d.png.thumb.jpg

有源蜂鸣器,和默认代码按键2冲突,修改按键2的GPIO为PB15
https://club.gizwits.com/data/attachment/forum/202101/26/142615qmneb2eymwebwtkk.png.thumb.jpg

配置温湿度传感器DHT11



为每个单独的文件生成.C.H文件,方便调用头文件
https://club.gizwits.com/data/attachment/forum/202101/26/142615pe4gbrl5g623r46q.png.thumb.jpg

生成KEIL的代码
https://club.gizwits.com/data/attachment/forum/202101/26/142615ljo0lvooa1bhcm0u.png.thumb.jpg

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

2、配置中断向量偏移地址设置
https://club.gizwits.com/data/attachment/forum/202101/26/142616bbxwl62dpv5dxg25.png.thumb.jpg

3.重新构建工程,添加相关头文件。
https://club.gizwits.com/data/attachment/forum/202101/26/142616lnvibffxmxlnmtms.png.thumb.jpg

4.添加flash.h,flash.h, gagent_md5.c, gagent_md5.h, app.c文件到项目
https://club.gizwits.com/data/attachment/forum/202101/26/142617had9pqiqiju79e8p.png.thumb.jpg

5. 在mian.c里面添加一下头文件
https://club.gizwits.com/data/attachment/forum/202101/26/142617hyqlsm4ywhldsch4.png.thumb.jpg

在main.c里面添加如下代码
https://club.gizwits.com/data/attachment/forum/202101/26/142618lyj4iiwj44cryk4t.png.thumb.jpg

       6.在gizwits_protocol.h里面添加如下代码

[*]/************************************
[*]* OTA
[*]************************************/
[*]#define PIECE_MAX_LEN256
[*]
[*]#define FILE_MD5_MAX_LEN32
[*]//#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;
[*]
[*]} updataPieceData_TypeDef;
[*]
[*]typedef struct
[*]{
[*]    uint16_t rom_statue;
[*]
[*]    uint32_t rom_size;
[*]
[*]    uint8_tssl_data;
[*]
[*]} 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);

复制代码
https://club.gizwits.com/data/attachment/forum/202101/26/142618nh1h2oovt0iho0c0.png.thumb.jpg

https://club.gizwits.com/data/attachment/forum/202101/26/142619qxwpzv3xxucw9wm0.png.thumb.jpg


7. 在gizwits_protocol.c里面添加相应的代码,此处不一一例举,只截图详细,详细代码请看附件代码(注意修改gizwitsHandle函数,此处不做截图)。
https://club.gizwits.com/data/attachment/forum/202101/26/142620hqqria4qw6rzeir8.png.thumb.jpg

       8.在gizwits_prduct.h修改这个参数可改变版本号,当前版本需要大于上一个版本。
https://club.gizwits.com/data/attachment/forum/202101/26/142620rf39469kgeqag4s9.png.thumb.jpg

       9.将代码下载到对应的地址,前面已配置好地址。后面需要生成bin文件才能进行推送(机智云最新版本的升级界面支持hex),在配置里面修改生成bin文件。
https://club.gizwits.com/data/attachment/forum/202101/26/142621ol0e7a4eg4jfejmm.png.thumb.jpg
https://club.gizwits.com/data/attachment/forum/202101/26/142622ocittc9ici7nccje.png.thumb.jpg


       10.在产品的OTA界面进行固件升级,升级配置如下,手动推送需要主动更新,静默推送自动更新,其余按照要求配置即可。
https://club.gizwits.com/data/attachment/forum/202101/26/142622q5sw67v64zc4lcsf.png.thumb.jpg

       到此本教程结束,如有疑问联系机智云技术支持,15120205205(QQ,微信,电话同号)
FLASH驱动编写Flash.c1
[*]   #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); //в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=*(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;//写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;//读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.    typedefvoid (*iapfun)(void);
[*]
[*]112.    iapfun jump2app;
[*]
[*]113.    uint16_t iapbuf;
[*]
[*]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.    }

复制代码

flash.h1.
[*]   #ifndef _FLASH_
[*]2.    #define _FLASH_
[*]3.    #include "stm32f1xx_hal.h"
[*]
[*]4.    //#define DEBUG
[*]5.    //#define PROTOCOL_DEBUG
[*]6.    typedef uint32_tu32;
[*]
[*]7.    typedef uint16_t u16;
[*]
[*]8.    typedef uint8_tu8;
[*]
[*]9.    typedef __IO uint32_tvu32;
[*]
[*]10.typedef __IO uint16_t vu16;
[*]
[*]11.typedef __IO uint8_tvu8;
[*]
[*]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_tssl_data;
[*]
[*]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_LEN256
[*]
[*]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

复制代码

APP驱动编写app.c1.
[*]   /**
[*]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.    * @briefMain program.
[*]
[*]27.    * @paramNone
[*]
[*]28.    * @retval None
[*]
[*]29.    */
[*]30.update_param_def update_param;
[*]
[*]31.uint8_t md5_calc;
[*]
[*]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;
[*]
[*]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);
[*]
[*]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;
[*]
[*]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.    }

复制代码

app.h1.
[*]   /**
[*]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***/

复制代码


gagent_md5驱动编写gagent_md5.c1.
[*]   #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;
[*]10.      context->count = 0;
[*]11.      context->state = 0x67452301;
[*]12.      context->state = 0xEFCDAB89;
[*]13.      context->state = 0x98BADCFE;
[*]14.      context->state = 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 >> 3) & 0x3F;
[*]
[*]20.      partlen = 64 - index;
[*]21.      context->count += inputlen << 3;
[*]22.      if (context->count < (inputlen << 3))
[*]
[*]23.      context->count++;
[*]24.      context->count += inputlen >> 29;
[*]
[*]25.      if (inputlen >= partlen)
[*]26.      {
[*]27.      memcpy(&context->buffer, input, partlen);
[*]
[*]28.      GAgent_MD5Transform(context->state, context->buffer);
[*]
[*]29.      for (i = partlen; i + 64 <= inputlen; i += 64)
[*]
[*]30.               GAgent_MD5Transform(context->state, &input);
[*]
[*]31.      index = 0;
[*]32.      }
[*]33.      else
[*]34.      {
[*]35.      i = 0;
[*]36.      }
[*]37.      memcpy(&context->buffer, &input, inputlen - i);
[*]
[*]38.}
[*]39.void GAgent_MD5Final(MD5_CTX *context, unsigned char digest)
[*]
[*]40.{
[*]41.      unsigned int index = 0, padlen = 0;
[*]42.      unsigned char bits;
[*]43.      index = (context->count >> 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 = input & 0xFF;
[*]56.      output = (input >> 8) & 0xFF;
[*]
[*]57.      output = (input >> 16) & 0xFF;
[*]
[*]58.      output = (input >> 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 = (input) |
[*]69.                      (input << 8) |
[*]70.                      (input << 16) |
[*]71.                      (input << 24);
[*]72.      i++;
[*]73.      j += 4;
[*]74.      }
[*]75.}
[*]76.void GAgent_MD5Transform(unsigned int state, unsigned char block)
[*]
[*]77.{
[*]78.      unsigned int a = state;
[*]79.      unsigned int b = state;
[*]80.      unsigned int c = state;
[*]81.      unsigned int d = state;
[*]82.      unsigned int x;
[*]83.      GAgent_MD5Decode(x, block, 64);
[*]84.      FF(a, b, c, d, x, 7, 0xd76aa478); /* 1 */
[*]85.      FF(d, a, b, c, x, 12, 0xe8c7b756); /* 2 */
[*]
[*]86.      FF(c, d, a, b, x, 17, 0x242070db); /* 3 */
[*]
[*]87.      FF(b, c, d, a, x, 22, 0xc1bdceee); /* 4 */
[*]
[*]88.      FF(a, b, c, d, x, 7, 0xf57c0faf); /* 5 */
[*]89.      FF(d, a, b, c, x, 12, 0x4787c62a); /* 6 */
[*]
[*]90.      FF(c, d, a, b, x, 17, 0xa8304613); /* 7 */
[*]
[*]91.      FF(b, c, d, a, x, 22, 0xfd469501); /* 8 */
[*]
[*]92.      FF(a, b, c, d, x, 7, 0x698098d8); /* 9 */
[*]93.      FF(d, a, b, c, x, 12, 0x8b44f7af); /* 10 */
[*]
[*]94.      FF(c, d, a, b, x, 17, 0xffff5bb1); /* 11 */
[*]
[*]95.      FF(b, c, d, a, x, 22, 0x895cd7be); /* 12 */
[*]
[*]96.      FF(a, b, c, d, x, 7, 0x6b901122); /* 13 */
[*]
[*]97.      FF(d, a, b, c, x, 12, 0xfd987193); /* 14 */
[*]
[*]98.      FF(c, d, a, b, x, 17, 0xa679438e); /* 15 */
[*]
[*]99.      FF(b, c, d, a, x, 22, 0x49b40821); /* 16 */
[*]
[*]100.
[*]101.      /* Round 2 */
[*]102.      GG(a, b, c, d, x, 5, 0xf61e2562); /* 17 */
[*]103.      GG(d, a, b, c, x, 9, 0xc040b340); /* 18 */
[*]104.      GG(c, d, a, b, x, 14, 0x265e5a51); /* 19 */
[*]
[*]105.      GG(b, c, d, a, x, 20, 0xe9b6c7aa); /* 20 */
[*]106.      GG(a, b, c, d, x, 5, 0xd62f105d); /* 21 */
[*]107.      GG(d, a, b, c, x, 9, 0x2441453); /* 22 */
[*]108.      GG(c, d, a, b, x, 14, 0xd8a1e681); /* 23 */
[*]
[*]109.      GG(b, c, d, a, x, 20, 0xe7d3fbc8); /* 24 */
[*]110.      GG(a, b, c, d, x, 5, 0x21e1cde6); /* 25 */
[*]111.      GG(d, a, b, c, x, 9, 0xc33707d6); /* 26 */
[*]112.      GG(c, d, a, b, x, 14, 0xf4d50d87); /* 27 */
[*]113.      GG(b, c, d, a, x, 20, 0x455a14ed); /* 28 */
[*]114.      GG(a, b, c, d, x, 5, 0xa9e3e905); /* 29 */
[*]115.      GG(d, a, b, c, x, 9, 0xfcefa3f8); /* 30 */
[*]116.      GG(c, d, a, b, x, 14, 0x676f02d9); /* 31 */
[*]117.      GG(b, c, d, a, x, 20, 0x8d2a4c8a); /* 32 */
[*]
[*]118.
[*]119.      /* Round 3 */
[*]120.      HH(a, b, c, d, x, 4, 0xfffa3942); /* 33 */
[*]121.      HH(d, a, b, c, x, 11, 0x8771f681); /* 34 */
[*]122.      HH(c, d, a, b, x, 16, 0x6d9d6122); /* 35 */
[*]
[*]123.      HH(b, c, d, a, x, 23, 0xfde5380c); /* 36 */
[*]
[*]124.      HH(a, b, c, d, x, 4, 0xa4beea44); /* 37 */
[*]125.      HH(d, a, b, c, x, 11, 0x4bdecfa9); /* 38 */
[*]126.      HH(c, d, a, b, x, 16, 0xf6bb4b60); /* 39 */
[*]127.      HH(b, c, d, a, x, 23, 0xbebfbc70); /* 40 */
[*]
[*]128.      HH(a, b, c, d, x, 4, 0x289b7ec6); /* 41 */
[*]129.      HH(d, a, b, c, x, 11, 0xeaa127fa); /* 42 */
[*]130.      HH(c, d, a, b, x, 16, 0xd4ef3085); /* 43 */
[*]131.      HH(b, c, d, a, x, 23, 0x4881d05); /* 44 */
[*]132.      HH(a, b, c, d, x, 4, 0xd9d4d039); /* 45 */
[*]133.      HH(d, a, b, c, x, 11, 0xe6db99e5); /* 46 */
[*]
[*]134.      HH(c, d, a, b, x, 16, 0x1fa27cf8); /* 47 */
[*]
[*]135.      HH(b, c, d, a, x, 23, 0xc4ac5665); /* 48 */
[*]136.
[*]137.      /* Round 4 */
[*]138.      II(a, b, c, d, x, 6, 0xf4292244); /* 49 */
[*]139.      II(d, a, b, c, x, 10, 0x432aff97); /* 50 */
[*]140.      II(c, d, a, b, x, 15, 0xab9423a7); /* 51 */
[*]
[*]141.      II(b, c, d, a, x, 21, 0xfc93a039); /* 52 */
[*]142.      II(a, b, c, d, x, 6, 0x655b59c3); /* 53 */
[*]143.      II(d, a, b, c, x, 10, 0x8f0ccc92); /* 54 */
[*]144.      II(c, d, a, b, x, 15, 0xffeff47d); /* 55 */
[*]
[*]145.      II(b, c, d, a, x, 21, 0x85845dd1); /* 56 */
[*]146.      II(a, b, c, d, x, 6, 0x6fa87e4f); /* 57 */
[*]147.      II(d, a, b, c, x, 10, 0xfe2ce6e0); /* 58 */
[*]
[*]148.      II(c, d, a, b, x, 15, 0xa3014314); /* 59 */
[*]149.      II(b, c, d, a, x, 21, 0x4e0811a1); /* 60 */
[*]
[*]150.      II(a, b, c, d, x, 6, 0xf7537e82); /* 61 */
[*]151.      II(d, a, b, c, x, 10, 0xbd3af235); /* 62 */
[*]
[*]152.      II(c, d, a, b, x, 15, 0x2ad7d2bb); /* 63 */
[*]153.      II(b, c, d, a, x, 21, 0xeb86d391); /* 64 */
[*]154.      state += a;
[*]155.      state += b;
[*]156.      state += c;
[*]157.      state += d;
[*]158.    }

复制代码

gagent_md5.h1.
[*]#ifndef _GAGENT_MD5_H
[*]
[*]2.    #define _GAGENT_MD5_H
[*]
[*]3.
[*]4.    typedef struct
[*]5.    {
[*]6.      unsigned int count;
[*]7.      unsigned int state;
[*]8.      unsigned char buffer;
[*]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);
[*]
[*]42.void GAgent_MD5Transform(unsigned int state, unsigned char block);
[*]
[*]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
[*]

复制代码

页: [1]
查看完整版本: 基于机智云物联网平台MCU模式基础教程及远程OTA