1149 lines
42 KiB
C
1149 lines
42 KiB
C
/******************************************************************************
|
||
* Copyright (c) 20203, Freqchip
|
||
*
|
||
* All rights reserved.
|
||
*
|
||
*
|
||
*/
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
//#include <core_cm33.h>
|
||
|
||
#include "fr30xx.h"
|
||
#include "co_util.h"
|
||
#include "gap_api.h"
|
||
#include "gatt_api.h"
|
||
#include "FreeRTOS.h"
|
||
#include "timers.h"
|
||
|
||
#include "app_ota.h"
|
||
#include "app_ota_service.h"
|
||
|
||
|
||
/******************************************************************************
|
||
* MACROS (宏定义)
|
||
*/
|
||
|
||
/*****************************************************************************
|
||
* CONSTANTS (常量定义)
|
||
*/
|
||
#define PMU_REG_FLASH_VDD_CTRL 0xFB
|
||
#define IMAGE_INFO_OTA_MAGIC (0x51525251)
|
||
/*****************************************************************************
|
||
* TYPEDEFS (类型定义)
|
||
*/
|
||
__PACKED_STRUCT ota_ongoing_t{
|
||
uint8_t type;
|
||
uint8_t start_flag;
|
||
uint8_t erase_flag;
|
||
uint8_t mac_addr[6];
|
||
};
|
||
__PACKED_STRUCT ota_file_version_t{
|
||
uint32_t otaboot_version;
|
||
uint32_t app_version;
|
||
uint32_t controller_version;
|
||
uint32_t dsp_version;
|
||
};
|
||
__PACKED_STRUCT file_info_t{
|
||
uint32_t file_version;
|
||
uint32_t file_storage_base;
|
||
uint32_t file_length;
|
||
uint32_t file_crc;
|
||
};
|
||
__PACKED_STRUCT ota_info_t{
|
||
uint8_t first_check_flag[4];
|
||
uint8_t file_type; //烧录文件中,所包含的文件类型
|
||
struct file_info_t boot_file_info;
|
||
struct file_info_t app_file_info;
|
||
struct file_info_t controller_file_info;
|
||
struct file_info_t dsp_file_info;
|
||
uint8_t controller_flag;
|
||
struct ota_ongoing_t ota_ongoing;
|
||
uint32_t rsv[10];
|
||
};
|
||
|
||
__PACKED_STRUCT firmware_version
|
||
{
|
||
uint32_t firmware_version;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT storage_baseaddr
|
||
{
|
||
uint32_t baseaddr;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT page_erase_rsp
|
||
{
|
||
uint32_t base_address;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT write_mem_rsp
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT read_mem_rsp
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT write_data_rsp
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT read_data_rsp
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT ota_start_rsp
|
||
{
|
||
uint32_t ota_start;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT ota_finish_rsp
|
||
{
|
||
uint32_t ota_finsih_state;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT app_ota_rsp_hdr_t
|
||
{
|
||
uint8_t result;
|
||
uint8_t org_opcode;
|
||
uint16_t length;
|
||
__PACKED union
|
||
{
|
||
uint8_t nvds_type;
|
||
struct firmware_version version;
|
||
struct storage_baseaddr baseaddr;
|
||
struct page_erase_rsp page_erase;
|
||
struct write_mem_rsp write_mem;
|
||
struct read_mem_rsp read_mem;
|
||
struct write_data_rsp write_data;
|
||
struct read_data_rsp read_data;
|
||
struct ota_finish_rsp finsih_rsp;
|
||
struct ota_start_rsp ota_start;
|
||
} __attribute__((packed)) rsp;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT page_erase_cmd
|
||
{
|
||
uint32_t base_address;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT write_mem_cmd
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT read_mem_cmd
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT write_data_cmd
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT read_data_cmd
|
||
{
|
||
uint32_t base_address;
|
||
uint16_t length;
|
||
} __attribute__((packed));
|
||
|
||
__PACKED_STRUCT firmware_check
|
||
{
|
||
uint32_t firmware_length;
|
||
uint32_t CRC32_data;
|
||
} __attribute__((packed));
|
||
__PACKED_STRUCT app_ota_cmd_hdr_t
|
||
{
|
||
uint8_t opcode;
|
||
uint16_t length;
|
||
__PACKED union
|
||
{
|
||
struct page_erase_cmd page_erase;
|
||
struct write_mem_cmd write_mem;
|
||
struct read_mem_cmd read_mem;
|
||
struct write_data_cmd write_data;
|
||
struct read_data_cmd read_data;
|
||
struct firmware_check fir_crc_data;
|
||
} __attribute__((packed)) cmd;
|
||
} __attribute__((packed));
|
||
|
||
struct image_info_t
|
||
{
|
||
uint32_t image_version;
|
||
uint32_t image_offset; // storage offset
|
||
uint32_t image_length;
|
||
uint32_t execute_offset; // execute offset
|
||
uint32_t copy_unit; // 4K, 8K, 16K, 32K, 64K, 128K
|
||
uint32_t copy_flag_store_step; // 4, 8, 16, 32, 64
|
||
uint32_t image_crc;
|
||
uint32_t image_valid;
|
||
uint32_t image_tlv_length; // Hash,signa length
|
||
uint32_t options;
|
||
uint32_t info_crc;
|
||
uint32_t ota_magic; // 需要更新标志
|
||
};
|
||
|
||
__PACKED_STRUCT otas_send_rsp
|
||
{
|
||
uint8_t conidx;
|
||
uint16_t length;
|
||
uint8_t *buffer;
|
||
};
|
||
__PACKED_STRUCT source_file_info_t{
|
||
uint8_t check_buff[4];
|
||
uint32_t version;
|
||
uint32_t length;
|
||
uint32_t crc;
|
||
};
|
||
typedef unsigned int uLong;
|
||
typedef unsigned int uInt;
|
||
typedef uLong uLongf;
|
||
typedef unsigned char Byte;
|
||
typedef Byte Bytef;
|
||
#define ZEXPORT
|
||
#define OF(a) a
|
||
#define Z_NULL 0
|
||
|
||
#define local static
|
||
|
||
#define IMAGE_INFO_CRC_ZONE_LEN ((uint32_t)(&((struct image_info_t *)0)->info_crc))
|
||
|
||
/******************************************************************************
|
||
* LOCAL VARIABLES (局部变量)
|
||
*/
|
||
static uint8_t first_loop;
|
||
const uint8_t ota_check_data[4] = {0x43,0x75,0x28,0x19};
|
||
const uint8_t app_check_data[4] = {0x55,0xAA,0x55,0xAA};
|
||
const uint8_t controller_check_data[4] = {0x55,0xAA,0xAA,0x55};
|
||
const uint8_t dsp_check_data[4] = {0xAA,0x55,0x55,0xAA};
|
||
static void app_boot_retarget(uint32_t target);
|
||
static uint32_t ota_imagesize = 0;
|
||
static TimerHandle_t xTimer_OtaTimerOut = NULL;
|
||
static uint16_t at_data_idx;
|
||
static uint32_t firmware_vesion_new = 0;
|
||
static uint32_t firmware_size_new = 0;
|
||
static uint32_t ota_ongoing_base = 0;
|
||
static uint32_t ota_ongoing_max_code_size = 0;
|
||
static uint8_t file_type = 0;
|
||
uint32_t Crc32CalByByte(int crc,uint8_t* ptr, int len);
|
||
/******************************************************************************
|
||
* GLOBAL VARIABLES (全局变量)
|
||
*/
|
||
struct app_otas_status_t app_otas_status;
|
||
struct ota_info_t * ota_info;
|
||
extern adv_handle ota_adv;
|
||
extern uint8_t ble_static_addr[6];
|
||
/******************************************************************************
|
||
* LOCAL FUNCTIONS (本地函数)
|
||
*/
|
||
__RAM_CODE static uint8_t app_otas_crc_cal(uint32_t firmware_length,uint32_t new_bin_addr,uint32_t crc_data_t);
|
||
uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len);
|
||
uint32_t get_boot_crc(uint32_t imagesize,uint32_t length);
|
||
/******************************************************************************
|
||
* EXTERN FUNCTIONS (外部函数)
|
||
*/
|
||
extern void wdt_rst_start(void);
|
||
extern void user_controller_init(void);
|
||
/*********************************************************************
|
||
* @fn check_file_integrity
|
||
*
|
||
* @brief check file intergrity when ota start,
|
||
* if file not intergrity,adv always on.
|
||
* else close ota
|
||
*/
|
||
void check_file_integrity(void)
|
||
{
|
||
if(ota_info->ota_ongoing.erase_flag)
|
||
{
|
||
adv_timeout_TimerStop();
|
||
}else{
|
||
/*ota disable*/
|
||
ota_info->ota_ongoing.start_flag = 0;
|
||
flash_write(QSPI0,BOOT_B_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)ota_info);
|
||
wdt_rst_start();
|
||
}
|
||
}
|
||
|
||
void show_reg(uint8_t *buffer,uint16_t length)
|
||
{
|
||
for(int i = 0; i < length; i++)
|
||
{
|
||
printf("%02x ",buffer[i]);
|
||
}
|
||
printf("\r\n");
|
||
}
|
||
|
||
void print_info(struct source_file_info_t * info)
|
||
{
|
||
printf("\ncheck:%02x,%02x,%02x,%02x",info->check_buff[0],info->check_buff[1],
|
||
info->check_buff[2],info->check_buff[3]);
|
||
printf("\nversion:%08x",info->version);
|
||
printf("\nlength:%08x",info->length);
|
||
printf("\ncrc:%08x\r\n",info->crc);
|
||
}
|
||
/*********************************************************************
|
||
* @fn get_ota_info
|
||
*
|
||
* @brief 第一次上电的时候,获取文件有效信息
|
||
*/
|
||
bool get_ota_info(void)
|
||
{
|
||
struct ota_info_t get_ota_info;
|
||
flash_read(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)&get_ota_info);
|
||
/*检查是不是第一次上电,第一次上电,从文件中读取文件信息*/
|
||
if(memcmp(get_ota_info.first_check_flag,ota_check_data,4) != 0)
|
||
{
|
||
struct source_file_info_t src_info;
|
||
struct image_info_t image_info;
|
||
|
||
/*获取boot有效信息,版本号,存储地址,程序长度,crc*/
|
||
flash_read(QSPI0,BOOT_A_INFO_ADDRESS,sizeof(struct image_info_t),(uint8_t *)&image_info);
|
||
get_ota_info.boot_file_info.file_version = image_info.image_version;
|
||
get_ota_info.boot_file_info.file_storage_base = OTA_B_STORAGE_ADDRESS;
|
||
get_ota_info.boot_file_info.file_length = image_info.image_length;
|
||
get_ota_info.boot_file_info.file_crc = image_info.image_crc;
|
||
get_ota_info.file_type = 0;
|
||
|
||
/*获取app有效信息,版本号,存储地址,程序长度,crc*/
|
||
flash_read(QSPI0,APP_CODE_STORAGE_ADDRESS+APP_CODE_INFO_OFFSET,sizeof(struct source_file_info_t),(uint8_t *)&src_info);
|
||
print_info(&src_info);
|
||
if(memcmp(src_info.check_buff,app_check_data,4) == 0)
|
||
{
|
||
uint32_t app_code_crc;
|
||
get_ota_info.app_file_info.file_version = src_info.version;
|
||
get_ota_info.app_file_info.file_storage_base = APP_CODE_STORAGE_ADDRESS;
|
||
get_ota_info.app_file_info.file_length = src_info.length;
|
||
flash_read(QSPI0,APP_CODE_STORAGE_ADDRESS+src_info.length,4,(uint8_t *)&app_code_crc);
|
||
get_ota_info.app_file_info.file_crc = app_code_crc;
|
||
get_ota_info.file_type |= FILE_TYPE_APP;
|
||
printf("app crc:%x\r\n",get_ota_info.app_file_info.file_crc);
|
||
}else{
|
||
return false;
|
||
}
|
||
/*
|
||
1、检测controller地址是否controller有效信息,有设置controller flag为1,表示会在应用层初始化controller
|
||
否则,boot里面初始化controller
|
||
2、获取controller有效信息,版本号,存储地址,程序长度,crc
|
||
*/
|
||
flash_read(QSPI0,CONTROLLER_STORAGE_ADDRESS,sizeof(struct source_file_info_t),(uint8_t *)&src_info);
|
||
printf("controller:%x\r\n",CONTROLLER_STORAGE_ADDRESS);
|
||
print_info(&src_info);
|
||
// if(memcmp(src_info.check_buff,controller_check_data,4) == 0 )
|
||
{
|
||
get_ota_info.controller_flag = 1;
|
||
get_ota_info.controller_file_info.file_version = src_info.version;
|
||
get_ota_info.controller_file_info.file_storage_base = CONTROLLER_STORAGE_ADDRESS;
|
||
get_ota_info.controller_file_info.file_crc = src_info.crc;
|
||
get_ota_info.controller_file_info.file_length = src_info.length;
|
||
get_ota_info.file_type |= FILE_CONTROLLER;
|
||
}
|
||
// else{
|
||
// get_ota_info.controller_flag = 0;
|
||
// }
|
||
|
||
|
||
/*获取DSP有效信息,版本号,存储地址,程序长度,crc*/
|
||
flash_read(QSPI0,DSP_STORAGE_ADDRESS,sizeof(struct source_file_info_t),(uint8_t *)&src_info);
|
||
printf("dsp:%x\r\n",DSP_STORAGE_ADDRESS);
|
||
print_info(&src_info);
|
||
// if(memcmp(src_info.check_buff,dsp_check_data,4) == 0)
|
||
{
|
||
get_ota_info.dsp_file_info.file_version = src_info.version;
|
||
get_ota_info.dsp_file_info.file_storage_base = DSP_STORAGE_ADDRESS;
|
||
get_ota_info.dsp_file_info.file_crc = src_info.crc;
|
||
get_ota_info.dsp_file_info.file_length = src_info.length;
|
||
get_ota_info.file_type |= FILE_TYPE_DSP;
|
||
}
|
||
|
||
/*初始化ota 升级时的状态信息*/
|
||
get_ota_info.ota_ongoing.start_flag = 0;
|
||
get_ota_info.ota_ongoing.erase_flag = 0;
|
||
|
||
memcpy(get_ota_info.first_check_flag,ota_check_data,4);
|
||
flash_erase(QSPI0,OTA_BOOT_INFO_ADDRESS,0x1000);
|
||
flash_write(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)&get_ota_info);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn Document_validity_check
|
||
*
|
||
* @brief 校验APP,DSP,CONTROLLER程序
|
||
*/
|
||
bool Document_validity_check(void)
|
||
{
|
||
#if DOCUMENT_CHECK
|
||
struct ota_info_t get_ota_info;
|
||
bool status = true;
|
||
flash_read(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)&get_ota_info);
|
||
printf("validity type:%02x\r\n",get_ota_info.file_type);
|
||
do
|
||
{
|
||
/*对app文件进行校验*/
|
||
if(get_ota_info.file_type & FILE_TYPE_APP)
|
||
{
|
||
printf("address:%x,length:%x\r\n",get_ota_info.app_file_info.file_storage_base,get_ota_info.app_file_info.file_length);
|
||
if(get_boot_crc(get_ota_info.app_file_info.file_storage_base,get_ota_info.app_file_info.file_length) == get_ota_info.app_file_info.file_crc)
|
||
{
|
||
status = true;
|
||
}else{
|
||
status = false;
|
||
break;
|
||
}
|
||
}else{
|
||
status = false;
|
||
break;
|
||
}
|
||
#if 0
|
||
/*对control文件进行校验*/
|
||
if(get_ota_info.file_type & FILE_TYPE_CONTROLLER)
|
||
{
|
||
printf("address:%x,length:%x\r\n",get_ota_info.controller_file_info.file_storage_base,get_ota_info.controller_file_info.file_length);
|
||
if(get_boot_crc(get_ota_info.controller_file_info.file_storage_base+FILE_CODE_ADDRESS_OFFSET,get_ota_info.controller_file_info.file_length) == get_ota_info.controller_file_info.file_crc)
|
||
{
|
||
status = true;
|
||
}else{
|
||
status = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*对dsp文件进行校验*/
|
||
if(get_ota_info.file_type & FILE_TYPE_DSP)
|
||
{
|
||
printf("address:%x,length:%x\r\n",get_ota_info.dsp_file_info.file_storage_base,get_ota_info.dsp_file_info.file_length);
|
||
if(get_boot_crc(get_ota_info.dsp_file_info.file_storage_base+FILE_CODE_ADDRESS_OFFSET,get_ota_info.dsp_file_info.file_length) == get_ota_info.dsp_file_info.file_crc)
|
||
{
|
||
status = true;
|
||
}else{
|
||
status = false;
|
||
break;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
}while(0);
|
||
#else
|
||
bool status = true;
|
||
#endif
|
||
return status;
|
||
}
|
||
/*********************************************************************
|
||
* @fn ota_boot_start
|
||
*
|
||
*/
|
||
void ota_boot_start(void)
|
||
{
|
||
if(get_ota_info() == true)
|
||
{
|
||
struct ota_info_t get_ota_info;
|
||
flash_read(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)&get_ota_info);
|
||
/*判断需不需要ota 升级*/
|
||
if(get_ota_info.ota_ongoing.start_flag != 0x01)
|
||
{
|
||
/*对文件有效性进行检查,如果没有文件则进入默认boot程序*/
|
||
if((Document_validity_check() == true))
|
||
{
|
||
/*判断应用层初始化controller还是boot初始化controller*/
|
||
if(get_ota_info.controller_flag == 0x01 )
|
||
{
|
||
printf("controller code\r\n");
|
||
co_delay_100us(100);
|
||
/*jump new address*/
|
||
app_boot_retarget(RETARGET_APP_CODE_ADDRESS);
|
||
while(1);
|
||
|
||
}else{
|
||
printf("no controller code\r\n");
|
||
/*control init*/
|
||
user_controller_init();
|
||
|
||
/*jump new address*/
|
||
app_boot_retarget(RETARGET_APP_CODE_ADDRESS);
|
||
while(1);
|
||
}
|
||
}else{
|
||
ota_info = pvPortMalloc(sizeof(struct ota_info_t));
|
||
flash_read(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)ota_info);
|
||
}
|
||
}else{
|
||
/*进入ota程序,获取ota 信息,并且设置ota升级地址*/
|
||
ota_info = pvPortMalloc(sizeof(struct ota_info_t));
|
||
flash_read(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)ota_info);
|
||
memcpy(ble_static_addr,ota_info->ota_ongoing.mac_addr,6);
|
||
}
|
||
}else{
|
||
ota_info = pvPortMalloc(sizeof(struct ota_info_t));
|
||
flash_read(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)ota_info);
|
||
memset(ota_info->first_check_flag,0,4);
|
||
ota_info->app_file_info.file_version = 0;
|
||
ota_info->boot_file_info.file_version = 0;
|
||
ota_info->controller_file_info.file_version = 0;
|
||
ota_info->dsp_file_info.file_version = 0;
|
||
ota_info->app_file_info.file_storage_base = APP_CODE_STORAGE_ADDRESS;
|
||
ota_info->boot_file_info.file_storage_base = OTA_B_STORAGE_ADDRESS;
|
||
ota_info->controller_file_info.file_storage_base = CONTROLLER_STORAGE_ADDRESS;
|
||
ota_info->dsp_file_info.file_storage_base = DSP_STORAGE_ADDRESS;
|
||
ota_info->ota_ongoing.start_flag = 1;
|
||
ota_info->ota_ongoing.erase_flag = 1;
|
||
ota_info->file_type = 0;
|
||
}
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn ota_init
|
||
*
|
||
* @brief Initialization ota
|
||
*/
|
||
void ota_init(void)
|
||
{
|
||
app_otas_status.read_opcode = OTA_CMD_NULL;
|
||
first_loop = true;
|
||
at_data_idx = 0;
|
||
}
|
||
/*********************************************************************
|
||
* @fn ota_deinit
|
||
*
|
||
* @brief reset chip,when ota abnormal disconnection
|
||
*/
|
||
void ota_deinit(void)
|
||
{
|
||
wdt_rst_start();
|
||
}
|
||
/*********************************************************************
|
||
* @fn platform_reset
|
||
*
|
||
* @brief reset chip
|
||
*/
|
||
void platform_reset(void)
|
||
{
|
||
// Disable interrupts
|
||
__disable_irq();
|
||
|
||
ool_write(PMU_REG_FLASH_VDD_CTRL, ool_read(PMU_REG_FLASH_VDD_CTRL) & 0xFE);
|
||
co_delay_100us(300);
|
||
|
||
NVIC_SystemReset();
|
||
}
|
||
/*********************************************************************
|
||
* @fn ota_set_imagesize
|
||
*
|
||
* @brief set ota file size
|
||
*/
|
||
void ota_set_imagesize(uint32_t imagesize)
|
||
{
|
||
ota_imagesize = imagesize;
|
||
}
|
||
/*********************************************************************
|
||
* @fn ota_set_imagesize
|
||
*
|
||
* @brief get ota file size
|
||
*/
|
||
uint32_t ota_get_imagesize(void)
|
||
{
|
||
return ota_imagesize;
|
||
}
|
||
/*********************************************************************
|
||
* @fn app_boot_retarget
|
||
*
|
||
* @brief 重映射中断向量表,MSP指针,代码跳转RAM执行
|
||
*/
|
||
__RAM_CODE static void app_boot_retarget(uint32_t target)
|
||
{
|
||
static str_CoreRemapStart_t *CoreRemapStart;
|
||
|
||
CoreRemapStart = (str_CoreRemapStart_t *)target;
|
||
|
||
/* Disable SysTick */
|
||
SysTick->CTRL = 0;
|
||
/* Modify intrerrupt vector table */
|
||
SCB->VTOR = target;
|
||
|
||
__set_MSP((volatile uint32_t)CoreRemapStart->MSP);
|
||
((void (*)(void))(CoreRemapStart->Reset_Handler | 0x01))();
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn app_otas_read_data
|
||
*
|
||
* @brief Read Data
|
||
*
|
||
* @param Read Data Buffer.
|
||
*
|
||
*
|
||
* @return Read Data Length.
|
||
*/
|
||
uint16_t app_otas_read_data(uint8_t *p_data)
|
||
{
|
||
uint16_t length;
|
||
switch(app_otas_status.read_opcode)
|
||
{
|
||
case OTA_CMD_READ_DATA:
|
||
|
||
length = app_otas_status.length;
|
||
break;
|
||
case OTA_CMD_READ_MEM:
|
||
|
||
length = app_otas_status.length;
|
||
break;
|
||
default:
|
||
length = 0;
|
||
break;
|
||
}
|
||
app_otas_status.read_opcode = OTA_CMD_NULL;
|
||
return length;
|
||
}
|
||
/*********************************************************************
|
||
* @fn ota_start_cb
|
||
*
|
||
* @brief stop start,reset chip
|
||
*
|
||
*/
|
||
void ota_start_callback(TimerHandle_t pxTimer)
|
||
{
|
||
xTimerStop(xTimer_OtaTimerOut,0);
|
||
ota_deinit();
|
||
}
|
||
/*********************************************************************
|
||
* @fn ota_start
|
||
*
|
||
* @brief ota timeout enable
|
||
*
|
||
*/
|
||
void ota_start(void)
|
||
{
|
||
if(xTimer_OtaTimerOut == NULL)
|
||
{
|
||
xTimer_OtaTimerOut = xTimerCreate("ota",OTA_START_TIMOUT/portTICK_PERIOD_MS,pdFALSE,NULL,ota_start_callback);
|
||
xTimerStart(xTimer_OtaTimerOut,0);
|
||
}else{
|
||
xTimerStop(xTimer_OtaTimerOut,0);
|
||
xTimerStart(xTimer_OtaTimerOut,0);
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* @fn ota_stop
|
||
*
|
||
* @brief close ota stop
|
||
*
|
||
*/
|
||
void ota_stop(void)
|
||
{
|
||
xTimerStop(xTimer_OtaTimerOut,0);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn app_otas_recv_data
|
||
*
|
||
* @brief Otas Data handler
|
||
*
|
||
*/
|
||
void app_otas_recv_data(uint8_t conidx,uint8_t *p_data,uint16_t len)
|
||
{
|
||
struct app_ota_cmd_hdr_t *cmd_hdr = (struct app_ota_cmd_hdr_t *)p_data;
|
||
struct app_ota_rsp_hdr_t *rsp_hdr;
|
||
uint16_t rsp_data_len = (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN+OTA_HDR_RESULT_LEN);
|
||
if(first_loop)
|
||
{
|
||
/*close adv time out*/
|
||
adv_timeout_TimerStop();
|
||
first_loop = false;
|
||
}
|
||
ota_start();
|
||
at_data_idx++;
|
||
switch(cmd_hdr->opcode)
|
||
{
|
||
case OTA_CMD_NVDS_TYPE:
|
||
rsp_data_len += 1;
|
||
break;
|
||
case OTA_CMD_GET_STR_BASE:
|
||
at_data_idx = 0;
|
||
rsp_data_len += sizeof(struct storage_baseaddr);
|
||
break;
|
||
case OTA_CMD_READ_FW_VER:
|
||
rsp_data_len += sizeof(struct firmware_version);
|
||
break;
|
||
case OTA_CMD_PAGE_ERASE:
|
||
rsp_data_len += sizeof(struct page_erase_rsp);
|
||
break;
|
||
case OTA_CMD_WRITE_DATA:
|
||
rsp_data_len += sizeof(struct write_data_rsp);
|
||
break;
|
||
case OTA_CMD_READ_DATA:
|
||
rsp_data_len += sizeof(struct read_data_rsp) + cmd_hdr->cmd.read_data.length;
|
||
if(rsp_data_len > OTAS_NOTIFY_DATA_SIZE)
|
||
{
|
||
rsp_data_len = sizeof(struct read_data_rsp) + (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN+OTA_HDR_RESULT_LEN);
|
||
app_otas_status.read_opcode = OTA_CMD_READ_DATA;
|
||
app_otas_status.length = cmd_hdr->cmd.read_data.length;
|
||
app_otas_status.base_addr = cmd_hdr->cmd.read_data.base_address;
|
||
}
|
||
break;
|
||
case OTA_CMD_WRITE_MEM:
|
||
rsp_data_len += sizeof(struct write_mem_rsp);
|
||
break;
|
||
case OTA_CMD_READ_MEM:
|
||
rsp_data_len += sizeof(struct read_mem_rsp) + cmd_hdr->cmd.read_mem.length;
|
||
if(rsp_data_len > OTAS_NOTIFY_DATA_SIZE)
|
||
{
|
||
rsp_data_len = sizeof(struct read_data_rsp) + (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN+OTA_HDR_RESULT_LEN);
|
||
app_otas_status.read_opcode = OTA_CMD_READ_MEM;
|
||
app_otas_status.length = cmd_hdr->cmd.read_data.length;
|
||
app_otas_status.base_addr = cmd_hdr->cmd.read_data.base_address;
|
||
}
|
||
else
|
||
{
|
||
app_otas_status.read_opcode = OTA_CMD_NULL;
|
||
}
|
||
break;
|
||
case OTA_CMD_START:
|
||
rsp_data_len += sizeof(struct ota_start_rsp);
|
||
break;
|
||
case OTA_CMD_NULL:
|
||
|
||
return;
|
||
}
|
||
struct otas_send_rsp *req = pvPortMalloc(sizeof(struct otas_send_rsp));
|
||
uint16_t base_length;
|
||
req->conidx = conidx;
|
||
req->length = rsp_data_len;
|
||
req->buffer = pvPortMalloc(rsp_data_len);
|
||
rsp_hdr = (struct app_ota_rsp_hdr_t *)&req->buffer[0];
|
||
rsp_hdr->result = OTA_RSP_SUCCESS;
|
||
rsp_hdr->org_opcode = cmd_hdr->opcode;
|
||
rsp_hdr->length = rsp_data_len - (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN+OTA_HDR_RESULT_LEN);
|
||
|
||
switch(cmd_hdr->opcode)
|
||
{
|
||
case OTA_CMD_NVDS_TYPE:
|
||
rsp_hdr->rsp.nvds_type = 0x01;
|
||
break;
|
||
case OTA_CMD_GET_STR_BASE: //获取存储地址
|
||
switch(ota_info->ota_ongoing.type)
|
||
{
|
||
case FILE_BOOT_LOADER:
|
||
rsp_hdr->rsp.baseaddr.baseaddr = ota_info->boot_file_info.file_storage_base;
|
||
ota_ongoing_base = ota_info->boot_file_info.file_storage_base;
|
||
ota_ongoing_max_code_size = BOOT_CODE_MAX_SIZE;
|
||
break;
|
||
case FILE_APP:
|
||
rsp_hdr->rsp.baseaddr.baseaddr = ota_info->app_file_info.file_storage_base;
|
||
ota_ongoing_base = ota_info->app_file_info.file_storage_base;
|
||
ota_ongoing_max_code_size = APP_CODE_MAX_SIZE;
|
||
break;
|
||
case FILE_CONTROLLER:
|
||
rsp_hdr->rsp.baseaddr.baseaddr = ota_info->controller_file_info.file_storage_base;
|
||
ota_ongoing_base = ota_info->controller_file_info.file_storage_base;
|
||
ota_ongoing_max_code_size = CONTROLLER_CODE_MAX_SIZE;
|
||
break;
|
||
case FILE_DSP:
|
||
rsp_hdr->rsp.baseaddr.baseaddr = ota_info->dsp_file_info.file_storage_base;
|
||
ota_ongoing_base = ota_info->dsp_file_info.file_storage_base;
|
||
ota_ongoing_max_code_size = DSP_CODE_MAX_SIZE;
|
||
break;
|
||
}
|
||
break;
|
||
case OTA_CMD_READ_FW_VER: //获取版本号
|
||
{
|
||
uint8_t type;
|
||
type = *(p_data + (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN));
|
||
switch(type)
|
||
{
|
||
case FILE_BOOT_LOADER:
|
||
rsp_hdr->rsp.version.firmware_version = ota_info->boot_file_info.file_version;
|
||
break;
|
||
|
||
case FILE_APP:
|
||
rsp_hdr->rsp.version.firmware_version = ota_info->app_file_info.file_version;
|
||
break;
|
||
|
||
case FILE_CONTROLLER:
|
||
rsp_hdr->rsp.version.firmware_version = ota_info->controller_file_info.file_version;
|
||
break;
|
||
case FILE_DSP:
|
||
rsp_hdr->rsp.version.firmware_version = ota_info->dsp_file_info.file_version;
|
||
break;
|
||
}
|
||
|
||
}
|
||
break;
|
||
case OTA_CMD_PAGE_ERASE: //擦除
|
||
{
|
||
rsp_hdr->rsp.page_erase.base_address = cmd_hdr->cmd.page_erase.base_address;
|
||
printf("erase:%x\r\n",cmd_hdr->cmd.page_erase.base_address);
|
||
|
||
/*设置擦除状态*/
|
||
if(ota_info->ota_ongoing.erase_flag == 0)
|
||
{
|
||
ota_info->ota_ongoing.erase_flag = 1;
|
||
GLOBAL_INT_DISABLE();
|
||
flash_erase(QSPI0,OTA_BOOT_INFO_ADDRESS,0x1000);
|
||
flash_write(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)ota_info);
|
||
GLOBAL_INT_RESTORE();
|
||
}
|
||
|
||
/*判断下发的擦除地址是否小于存储地址*/
|
||
if(rsp_hdr->rsp.page_erase.base_address < ota_ongoing_base)
|
||
{
|
||
/*disconnect link*/
|
||
gap_disconnect(conidx);
|
||
}
|
||
else if(rsp_hdr->rsp.page_erase.base_address >= (ota_ongoing_base+ota_ongoing_max_code_size))
|
||
{
|
||
/*disconnect link*/
|
||
printf("erase over size\r\n");
|
||
gap_disconnect(conidx);
|
||
}
|
||
else
|
||
{
|
||
GLOBAL_INT_DISABLE();
|
||
flash_erase(QSPI0,rsp_hdr->rsp.page_erase.base_address, 0x1000);
|
||
GLOBAL_INT_RESTORE();
|
||
}
|
||
}
|
||
break;
|
||
case OTA_CMD_CHIP_ERASE:
|
||
break;
|
||
case OTA_CMD_WRITE_DATA: //导入数据
|
||
{
|
||
printf("program:%x,length:%d\r\n",rsp_hdr->rsp.write_data.base_address,rsp_hdr->rsp.write_data.length);
|
||
rsp_hdr->rsp.write_data.base_address = cmd_hdr->cmd.write_data.base_address;
|
||
rsp_hdr->rsp.write_data.length = cmd_hdr->cmd.write_data.length;
|
||
/*判断下发的烧录地址是否小于存储地址*/
|
||
if(rsp_hdr->rsp.write_data.base_address < ota_ongoing_base)
|
||
{
|
||
/*disconnect link*/
|
||
gap_disconnect(conidx);
|
||
}
|
||
else if(rsp_hdr->rsp.write_data.base_address+rsp_hdr->rsp.write_data.length > (ota_ongoing_base+ota_ongoing_max_code_size))
|
||
{
|
||
/*disconnect link*/
|
||
printf("program over size\r\n");
|
||
gap_disconnect(conidx);
|
||
}
|
||
else
|
||
{
|
||
GLOBAL_INT_DISABLE();
|
||
/*flash write*/
|
||
flash_write(QSPI0,rsp_hdr->rsp.write_data.base_address,
|
||
rsp_hdr->rsp.write_data.length,
|
||
p_data + (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN)+sizeof(struct write_data_cmd));
|
||
GLOBAL_INT_RESTORE();
|
||
}
|
||
}
|
||
break;
|
||
case OTA_CMD_READ_DATA:
|
||
rsp_hdr->rsp.read_data.base_address = cmd_hdr->cmd.read_data.base_address;
|
||
rsp_hdr->rsp.read_data.length = cmd_hdr->cmd.read_data.length;
|
||
base_length = sizeof(struct read_data_rsp) + (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN+OTA_HDR_RESULT_LEN);
|
||
if(rsp_data_len != base_length)
|
||
{
|
||
flash_read(QSPI0,rsp_hdr->rsp.read_data.base_address,
|
||
rsp_hdr->rsp.read_data.length,
|
||
(uint8_t*)rsp_hdr+base_length);
|
||
}
|
||
break;
|
||
case OTA_CMD_WRITE_MEM:
|
||
rsp_hdr->rsp.write_mem.base_address = cmd_hdr->cmd.write_mem.base_address;
|
||
rsp_hdr->rsp.write_mem.length = cmd_hdr->cmd.write_mem.length;
|
||
memcpy((void *)rsp_hdr->rsp.write_mem.base_address,
|
||
p_data + (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN)+sizeof(struct write_data_cmd),
|
||
rsp_hdr->rsp.write_mem.length);
|
||
break;
|
||
case OTA_CMD_READ_MEM:
|
||
rsp_hdr->rsp.read_mem.base_address = cmd_hdr->cmd.read_mem.base_address;
|
||
rsp_hdr->rsp.read_mem.length = cmd_hdr->cmd.read_mem.length;
|
||
base_length = sizeof(struct read_mem_rsp) + (OTA_HDR_OPCODE_LEN+OTA_HDR_LENGTH_LEN+OTA_HDR_RESULT_LEN);
|
||
if(rsp_data_len != base_length)
|
||
{
|
||
memcpy((uint8_t*)rsp_hdr+base_length,
|
||
(void *)rsp_hdr->rsp.read_mem.base_address,
|
||
rsp_hdr->rsp.read_data.length);
|
||
}
|
||
break;
|
||
case OTA_CMD_REBOOT: //复位重启
|
||
{
|
||
printf("crc base:%x,length:%x\r\n",ota_ongoing_base,cmd_hdr->cmd.fir_crc_data.firmware_length);
|
||
if(app_otas_crc_cal(cmd_hdr->cmd.fir_crc_data.firmware_length,ota_ongoing_base,cmd_hdr->cmd.fir_crc_data.CRC32_data))
|
||
{
|
||
|
||
switch(ota_info->ota_ongoing.type)
|
||
{
|
||
case FILE_BOOT_LOADER:
|
||
{
|
||
volatile struct image_info_t image_info;
|
||
flash_read(QSPI0,BOOT_A_INFO_ADDRESS,sizeof(struct image_info_t),(uint8_t *)&image_info);
|
||
image_info.image_version += 1;
|
||
image_info.image_offset = OTA_B_STORAGE_ADDRESS;
|
||
image_info.image_length = cmd_hdr->cmd.fir_crc_data.firmware_length;
|
||
image_info.ota_magic = IMAGE_INFO_OTA_MAGIC;
|
||
image_info.image_crc = get_boot_crc(ota_ongoing_base,cmd_hdr->cmd.fir_crc_data.firmware_length);
|
||
image_info.info_crc = crc32(0x00000000,(uint8_t *)&image_info,IMAGE_INFO_CRC_ZONE_LEN);
|
||
printf("image_info_crc:%x\r\n",image_info.info_crc);
|
||
GLOBAL_INT_DISABLE();
|
||
flash_erase(QSPI0,BOOT_B_INFO_ADDRESS,0x1000);
|
||
flash_write(QSPI0,BOOT_B_INFO_ADDRESS,sizeof(struct image_info_t),(uint8_t *)&image_info);
|
||
GLOBAL_INT_RESTORE();
|
||
ota_info->boot_file_info.file_version = image_info.image_version;
|
||
ota_info->boot_file_info.file_length = image_info.image_length;
|
||
ota_info->boot_file_info.file_crc = image_info.image_crc;
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 1;
|
||
ota_info->ota_ongoing.start_flag = 0;
|
||
ota_info->ota_ongoing.erase_flag = 0;
|
||
}
|
||
break;
|
||
case FILE_APP:
|
||
{
|
||
struct source_file_info_t src_info;
|
||
uint32_t app_code_crc;
|
||
flash_read(QSPI0,APP_CODE_STORAGE_ADDRESS+APP_CODE_INFO_OFFSET,sizeof(struct source_file_info_t),(uint8_t *)&src_info);
|
||
if(memcmp(src_info.check_buff,app_check_data,4) == 0)
|
||
{
|
||
ota_info->app_file_info.file_version = src_info.version;
|
||
ota_info->app_file_info.file_length = src_info.length;
|
||
flash_read(QSPI0,APP_CODE_STORAGE_ADDRESS+src_info.length,4,(uint8_t *)&app_code_crc);
|
||
ota_info->app_file_info.file_crc = app_code_crc;
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 1;
|
||
ota_info->ota_ongoing.start_flag = 0;
|
||
ota_info->ota_ongoing.erase_flag = 0;
|
||
}else{
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 0;
|
||
printf("app ota fail\r\n");
|
||
}
|
||
}
|
||
break;
|
||
case FILE_CONTROLLER:
|
||
{
|
||
struct source_file_info_t src_info;
|
||
flash_read(QSPI0,CONTROLLER_STORAGE_ADDRESS,sizeof(struct source_file_info_t),(uint8_t *)&src_info);
|
||
if(memcmp(src_info.check_buff,controller_check_data,4) == 0 )
|
||
{
|
||
ota_info->controller_file_info.file_length = src_info.length;
|
||
ota_info->controller_file_info.file_version = src_info.version;
|
||
ota_info->controller_file_info.file_crc = src_info.crc;
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 1;
|
||
ota_info->ota_ongoing.start_flag = 0;
|
||
ota_info->ota_ongoing.erase_flag = 0;
|
||
}else{
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 0;
|
||
printf("controller ota fail\r\n");
|
||
}
|
||
}
|
||
break;
|
||
case FILE_DSP:
|
||
{
|
||
struct source_file_info_t src_info;
|
||
flash_read(QSPI0,DSP_STORAGE_ADDRESS,sizeof(struct source_file_info_t),(uint8_t *)&src_info);
|
||
if(memcmp(src_info.check_buff,dsp_check_data,4) == 0)
|
||
{
|
||
ota_info->dsp_file_info.file_length = src_info.length;
|
||
ota_info->dsp_file_info.file_version = src_info.version;
|
||
ota_info->dsp_file_info.file_crc = src_info.crc;
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 1;
|
||
ota_info->ota_ongoing.start_flag = 0;
|
||
ota_info->ota_ongoing.erase_flag = 0;
|
||
}else{
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 0;
|
||
printf("dsp ota fail\r\n");
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
GLOBAL_INT_DISABLE();
|
||
flash_erase(QSPI0,OTA_BOOT_INFO_ADDRESS,0x1000);
|
||
flash_write(QSPI0,OTA_BOOT_INFO_ADDRESS,sizeof(struct ota_info_t),(uint8_t *)ota_info);
|
||
GLOBAL_INT_RESTORE();
|
||
printf("crc finish\r\n");
|
||
wdt_rst_start();
|
||
}else{
|
||
printf("crc error\r\n");
|
||
rsp_hdr->rsp.finsih_rsp.ota_finsih_state = 0;
|
||
wdt_rst_start();
|
||
}
|
||
}
|
||
break;
|
||
case OTA_CMD_START:
|
||
{
|
||
rsp_hdr->rsp.ota_start.ota_start = 1;
|
||
}
|
||
break;
|
||
default:
|
||
rsp_hdr->result = OTA_RSP_UNKNOWN_CMD;
|
||
break;
|
||
}
|
||
ota_gatt_report_notify(conidx,req->buffer,req->length);
|
||
vPortFree(req->buffer);
|
||
vPortFree(req);
|
||
}
|
||
|
||
/*********************************************************************
|
||
*
|
||
* @brief Check ota file
|
||
*
|
||
*/
|
||
local const uLongf crc_table[256] = {
|
||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||
0x2d02ef8dL
|
||
};
|
||
|
||
/* =========================================================================
|
||
* This function can be used by asm versions of crc32()
|
||
*/
|
||
const uLongf * ZEXPORT get_crc_table(void)
|
||
{
|
||
#ifdef DYNAMIC_CRC_TABLE
|
||
if (crc_table_empty) make_crc_table();
|
||
#endif
|
||
return (const uLongf *)crc_table;
|
||
}
|
||
|
||
/* ========================================================================= */
|
||
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||
#define DO2(buf) DO1(buf); DO1(buf);
|
||
#define DO4(buf) DO2(buf); DO2(buf);
|
||
#define DO8(buf) DO4(buf); DO4(buf);
|
||
|
||
/* ========================================================================= */
|
||
uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len)
|
||
{
|
||
// if (buf == Z_NULL) return 0L;
|
||
#ifdef DYNAMIC_CRC_TABLE
|
||
if (crc_table_empty)
|
||
make_crc_table();
|
||
#endif
|
||
crc = crc ^ 0xffffffffL;
|
||
while (len >= 8) {
|
||
DO8(buf);
|
||
len -= 8;
|
||
}
|
||
if (len) do {
|
||
DO1(buf);
|
||
} while (--len);
|
||
return crc ^ 0xffffffffL;
|
||
}
|
||
|
||
|
||
__RAM_CODE uint32_t Crc32CalByByte(int crc,uint8_t* ptr, int len)
|
||
{
|
||
int i = 0;
|
||
while(len-- != 0)
|
||
{
|
||
int high = crc/256;
|
||
crc <<= 8;
|
||
crc ^= crc_table[(high^ptr[i])&0xff];
|
||
crc &= 0xFFFFFFFF;
|
||
i++;
|
||
}
|
||
return crc&0xFFFFFFFF;
|
||
}
|
||
|
||
|
||
__RAM_CODE static uint8_t app_otas_crc_cal(uint32_t firmware_length,uint32_t new_bin_addr,uint32_t crc_data_t)
|
||
{
|
||
uint32_t crc_data = 0,i = 0;
|
||
uint8_t * crc_check_data = pvPortMalloc(0x1000);
|
||
uint8_t ret = 0;
|
||
uint32_t data_size = firmware_length;
|
||
uint32_t read_address = new_bin_addr;
|
||
while(data_size > 0x1000)
|
||
{
|
||
flash_read(QSPI0,read_address, 0x1000,crc_check_data);
|
||
crc_data = Crc32CalByByte(crc_data, crc_check_data,0x1000);
|
||
data_size -= 0x1000;
|
||
read_address += 0x1000;
|
||
}
|
||
flash_read(QSPI0,read_address, data_size,crc_check_data);
|
||
crc_data = Crc32CalByByte(crc_data, crc_check_data,data_size);
|
||
printf("crc:%x,%x",crc_data,crc_data_t);
|
||
vPortFree(crc_check_data);
|
||
if(crc_data_t == crc_data)
|
||
ret = 1;
|
||
|
||
return ret;
|
||
}
|
||
|
||
uint32_t get_boot_crc(uint32_t imagesize,uint32_t length)
|
||
{
|
||
uint32_t crc_data = 0,i = 0;
|
||
uint8_t * crc_check_data = pvPortMalloc(0x1000);
|
||
uint8_t ret = 0;
|
||
uint32_t data_size = length;
|
||
uint32_t read_address = imagesize;
|
||
while(data_size > 0x1000)
|
||
{
|
||
flash_read(QSPI0,read_address, 0x1000,crc_check_data);
|
||
crc_data = crc32(crc_data, crc_check_data,0x1000);
|
||
data_size -= 0x1000;
|
||
read_address += 0x1000;
|
||
}
|
||
flash_read(QSPI0,read_address, data_size,crc_check_data);
|
||
crc_data = crc32(crc_data, crc_check_data,data_size);
|
||
printf("file crc:%x\r\n",crc_data);
|
||
vPortFree(crc_check_data);
|
||
return crc_data;
|
||
} |