stm32F4 OTA升级(APP部分)

#ifndef __OTA_LOGIC_H__
#define __OTA_LOGIC_H__



#include "basic.h"



void OtaLogic_init(void);


//开始升级OTA
uint8_t OtaLogic_StartOTA(void);


//升级数据 处理
uint8_t OtaLogic_UPdate(char* data);


uint8_t OTALOGIC_UPDATE(int offset, int len, char* data);



/*OTA CRC校验*/
uint8_t OtaLogic_Check(void);



uint8_t OtaWriteReadOtaParamFlag(void);

#endif

/*OTA 数据初始化*/
void OtaLogic_init()
{
    memset(&gOTALogic, 0, sizeof(gOTALogic));
    gOTALogic.Status = OTA_INIT;
}



//开始升级OTA
uint8_t OtaLogic_StartOTA(void)
{
    uint8_t ret = 0;
    //u32 currentRunAPPAddr_para2 = 0;
    //OTA开始升级
    gOTALogic.Status = OTA_START;

    gOTALogic.Current_WriteOfset = 0;
    memset(gOTALogic.WritePageBuffer, 0 , sizeof(uint8_t) * OTA_WRITE_PAGE_SIZE);

    gOTALogic.LastRemaidLen = 0;
    memset(gOTALogic.LastRemaidBuffer, 0 , sizeof(uint8_t) * OTA_WRITE_PAGE_SIZE);



    printf("开始升级....\r\n");

    printf("0.当前是APP版本 程序将保存在 OTA_DOWN_ADDR\r\n");
    gOTALogic.OTAPackSaveAddr = OTA_DOWN_ADDR;
    printf("0.擦除 OTA保存区 ....\r\n");
    STMFLASH_EraseSector(OTA_DOWN_SECRTOR, 1);
		
    HAL_Delay(1000);  //延迟500MS
    printf("0.擦除成功\r\n");
	
    printf("0.设置保存区 地址[%08x]\r\n", gOTALogic.OTAPackSaveAddr);

    gOTALogic.WritePageIndex = 0;
    gOTALogic.OtaTcpFlashReadCrc = 0;
    gOTALogic.OtaTcpRecvCrc = 0;

    ret = 1;
    return ret;
}



//升级数据 处理
uint8_t OTALOGIC_UPDATE(int offset, int len, char* data)
{
    /*base64 输出buffer大小和长度*/
	char outtbuff[256] = {0};
    int outlen = 0;

    gOTALogic.Status = OTA_DOWLOAD;

    int writeLen = 0;           //当前写入区长度 下标
    int thisTimeWriteLen = 0;   //此次处理数据的 总长度
    uint8_t ret = 0;
    int i = 0;
    int j = 0;

    u32 writeBuf[128] = {0};
    u32 t_wbuf = 0;

    //如果下发长度地址 小于当前的已处理地址
    if(offset + len <= gOTALogic.Current_WriteOfset)
    {
        printf("当前数据包已处理,不做处理\r\n");
        return 0;
    }

    base64_decode(data, outtbuff, &outlen);
    printf("1.ota decode Len: [%d]\r\n", outlen);

#if IS_DEBUG_OTA_UPDATE
    for(i= 0; i<outlen ;i++)
    {
        printf("%02x ",outtbuff[i]);
        if((i+1) %16 ==0 )
            printf("\r\n");
    }
    printf("\r\n");
#endif

    /*计算当前当前OTA包的CRC*/
    for(i= 0; i < outlen ;i++)
    {
        //printf("%02x ",outtbuff[i]);
        gOTALogic.OtaTcpRecvCrc += outtbuff[i];
        // if((i+1) %16 ==0 )
        //     printf("\r\n");
    }

    /*拷贝上次剩余的缓存到写入区 */
    if(gOTALogic.LastRemaidLen > 0)
    {
        for(i = 0; i < gOTALogic.LastRemaidLen; i++)
        {
            /*STEP 1*/
            gOTALogic.WritePageBuffer[writeLen] =  gOTALogic.LastRemaidBuffer[i];
            writeLen ++;        
        }

        //清除上次保存缓存区
        gOTALogic.LastRemaidLen = 0;
        memset(gOTALogic.LastRemaidBuffer, 0, OTA_WRITE_PAGE_SIZE);
    }

    /*当前缓存数据 >= 512 个字节长度数据*/
    for(i = 0; i < outlen; i++)
    {
        if(writeLen == OTA_WRITE_PAGE_SIZE)
        {
            for(j = 0; j <128; j++)
            {
                t_wbuf = BUILD_UINT32(gOTALogic.WritePageBuffer[4*j], gOTALogic.WritePageBuffer[4*j +1], gOTALogic.WritePageBuffer[4*j +2], gOTALogic.WritePageBuffer[4*j +3]);
               
                writeBuf[j] = t_wbuf;
            }

#if IS_DEBUG_OTA_UPDATE
            printf("t buf >>>>>\r\n");
            for(j = 0; j <128; j++)
            {
                //t_wbuf = BUILD_UINT32(gOTALogic.WritePageBuffer[4*j], gOTALogic.WritePageBuffer[4*j +1], gOTALogic.WritePageBuffer[4*j +2], gOTALogic.WritePageBuffer[4*j +3]);
               
              
                printf("[%2x]\r\n", writeBuf[j]);
                if((j+1) %16 == 0)
                    printf("\r\n");
            }
#endif

            STMFLASH_WriteWord(gOTALogic.OTAPackSaveAddr + (512) *(gOTALogic.WritePageIndex), writeBuf, OTA_WRITE_PAGE_SIZE/4);
           
            gOTALogic.WritePageIndex++;
            printf("1.#Write[%d] Pack Data To flash!#\r\n", gOTALogic.WritePageIndex);

            //如果写入,则清除写入区的缓存
            writeLen = 0;
            memset(gOTALogic.WritePageBuffer, 0, OTA_WRITE_PAGE_SIZE);
        }
      
        /*STEP 2*/
        gOTALogic.WritePageBuffer[writeLen] =  outtbuff[i]; //拷贝缓存区到 写入区
        writeLen ++;

        gOTALogic.Current_WriteOfset ++;  //接收缓存数据总长度
        thisTimeWriteLen ++;
    }
   

    //保存剩余未写入区域
    gOTALogic.LastRemaidLen = writeLen; //记录此次的剩余的长度
    memcpy(gOTALogic.LastRemaidBuffer, gOTALogic.WritePageBuffer, writeLen);

    printf("1.Recv [%d] bytes. from clound. Write [%d]Page. size:[%d]bytes. Remind [%d] bytes not Write.", \
             gOTALogic.Current_WriteOfset, gOTALogic.WritePageIndex, gOTALogic.WritePageIndex * 512, gOTALogic.LastRemaidLen);

    ret = 1;
    return ret;
}




/*升级包校验*/
uint8_t OtaLogic_Check(void)
{
    uint8_t ret =0;
    int writeLen = 0;
    int i =0;
    uint8_t ReadBuf [512] = {0};
    int j = 0;

    u32 writeBuf[128] = {0};
    u32 t_wbuf = 0;

    int readTimers = 0;
    int readOffset = 0;

    gOTALogic.Status = OTA_CHECK;

    u32 isHaveOTApack_para1 = 0;
    //u32 currentRunAPPAddr_para2 = 0;
    u32 LastcurrentRunAPPAddr_para2 = 0;
    u32 currentOtaPackAddr_para3 = 0;

    //处理最后剩余的OTA数据长度
    if(gOTALogic.LastRemaidLen > 0)
    {
        printf("1.Write Last Pack Len to Flash:[%d]\r\n", gOTALogic.LastRemaidLen);
        for(i = 0; i < gOTALogic.LastRemaidLen; i++)
        {
            gOTALogic.WritePageBuffer[writeLen] =  gOTALogic.LastRemaidBuffer[i];
            //gOTALogic.Current_WriteOfset ++;
            writeLen ++;
        }

        //清除上次保存缓存区
 
        for(j = 0; j <128; j++)
        {
            t_wbuf = BUILD_UINT32(gOTALogic.WritePageBuffer[4*j], gOTALogic.WritePageBuffer[4*j +1], gOTALogic.WritePageBuffer[4*j +2], gOTALogic.WritePageBuffer[4*j +3]);
          
            
            writeBuf[j] = t_wbuf;
         
        }  

#if IS_DEBUG_OTA_UPDATE
     printf("write last >>>>>\r\n");
    for(j = 0; j < 128; j++)
        {
            printf("%08x ", writeBuf[j] );
            if((j+1) %16 == 0)
                printf("\r\n");
        }  
#endif
        
          
      
        STMFLASH_WriteWord(gOTALogic.OTAPackSaveAddr + (512) *(gOTALogic.WritePageIndex), writeBuf, gOTALogic.LastRemaidLen/4);

        memset(gOTALogic.WritePageBuffer, 0, OTA_WRITE_PAGE_SIZE);
    }

    /*计算Flash CRC*/
    readTimers = gDeviceInfo.LastCaculatOTAPack/512;
    readOffset = gDeviceInfo.LastCaculatOTAPack % 512;
  
    printf("2.CaCulate [%d] Pack Crc From Flash...\r\n", readTimers);
    //读取并计算 写入数据 包的长度CRC
    for(j = 0; j< readTimers; j++) {
       
		FLASH_ReadByte(gOTALogic.OTAPackSaveAddr +j*512, ReadBuf, 512);
        for(i = 0; i < 512; i++) {
            
            gOTALogic.OtaTcpFlashReadCrc += ReadBuf[i];
   
        }
        
	}

#if IS_DEBUG_OTA_UPDATE
     for(j = 0; j< readTimers; j++) {
        //if(j<3)
        printf("pack [%d] check\r\n", j);
		FLASH_ReadByte(gOTALogic.OTAPackSaveAddr +j*512, ReadBuf, 512);
        for(i = 0; i < 512; i++) {
            
            //gOTALogic.OtaTcpFlashReadCrc += ReadBuf[i];

            printf("%02x ", ReadBuf[i]);
            if((i+1)%16 ==0)
                printf("\r\n");     
        }
        printf("\r\n");
	} 
#endif

    printf("2.CaCulate [%d] Len Crc From Last Pack ...\r\n", readOffset);
    //读取并计算 写入最后一包的长度CRC
    FLASH_ReadByte(gOTALogic.OTAPackSaveAddr +j*512, ReadBuf, readOffset);
    for(i = 0; i < readOffset; i++) {
      
        gOTALogic.OtaTcpFlashReadCrc += ReadBuf[i];

     
    }

#if IS_DEBUG_OTA_UPDATE
    FLASH_ReadByte(gOTALogic.OTAPackSaveAddr +j*512, ReadBuf, readOffset);
    for(i = 0; i < readOffset; i++) {
        printf("%02x ", ReadBuf[i]);
      

         if((i+1)%16 ==0)
             printf("\r\n");
    }
#endif

    /*计算平台下发接收的crc和 读取保存之后的CRC数据*/
    printf("2.Recv from Clound:[0x%x].\r\n", gOTALogic.OtaTcpRecvCrc); 
    printf("2.Flash Read Crc :[0x%x] VS ", gOTALogic.OtaTcpFlashReadCrc);
    
    /*计算平台协议包里面的总长度*/
    printf("2.Caculate Sum Len from Clound: [%d].\r\n", gDeviceInfo.LastCaculatOTAPack);
    
    /*设备接收的数据总长度*/
    printf("2.Sum Recv [%d] Len From Clound.\r\n", gOTALogic.Current_WriteOfset);

    /*写入flash的数据总长度*/
    printf("2.Have Write [%d] bytes To Flash...\r\n", gOTALogic.LastRemaidLen + gOTALogic.WritePageIndex*512);

    
    gOTALogic.LastRemaidLen = 0;
    memset(gOTALogic.LastRemaidBuffer, 0, OTA_WRITE_PAGE_SIZE);

    gOTALogic.WritePageIndex = 0;
    gOTALogic.Current_WriteOfset = 0;
    gOTALogic.LastRemaidLen = 0;
   
    //校验 CRC //和检验
    if(gOTALogic.OtaTcpFlashReadCrc == gOTALogic.OtaTcpRecvCrc)
    {
        ret = 1;
        gOTALogic.Status = OTA_SUCCESSED;
        printf("3.恭喜你.软件升级成功!\r\n");

#if 1
        printf("3.开始写入bootloader参数...\r\n");
        //printf("------- ota param read-------------\r\n");
        STMFLASH_ReadWord(OTA_PARM_1_ADDR, &isHaveOTApack_para1, 1);
        //printf("读取是否有升级包标识 = [%08x]\r\n", isHaveOTApack_para1);
        HAL_Delay(10);
        STMFLASH_ReadWord(OTA_PARM_2_ADDR, &LastcurrentRunAPPAddr_para2, 1);
        //printf("读取当前运行包地址 = [%08x]\r\n", LastcurrentRunAPPAddr_para2);

        /*此处神秘代码.防止写不进去,多写几次--- 擦除OTA参数地址*/
        OtaWriteReadOtaParamFlag(); /*读-擦-写*/
        OtaWriteReadOtaParamFlag(); /*读-擦-写*/
        OtaWriteReadOtaParamFlag(); /*读-擦-写*/
        OtaWriteReadOtaParamFlag(); /*读-擦-写*/

       if (OTA_PACK_USER_VERSION == 0){  //当前是APP版本 /*读-擦-写*/
            printf("3.当前是APP版本\r\n");
            isHaveOTApack_para1 = 0x01;  //写入OTA升级包标识
            STMFLASH_WriteWord(OTA_PARM_1_ADDR, &isHaveOTApack_para1, 1);
            printf("3.写入OTA参数1 [%d]\r\n", isHaveOTApack_para1);
            HAL_Delay(50);
            printf("------- ota param write para3 -----------\r\n");
            currentOtaPackAddr_para3 = OTA_DOWN_ADDR; //写入OTA升级地址
            printf("3.写入OTA参数3 [0x%08x]\r\n", currentOtaPackAddr_para3);
            STMFLASH_WriteWord(OTA_PARM_3_ADDR, &currentOtaPackAddr_para3, 1);
            HAL_Delay(50);				
		} else {
            printf("3.当前是 OTA 版本\r\n");
            isHaveOTApack_para1 = 0x02;  //写入OTA升级包标识
            STMFLASH_WriteWord(OTA_PARM_1_ADDR, &isHaveOTApack_para1, 1);
            printf("3.写入OTA参数1 [%d]\r\n", isHaveOTApack_para1);
            HAL_Delay(50);
            printf("------- ota param write para3 -----------\r\n");
            currentOtaPackAddr_para3 = APP1_RUN_ADDR; 
            printf("3.写入OTA参数3 [0x%08x]\r\n", currentOtaPackAddr_para3);
            STMFLASH_WriteWord(OTA_PARM_3_ADDR, &currentOtaPackAddr_para3, 1);
            HAL_Delay(50);			
		}


        printf("------- 3.参数检查读写  -------------\r\n");
        STMFLASH_ReadWord(OTA_PARM_1_ADDR, &isHaveOTApack_para1, 1);
        printf("3.读取是否有升级包 标识ota参数1 = [%08x]\r\n", isHaveOTApack_para1);

        HAL_Delay(10);
        STMFLASH_ReadWord(OTA_PARM_3_ADDR, &currentOtaPackAddr_para3, 1);
        printf("3.读取当前运行包地址 ota参数3 = [%08x]\r\n", currentOtaPackAddr_para3);


#endif
        printf("3.写入成功...重启设备\r\n");

        //软件重启
        HAL_Delay(100);
        __HAL_RCC_PWR_CLK_DISABLE();
        HAL_RCC_DeInit();
        __set_FAULTMASK(1);	//关闭所有中断
        __disable_irq();
        NVIC_SystemReset();	//软件复位

    } else {
        ret = 0;
        STMFLASH_EraseSector(OTA_PARM_SECRTOR, 1);
        gOTALogic.Status = OTA_FAILED;
        printf("CRC校验失败. 软件升级失败!\r\n");
    }

    gOTALogic.OtaTcpFlashReadCrc = 0;
    gOTALogic.OtaTcpRecvCrc = 0;
    return ret;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值