992 lines
35 KiB
C
992 lines
35 KiB
C
/**
|
||
* @file ota_execute.c
|
||
* @brief OTA 功能实现文件,供OTA协议层调用
|
||
* @details
|
||
* @author George
|
||
* @date 2021/6/28
|
||
* @version A001
|
||
* @par Copyright (c):
|
||
* SmartFenda.
|
||
* @par History:
|
||
* version: author, date, desc\n
|
||
*/
|
||
|
||
#include "am_util_debug.h"
|
||
#include "sys_config.h"
|
||
|
||
#include "FreeRTOS.h"
|
||
#include "task.h"
|
||
#include "timers.h"
|
||
|
||
#include "crc32.h"
|
||
#include "am_bootloader.h"
|
||
#include "am_multi_boot.h"
|
||
//#include "amota_profile_config.h"
|
||
#include "am_hal_mram.h"
|
||
|
||
#include "ble_ota_execute.h"
|
||
#include "ble_protocol.h"
|
||
#include "flash_api.h"
|
||
//#include "user_gps.h"
|
||
#include "ppg_api.h"
|
||
#include "task_ble.h"
|
||
#include "log_api.h"
|
||
#include "rtc_api.h"
|
||
#include "user_adapter.h"
|
||
#include "motor_api.h"
|
||
#include "sys_adapter.h"
|
||
|
||
#include "user_pack_analysis.h"
|
||
#include "sys_typedef.h"
|
||
#include "ui_event.h"
|
||
#include "task_ui.h"
|
||
#include "user_charge.h"
|
||
#include "ui_port_fw.h"
|
||
#include "charge_api.h"
|
||
|
||
|
||
#define ENABLE_STATIC_PRINT false
|
||
extern uint32_t am_util_stdio_printf(const char *pcFmt, ...);
|
||
#define static_print_remind(...) am_util_stdio_printf(__VA_ARGS__)
|
||
#if ENABLE_STATIC_PRINT
|
||
#define static_print_info(...) am_util_stdio_printf(__VA_ARGS__)
|
||
#else
|
||
#define static_print_info(...)
|
||
#endif
|
||
|
||
#define OTA_READ_BUFSIZE 1024 // 若空间不够可以设1024或更小的值
|
||
|
||
#define BYTES_2_UINT32(n, p) {n = ((uint32_t)(p)[0] + ((uint32_t)(p)[1] << 8) + \
|
||
((uint32_t)(p)[2] << 16) + ((uint32_t)(p)[3] << 24));}
|
||
|
||
// Protection against NULL pointer
|
||
//#define FLASH_OPERATE(pFlash, func) ((pFlash)->func ? (pFlash)->func() : 0)
|
||
#define FLASH_OPERATE(pFlash, func)
|
||
|
||
|
||
#if 1
|
||
|
||
//MBR INFO 此定义OTA与BOOT工程中MBR严格对齐
|
||
enum {
|
||
FW_SOUR_CS_NULL,
|
||
FW_SOUR_CS_RAM,
|
||
FW_SOUR_CS_ROM,
|
||
FW_SOUR_CS_FLASH,
|
||
FW_SOUR_CS_FS,
|
||
FW_SOUR_CS_MAX,
|
||
};
|
||
|
||
typedef struct {
|
||
// 固件源地址
|
||
uint32_t fw_sour_addr;
|
||
// 固件目的地址(运行地址)
|
||
uint32_t fw_dest_addr;
|
||
// 固件源片选
|
||
uint32_t fw_sour_cs:8;
|
||
// 固件目的片选
|
||
uint32_t fw_dest_cs:8;//固件源存放片选。NULL、RAM、ROM、EXT_FLASH、FS
|
||
// 保留字节
|
||
uint32_t fw_reserve1:16;
|
||
// 固件版本号
|
||
uint8_t fw_version[4];
|
||
// 固件大小, 单位字节
|
||
uint32_t fw_bytes;
|
||
// 固件 crc32 值
|
||
uint32_t fw_crc32;
|
||
}fw_parm_t;
|
||
|
||
typedef struct {
|
||
// 0x01: 不需要搬运固件, 直接跳转到 APP 区(正式固件) 执行;
|
||
// 0x02: 不需要搬运固件, 直接跳转到 APP 区(厂测固件) 执行;
|
||
// 0x03: 不需要搬运固件, 直接跳转到 APP 区(DTM固件) 执行;
|
||
// 0x10: 需要搬运正式固件;
|
||
// 0x20: 需要搬运厂测固件;
|
||
// 0x30: 需要搬运DTM固件;
|
||
uint32_t carry_fw_flag;
|
||
// 标签
|
||
char mark[32];
|
||
// 正式固件参数
|
||
fw_parm_t formal;
|
||
// 厂测固件参数
|
||
fw_parm_t factory;
|
||
// DTM固件参数
|
||
fw_parm_t dmt;
|
||
// OTA 参数区的 crc32 校验值
|
||
uint32_t crc32;
|
||
}mbr_parm_t;
|
||
|
||
#endif
|
||
|
||
//
|
||
// Data structure for Breakpoint continuation
|
||
//
|
||
typedef struct
|
||
{
|
||
uint32_t fileOffset;
|
||
uint32_t fileSize;
|
||
uint32_t fileCrc32;
|
||
uint32_t ifResume;
|
||
uint32_t crc;
|
||
uint32_t res; // 8字节对齐
|
||
}FwBreakPointInfo_t;
|
||
|
||
otasFlashOp_t otaFlashOp = {
|
||
.bufferIndex = 0,
|
||
};
|
||
|
||
static FwBreakPointInfo_t g_otaBreakPoint = {0};
|
||
|
||
static TimerHandle_t ota_timeout_time_handle = NULL;
|
||
static TimerHandle_t g_otaResendTimer = NULL;
|
||
static OtaCtrlBlock_t g_otaCtrlBlock = {0};
|
||
static am_multiboot_flash_info_t *g_pFlash = NULL;
|
||
static am_multiboot_flash_info_t g_ext_flash = {0};
|
||
static uint8_t OtasReadBuf[OTA_READ_BUFSIZE] = {0};
|
||
|
||
static head_desc_parm g_ota_head_param;
|
||
static head_struct_parm g_ota_head_struct;
|
||
static mbr_parm_t g_boot_mbr_info;
|
||
|
||
extern void user_update_percent_show(uint8_t percent);
|
||
extern void DeviceRequestOTAFileData(uint32_t offset,uint16_t DataLen,uint32_t TotalFileSise,uint32_t ReceivedFileSize);
|
||
void OtaUpdateBreakPoint(void);
|
||
|
||
extern uint8_t user_dog_get_timeout_status(void);
|
||
int ota_flash_read_func(uint32_t ui32DestAddr, uint32_t *pSrc, uint32_t ui32Length)
|
||
{
|
||
return flash_api_read(ui32DestAddr, pSrc, ui32Length);
|
||
}
|
||
|
||
int ota_flash_write_func(uint32_t ui32DestAddr, uint32_t *pSrc, uint32_t ui32Length)
|
||
{
|
||
return flash_api_write(ui32DestAddr, pSrc, ui32Length);
|
||
}
|
||
|
||
int ota_flash_erase_func(uint32_t ui32Addr)
|
||
{
|
||
return flash_api_erase(ui32Addr);
|
||
}
|
||
|
||
int ota_ext_flash_info_init(am_multiboot_flash_info_t *pFlash)
|
||
{
|
||
pFlash->flashPageSize = flash_api_get_erase_unit_size();
|
||
pFlash->flashSectorSize = flash_api_get_erase_unit_size();
|
||
pFlash->flash_init = NULL;
|
||
pFlash->flash_deinit = NULL;
|
||
pFlash->flash_enable = NULL;
|
||
pFlash->flash_disable = NULL;
|
||
pFlash->flash_read_page = ota_flash_read_func;
|
||
pFlash->flash_write_page = ota_flash_write_func;
|
||
pFlash->flash_erase_sector = ota_flash_erase_func;
|
||
return true;
|
||
}
|
||
|
||
static void OtaTimeoutCb(TimerHandle_t xTimer)
|
||
{
|
||
static_print_info("?????ota_timeout?????\r\n");
|
||
OtaFailed(PACK_WAIE_TIMEOUT_ERROR);
|
||
}
|
||
|
||
void OtaCreatTimeoutTimer(void)
|
||
{
|
||
ota_timeout_time_handle = xTimerCreate("ota_timeout_task_time",(1000 * 10), false, NULL, OtaTimeoutCb);
|
||
if(ota_timeout_time_handle==NULL)
|
||
{
|
||
static_print_info("?????ota_timeout_creat_time fail?????\r\n");
|
||
}
|
||
}
|
||
|
||
void OtaTimeoutReset(void)
|
||
{
|
||
if(ota_timeout_time_handle != NULL)
|
||
{
|
||
xTimerReset(ota_timeout_time_handle, 0);
|
||
}
|
||
}
|
||
|
||
void OtaTimeoutTimerStop(void)
|
||
{
|
||
if(ota_timeout_time_handle != NULL)
|
||
{
|
||
xTimerStop(ota_timeout_time_handle, 0);
|
||
}
|
||
}
|
||
|
||
static void OtaResendTimerCallback(TimerHandle_t xTimer)
|
||
{
|
||
static_print_info("need resend, offset=%x!\r\n", g_otaCtrlBlock.pkt.offset);
|
||
DeviceRequestOTAFileData(g_otaCtrlBlock.pkt.offset, g_otaCtrlBlock.pkt.ApplyLen,
|
||
g_otaCtrlBlock.pkt.FileSize, g_otaCtrlBlock.pkt.offset);
|
||
}
|
||
|
||
void OtaFrameResendTimerLoad(void)
|
||
{
|
||
if(g_otaResendTimer == NULL)
|
||
{
|
||
g_otaResendTimer = xTimerCreate("otaResendTimer",(1000 * 3), false, NULL, OtaResendTimerCallback);
|
||
static_print_info("g_otaResendTimer=0x%08X\r\n", g_otaResendTimer);
|
||
if(g_otaResendTimer != NULL)
|
||
{
|
||
xTimerStart(g_otaResendTimer, 0);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
xTimerReset(g_otaResendTimer, 0);
|
||
}
|
||
}
|
||
|
||
void OtaFrameResendTimerStop(void)
|
||
{
|
||
if(g_otaResendTimer != NULL)
|
||
{
|
||
xTimerStop(g_otaResendTimer, 0);
|
||
}
|
||
}
|
||
|
||
bool_t OtaIsStarted(void)
|
||
{
|
||
return g_otaCtrlBlock.ota_start_flag;
|
||
}
|
||
|
||
/*!
|
||
* brief: Get Ota CtrlBlock, for OTA service call
|
||
*/
|
||
void GetOtaCtrlBlock(OtaCtrlBlock_t *ctrl)
|
||
{
|
||
memcpy(ctrl, &g_otaCtrlBlock, sizeof(OtaCtrlBlock_t));
|
||
}
|
||
|
||
/*!
|
||
* brief: Check whether the device can be OTA,for OTA service call
|
||
*/
|
||
uint8_t OtaRequest(uint32_t FwLen)
|
||
{
|
||
uint8_t CurrBattPercent;
|
||
chg_status_e charge_status;
|
||
|
||
CurrBattPercent = ui_port_get_battary_percent();
|
||
charge_status = charge_api_get_charge_status();
|
||
static_print_remind ("Current Batt Percent:%d%. - status = %d \r\n",CurrBattPercent,charge_status);
|
||
if(charge_status == BATT_STAT_CHARGE_TEMPER_0_5
|
||
|| charge_status == BATT_STAT_CHARGE_TEMPER_6_15
|
||
|| charge_status == BATT_STAT_CHARGE_TEMPER_16_45
|
||
|| charge_status == BATT_STAT_CHARGE_DONE_NOT_CHARGE
|
||
)
|
||
{
|
||
CurrBattPercent = 80; // 若处于充电状态则不用检测电量
|
||
}
|
||
if(CurrBattPercent < OTA_BATT_THRESHOLD)
|
||
{
|
||
return 1; //1:不能升级
|
||
}
|
||
memset(&g_otaCtrlBlock, 0, sizeof(g_otaCtrlBlock));
|
||
g_otaCtrlBlock.pkt.FileSize = FwLen;
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*!
|
||
* brief: OTA completed, for OTA service call
|
||
*/
|
||
void OtaSucceed(void)
|
||
{
|
||
uint32_t BreakPointPtrVal = 0;
|
||
|
||
OtaTimeoutTimerStop();
|
||
OtaFrameResendTimerStop();
|
||
|
||
BreakPointPtrVal = *((uint32_t *)USER_OTA_BREAK_POINT_ADDR);
|
||
if((BreakPointPtrVal != 0xFFFFFFFF) && (BreakPointPtrVal != 0))
|
||
{// 若存在断点续传信息则清除
|
||
memset(&g_otaBreakPoint, 0, sizeof(g_otaBreakPoint));
|
||
OtaUpdateBreakPoint();
|
||
}
|
||
|
||
if(g_otaCtrlBlock.HeaderInfo.fwDataType == MARK_MCU_FW_BIN)
|
||
{
|
||
OtaUpdateFwInfo();
|
||
}
|
||
|
||
task_ui_notify(EVENT_OTA_TRANSMITTING, 100, NULL, 0);
|
||
|
||
// log_api_record_action(rtc_api_get_utc_timestamp(), EVT_OTA_UPDATE, INFO1_OTA_SUCC, 0, 0, NULL);
|
||
task_ble_notify(BLE_RESET_AFTER_OTA_MSG, 0); //退出升级,延时复位
|
||
}
|
||
|
||
/*!
|
||
* brief: OTA Failed, for OTA service call
|
||
*/
|
||
void OtaFailed(uint8_t reason)
|
||
{
|
||
OtaTimeoutTimerStop();
|
||
OtaFrameResendTimerStop();
|
||
recovery_ble_task_priority();
|
||
g_otaCtrlBlock.ota_start_flag = FALSE;
|
||
|
||
if(g_otaCtrlBlock.ota_status == OTA_STATE_FW_DATA && g_otaCtrlBlock.pkt.offset > AM_HAL_FLASH_PAGE_SIZE)
|
||
{
|
||
static_print_info("we need storage breakpoint info:0x%x-0x%x-0x%x\r\n",g_otaCtrlBlock.HeaderInfo.fwCrc,g_otaCtrlBlock.pkt.offset,g_otaCtrlBlock.HeaderInfo.fwLength);
|
||
g_otaBreakPoint.fileCrc32 = g_otaCtrlBlock.HeaderInfo.fwCrc;
|
||
g_otaBreakPoint.fileOffset = g_otaCtrlBlock.pkt.offset;
|
||
g_otaBreakPoint.fileSize = g_otaCtrlBlock.HeaderInfo.fwLength;
|
||
g_otaBreakPoint.ifResume = 1;
|
||
OtaUpdateBreakPoint();
|
||
}
|
||
else if(g_otaCtrlBlock.ota_status == OTA_STATE_FW_RESET)
|
||
{
|
||
int32_t BreakPointPtrVal = 0;
|
||
|
||
BreakPointPtrVal = *((uint32_t *)OTA_BREAK_POINT_ADDR);
|
||
if((BreakPointPtrVal != 0xFFFFFFFF) && (BreakPointPtrVal != 0))
|
||
{// 若存在断点续传信息则清除
|
||
memset(&g_otaBreakPoint, 0, sizeof(g_otaBreakPoint));
|
||
//OtaUpdateBreakPoint();
|
||
}
|
||
}
|
||
task_ui_notify(EVENT_OTA_FAIL, 0, NULL, 0);
|
||
log_api_record_action(rtc_api_get_utc_timestamp(), EVT_OTA_UPDATE, INFO1_OTA_FAIL, reason, g_otaBreakPoint.fileOffset, NULL);
|
||
task_ble_notify(BLE_RESET_AFTER_OTA_MSG, 0); //退出升级,延时复位
|
||
// task_ui_notify(UI_MSG_GOTO_MAINMENU, 0, NULL, 0);
|
||
}
|
||
|
||
|
||
void OtaStop(void)
|
||
{
|
||
if(!OtaIsStarted())
|
||
return;
|
||
|
||
OtaFailed(DEVICE_DISCONNECT);
|
||
}
|
||
|
||
/*!
|
||
* brief: Start OTA,for OTA service call
|
||
*/
|
||
void OtaStart(void)
|
||
{
|
||
|
||
task_ui_notify(EVENT_OTA_TRANSMITTING, 0, NULL, 0);
|
||
|
||
log_api_record_action(rtc_api_get_utc_timestamp(), EVT_OTA_UPDATE, INFO1_OTA_START, 0, 0, NULL);
|
||
motor_api_stop();
|
||
//user_gps_shutdown();
|
||
gsensor_api_close();
|
||
ppg_api_close();
|
||
//g_user_tp_ops.close(); // 关闭tp
|
||
/* OTA 过程中 主频使用48M */
|
||
sys_smart_delay_ms(100);
|
||
sys_burst_mode_switch(0, 1, false);
|
||
|
||
g_otaCtrlBlock.ota_start_flag = TRUE;
|
||
g_otaCtrlBlock.ota_status = OTA_STATE_FW_HEADER;
|
||
g_otaCtrlBlock.pkt.ApplyLen = FW_HEAD_INFO_IEN; //请求的第一包为固定长度0x30的固件头部信息
|
||
}
|
||
|
||
/*!
|
||
* brief: Verify the currently written data
|
||
*/
|
||
static int OtaVerifyFlashContent(uint32_t flashAddr, uint32_t *pSram, uint32_t len, am_multiboot_flash_info_t *pFlash)
|
||
{
|
||
// read back and check
|
||
uint32_t offset = 0;
|
||
uint32_t remaining = len;
|
||
int ret = 0;
|
||
|
||
if(remaining < g_pFlash->flashPageSize)
|
||
{
|
||
remaining = g_pFlash->flashPageSize;
|
||
}
|
||
|
||
while (remaining)
|
||
{
|
||
uint32_t tmpSize = (remaining > OTA_READ_BUFSIZE) ? OTA_READ_BUFSIZE : remaining;
|
||
|
||
//pFlash->flash_read_page((uint32_t)OtasReadBuf, (uint32_t *)(flashAddr + offset), tmpSize);
|
||
ret = pFlash->flash_read_page((flashAddr + offset), (uint32_t *)OtasReadBuf, tmpSize);
|
||
|
||
ret = memcmp(OtasReadBuf, (uint8_t*)((uint32_t)pSram + offset), tmpSize);
|
||
if ( ret != 0 )
|
||
{
|
||
// there is write failure happened.
|
||
static_print_info("\r\n??????flash write verify failed. address 0x%x. length %d????? - tmpSize = %d - ret = %x \r\n", flashAddr, len,tmpSize );
|
||
for(uint16_t i = 0; i < tmpSize; i++ )
|
||
static_print_info("i = %d >>> read =%x - tran = %x \n",i,OtasReadBuf[i], ((uint8_t*)pSram)[i]);
|
||
break;
|
||
}
|
||
|
||
offset += tmpSize;
|
||
remaining -= tmpSize;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
/*!
|
||
* brief: OTA firmware writing to flash
|
||
*/
|
||
static uint32_t OtaWrite2Flash(uint16_t len, uint8_t *buf, uint32_t addr, bool lastPktFlag)
|
||
{
|
||
uint16_t ui16BytesRemaining = len;
|
||
uint32_t ui32TargetAddress = 0;
|
||
uint8_t ui8PageCount = 0;
|
||
uint32_t error_code = FENDA_SUCCESS;
|
||
uint16_t i;
|
||
uint8_t indx = 0;
|
||
uint32_t write_result = 0x10000;
|
||
|
||
addr -= otaFlashOp.bufferIndex;
|
||
//
|
||
// Check the target flash address to ensure we do not operation the wrong address
|
||
// make sure to write to page boundary
|
||
//
|
||
static_print_remind("len=0x%x,buf=0x%x,addr=0x%x,lastPktFlag=%d,Index=%d\n",len,buf,addr,lastPktFlag,otaFlashOp.bufferIndex);
|
||
if (((uint32_t)g_otaCtrlBlock.newFwFlashInfo.addr > addr) ||
|
||
(addr & (g_pFlash->flashPageSize - 1)))
|
||
{
|
||
//
|
||
// application is trying to write to wrong address
|
||
//
|
||
static_print_info(" application is trying to write to wrong address addr = %x\n",addr);
|
||
return DEVICE_FW_OTA_ERROR;
|
||
}
|
||
|
||
FLASH_OPERATE(g_pFlash, flash_enable);
|
||
while (ui16BytesRemaining)
|
||
{
|
||
uint16_t ui16Bytes2write = g_pFlash->flashPageSize - otaFlashOp.bufferIndex;
|
||
if (ui16Bytes2write > ui16BytesRemaining)
|
||
{
|
||
ui16Bytes2write = ui16BytesRemaining;
|
||
}
|
||
// move data into buffer
|
||
for ( i = 0; i < ui16Bytes2write; i++ )
|
||
{
|
||
// avoid using memcpy
|
||
otaFlashOp.writeBuffer[otaFlashOp.bufferIndex++] = buf[i];
|
||
}
|
||
ui16BytesRemaining -= ui16Bytes2write;
|
||
buf += ui16Bytes2write;
|
||
|
||
static_print_info("ui16BytesRemaining = %d - ui16Bytes2write = %d \n",ui16BytesRemaining,ui16Bytes2write);
|
||
//
|
||
// Write to flash when there is data more than 1 page size
|
||
// For last fragment write even if it is less than one page
|
||
//
|
||
if (lastPktFlag || (otaFlashOp.bufferIndex == g_pFlash->flashPageSize))
|
||
{
|
||
ui32TargetAddress = (addr + ui8PageCount*g_pFlash->flashPageSize);
|
||
|
||
for(indx = 0; indx < 3; indx++)
|
||
{
|
||
error_code = g_pFlash->flash_erase_sector(ui32TargetAddress);
|
||
static_print_info(" flash_erase_sector = %d \n",error_code);
|
||
if(error_code == AM_HAL_STATUS_SUCCESS)
|
||
//if(g_pFlash->flash_erase_sector(ui32TargetAddress) == AM_HAL_STATUS_SUCCESS)
|
||
{
|
||
error_code = g_pFlash->flash_write_page(ui32TargetAddress, (uint32_t *)otaFlashOp.writeBuffer, g_pFlash->flashPageSize);
|
||
static_print_info(" flash_write_page = %d \n",error_code);
|
||
if( error_code == write_result)
|
||
//if(g_pFlash->flash_write_page(ui32TargetAddress, (uint32_t *)otaFlashOp.writeBuffer, g_pFlash->flashPageSize) == AM_HAL_STATUS_SUCCESS)
|
||
{
|
||
if(OtaVerifyFlashContent(ui32TargetAddress, (uint32_t *)otaFlashOp.writeBuffer, otaFlashOp.bufferIndex, g_pFlash) == AM_HAL_STATUS_SUCCESS)
|
||
{
|
||
static_print_info("Flash write succeeded to address 0x%x. length %d\n", ui32TargetAddress, otaFlashOp.bufferIndex);
|
||
ui8PageCount++;
|
||
otaFlashOp.bufferIndex = 0;
|
||
error_code = FENDA_SUCCESS;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
error_code = DATA_CRC_OTA_ERROR;
|
||
static_print_remind("\r\n\r\n\n\nFlash verify failed to address: 0x%x. indx = %d\r \n", ui32TargetAddress, indx);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error_code = FLASH_WRITE_OTA_ERROR;
|
||
static_print_remind("\r\n\r\n\n\nFlash write failed to address: 0x%x. indx = %d - %d\r \n", ui32TargetAddress, indx,g_pFlash->flashPageSize);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error_code = FLASH_ERASE_OTA_ERROR;
|
||
static_print_remind("\r\n\r\n\n\nFlash erase sector failed to address: 0x%x. indx = %d\r\n", ui32TargetAddress, indx);
|
||
}
|
||
vTaskDelay(100);
|
||
}
|
||
|
||
if(indx >= 3)
|
||
{
|
||
OtaFailed(DEVICE_DISCONNECT);
|
||
static_print_remind("try 3 times to write flash, but all failed\r\n");
|
||
break;
|
||
}
|
||
|
||
// FlashOperationStatus = g_pFlash->flash_erase_sector(ui32TargetAddress);
|
||
|
||
// // Always write whole pages
|
||
// if ((g_pFlash->flash_write_page(ui32TargetAddress, (uint32_t *)otaFlashOp.writeBuffer, g_pFlash->flashPageSize) != 0)
|
||
// || (OtaVerifyFlashContent(ui32TargetAddress, (uint32_t *)otaFlashOp.writeBuffer, otaFlashOp.bufferIndex, g_pFlash) != 0))
|
||
// //if (g_pFlash->flash_write_page(ui32TargetAddress, (uint32_t *)otaFlashOp.writeBuffer, g_pFlash->flashPageSize) != 0)
|
||
// {
|
||
// static_print_info("FlashOperationStatus = %d, Flash write failed to address: 0x%x \n", FlashOperationStatus, ui32TargetAddress);
|
||
//
|
||
// bResult = false;
|
||
// break;
|
||
// }
|
||
// static_print_info("Flash write succeeded to address 0x%x. length %d\n", ui32TargetAddress, otaFlashOp.bufferIndex);
|
||
|
||
// ui8PageCount++;
|
||
// otaFlashOp.bufferIndex = 0;
|
||
// bResult = true;
|
||
}
|
||
}
|
||
FLASH_OPERATE(g_pFlash, flash_disable);
|
||
|
||
//
|
||
// If we get here, operations are done correctly
|
||
//
|
||
return error_code;
|
||
}
|
||
|
||
|
||
/*!
|
||
* brief: Verify Firmware Image CRC
|
||
*/
|
||
static bool_t OtaVerifyFirmwareCrc(void)
|
||
{
|
||
// read back the whole firmware image from flash and calculate CRC
|
||
uint32_t ui32CRC = 0;
|
||
uint32_t ui32_addr = 0;
|
||
uint32_t ui32_length = 0;
|
||
uint32_t blk_start,blk_end,blk_num,index;
|
||
uint16_t read_start_size = 0;
|
||
uint16_t read_end_size = 0;
|
||
uint32_t len_op=0;
|
||
uint32_t i=0;
|
||
// uint32_t ret=0;
|
||
|
||
//
|
||
// Check crc in external flash
|
||
//
|
||
FLASH_OPERATE(g_pFlash, flash_enable);
|
||
|
||
// if(g_otaCtrlBlock.HeaderInfo.fwDataType != MARK_MCU_FW_BIN)
|
||
{
|
||
ui32_addr = g_otaCtrlBlock.newFwFlashInfo.addr + g_otaCtrlBlock.HeaderInfo.secInfoLen;
|
||
ui32_length = g_otaCtrlBlock.HeaderInfo.fwLength - g_otaCtrlBlock.HeaderInfo.secInfoLen;
|
||
}
|
||
|
||
blk_start = ui32_addr/AMOTAS_TEMP_BUFSIZE;
|
||
len_op = ui32_addr%AMOTAS_TEMP_BUFSIZE;
|
||
if(len_op)
|
||
{
|
||
read_start_size = AMOTAS_TEMP_BUFSIZE - len_op;
|
||
if(read_start_size>ui32_length)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
}
|
||
else if(ui32_length<AMOTAS_TEMP_BUFSIZE)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
|
||
blk_end = (ui32_addr + ui32_length)/AMOTAS_TEMP_BUFSIZE;
|
||
if(blk_end>blk_start)
|
||
{
|
||
read_end_size = (ui32_addr + ui32_length)%AMOTAS_TEMP_BUFSIZE;
|
||
}
|
||
else
|
||
{
|
||
read_end_size = 0;
|
||
}
|
||
blk_num = (ui32_length - read_start_size - read_end_size)/AMOTAS_TEMP_BUFSIZE;
|
||
|
||
index = 0;
|
||
if(read_start_size)
|
||
{
|
||
len_op = read_start_size;
|
||
g_pFlash->flash_read_page((uint32_t)(ui32_addr + index),
|
||
(uint32_t *)otaFlashOp.writeBuffer,
|
||
len_op);
|
||
ui32CRC = crc32_ex(ui32CRC, otaFlashOp.writeBuffer, len_op);
|
||
blk_start++;
|
||
index += len_op;
|
||
}
|
||
|
||
if(blk_num)
|
||
{
|
||
len_op = AMOTAS_TEMP_BUFSIZE;
|
||
for(i=0;i<blk_num;i++)
|
||
{
|
||
g_pFlash->flash_read_page((uint32_t)(ui32_addr + index),
|
||
(uint32_t *)otaFlashOp.writeBuffer,
|
||
len_op);
|
||
ui32CRC = crc32_ex(ui32CRC, otaFlashOp.writeBuffer, len_op);
|
||
blk_start++;
|
||
index += len_op;
|
||
}
|
||
}
|
||
|
||
if(read_end_size)
|
||
{
|
||
len_op = read_end_size;
|
||
g_pFlash->flash_read_page((uint32_t)(ui32_addr + index),
|
||
(uint32_t *)otaFlashOp.writeBuffer,
|
||
len_op);
|
||
ui32CRC = crc32_ex(ui32CRC, otaFlashOp.writeBuffer, len_op);
|
||
blk_start++;
|
||
index += len_op;
|
||
}
|
||
|
||
if(index != ui32_length)
|
||
{
|
||
static_print_remind("error:[OtaVerifyFirmwareCrc()] ui32_addr %d index %d ui32_length %d\r\n",ui32_addr,index,ui32_length);
|
||
}
|
||
|
||
FLASH_OPERATE(g_pFlash, flash_disable);
|
||
static_print_remind("addr = 0x%x,len = %d-%d,ui32CRC = 0x%x,fwCrc = 0x%x\r\n",ui32_addr,ui32_length,index,ui32CRC, g_otaCtrlBlock.HeaderInfo.fwCrc);
|
||
|
||
return (ui32CRC == g_otaCtrlBlock.HeaderInfo.fwCrc);
|
||
}
|
||
|
||
/*!
|
||
* brief: Processing firmware header information.
|
||
*/
|
||
uint32_t ProcessingFwHeader(void)
|
||
{
|
||
uint32_t bResult = FENDA_SUCCESS;
|
||
|
||
g_otaCtrlBlock.HeaderInfo.encrypted = 0;
|
||
if(g_ota_head_struct.sour_addr)
|
||
{
|
||
g_otaCtrlBlock.HeaderInfo.fwStartAddr = g_ota_head_struct.sour_addr;
|
||
}
|
||
else
|
||
{
|
||
g_otaCtrlBlock.HeaderInfo.fwStartAddr = 0x28000;//default
|
||
}
|
||
g_otaCtrlBlock.HeaderInfo.fwLength = g_ota_head_struct.file_size+g_ota_head_param.h_len;
|
||
g_otaCtrlBlock.HeaderInfo.fwCrc = g_ota_head_struct.file_crc32;
|
||
g_otaCtrlBlock.HeaderInfo.secInfoLen = g_ota_head_param.h_len;
|
||
g_otaCtrlBlock.HeaderInfo.storageAddr = g_ota_head_struct.dest_addr;
|
||
g_otaCtrlBlock.HeaderInfo.fwDataType = g_ota_head_param.mark;
|
||
if(g_ota_head_struct.dest_cs && (g_ota_head_struct.dest_cs < FW_SOUR_CS_MAX))
|
||
{
|
||
g_otaCtrlBlock.HeaderInfo.storageType = g_ota_head_struct.dest_cs;//config
|
||
}
|
||
else
|
||
{
|
||
g_otaCtrlBlock.HeaderInfo.storageType = FW_SOUR_CS_FLASH;//default
|
||
}
|
||
|
||
static_print_info("============= fw header start ===============\n");
|
||
static_print_info("encrypted = 0x%x\n", g_otaCtrlBlock.HeaderInfo.encrypted);
|
||
//static_print_info("version = 0x%x\n", g_otaCtrlBlock.HeaderInfo.version);
|
||
static_print_info("fwLength = 0x%x\n", g_otaCtrlBlock.HeaderInfo.fwLength);
|
||
static_print_info("fwCrc = 0x%x\n", g_otaCtrlBlock.HeaderInfo.fwCrc);
|
||
static_print_info("fwStartAddr = 0x%x\n", g_otaCtrlBlock.HeaderInfo.fwStartAddr);
|
||
static_print_info("fwDataType = 0x%x\n", g_otaCtrlBlock.HeaderInfo.fwDataType);
|
||
static_print_info("storageType = 0x%x\n", g_otaCtrlBlock.HeaderInfo.storageType);
|
||
static_print_info("storageAddr = 0x%x\n", g_otaCtrlBlock.HeaderInfo.storageAddr);
|
||
static_print_info("fw_size = 0x%x\n",g_ota_head_struct.file_size);
|
||
static_print_info("============= fw header end ===============\n");
|
||
|
||
otaFlashOp.bufferIndex = 0;
|
||
g_otaCtrlBlock.pkt.offset = 0;
|
||
g_otaCtrlBlock.pkt.FileSize = g_otaCtrlBlock.HeaderInfo.fwLength;
|
||
g_otaCtrlBlock.ota_status = OTA_STATE_FW_DATA;
|
||
g_otaCtrlBlock.newFwFlashInfo.offset = 0;
|
||
|
||
// Initialize the flash operation interface and the new firmware storage address
|
||
if ( g_otaCtrlBlock.HeaderInfo.storageType == FW_SOUR_CS_ROM )
|
||
{
|
||
g_pFlash = &g_intFlash;
|
||
// Check to make sure the incoming image will fit in the space allocated for OTA
|
||
if (g_otaCtrlBlock.HeaderInfo.fwLength < AMOTA_INT_FLASH_OTA_MAX_SIZE)
|
||
{
|
||
g_otaCtrlBlock.newFwFlashInfo.addr = g_otaCtrlBlock.HeaderInfo.storageAddr;
|
||
}
|
||
else
|
||
{
|
||
static_print_info("\n??????not enough space. (len = %d)??????\n",g_otaCtrlBlock.HeaderInfo.fwLength);
|
||
bResult = DATA_PACK_SIZE_ERROR;
|
||
}
|
||
}
|
||
else if ( g_otaCtrlBlock.HeaderInfo.storageType == FW_SOUR_CS_FLASH )
|
||
{
|
||
ota_ext_flash_info_init(&g_ext_flash);
|
||
g_pFlash = &g_ext_flash;
|
||
if (g_pFlash->flash_read_page &&
|
||
g_pFlash->flash_write_page &&
|
||
g_pFlash->flash_erase_sector)
|
||
{
|
||
if(g_otaCtrlBlock.HeaderInfo.fwDataType == MARK_MCU_FW_BIN) // is a run image
|
||
{
|
||
if(g_otaCtrlBlock.HeaderInfo.fwLength > MAX_IMAGE_SIZE)
|
||
{
|
||
bResult = DATA_PACK_SIZE_ERROR;
|
||
}
|
||
}
|
||
g_otaCtrlBlock.newFwFlashInfo.addr = g_otaCtrlBlock.HeaderInfo.storageAddr;
|
||
}
|
||
else
|
||
{
|
||
bResult = DEVICE_FORBIT_OTA_ERROR;
|
||
}
|
||
}
|
||
|
||
return bResult;
|
||
}
|
||
|
||
/*!
|
||
* brief: Check whether breakpoint continuation is required.
|
||
*/
|
||
bool_t IfBreakPointValid(void)
|
||
{
|
||
uint32_t BreakPointPtrVal = 0;
|
||
|
||
BreakPointPtrVal = *((uint32_t *)USER_OTA_BREAK_POINT_ADDR);
|
||
static_print_remind("BreakPointPtrVal = %x\n", BreakPointPtrVal);
|
||
if((BreakPointPtrVal != 0xFFFFFFFF) && (BreakPointPtrVal != 0))
|
||
{
|
||
memcpy(&g_otaBreakPoint, (FwBreakPointInfo_t *)USER_OTA_BREAK_POINT_ADDR, sizeof(FwBreakPointInfo_t));
|
||
static_print_remind("g_otaBreakPoint.fileSize = %x,g_otaBreakPoint.fileCrc32 = %x\n",
|
||
g_otaBreakPoint.fileSize, g_otaBreakPoint.fileCrc32);
|
||
if(g_otaBreakPoint.ifResume &&
|
||
g_otaBreakPoint.fileSize == g_otaCtrlBlock.HeaderInfo.fwLength &&
|
||
g_otaBreakPoint.fileCrc32 == g_otaCtrlBlock.HeaderInfo.fwCrc)
|
||
{
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
memset(&g_otaBreakPoint, 0, sizeof(g_otaBreakPoint));
|
||
OtaUpdateBreakPoint();
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
/*!
|
||
* brief: New FW packet handler, for OTA service call
|
||
*/
|
||
uint32_t OtaPacketHandler(uint16_t len, uint8_t *buf)
|
||
{
|
||
uint32_t error_code = FENDA_SUCCESS;
|
||
int ret;
|
||
|
||
switch(g_otaCtrlBlock.ota_status)
|
||
{
|
||
case OTA_STATE_FW_HEADER:
|
||
ret = user_pack_json_head((char *)buf,&g_ota_head_param,&g_ota_head_struct);
|
||
static_print_info("OtaPacketHandler h_len %d = %d - %d - %d - %d- %d\n ",len,g_ota_head_param.h_len,g_ota_head_param.pack_len,g_ota_head_param.ext_offset,g_ota_head_param.struct_len,g_ota_head_param.struct_offset);
|
||
if(ret)
|
||
{
|
||
static_print_info("g_ota_head_struct %d = %d - %x - %x - %x -%x \n",
|
||
g_ota_head_struct.sour_addr,g_ota_head_struct.dest_addr,g_ota_head_struct.file_version[0],g_ota_head_struct.file_version[1],g_ota_head_struct.file_version[2],g_ota_head_struct.file_version[3]);
|
||
#if 1
|
||
//task_ui_notify(UI_MSG_DISPLAY_OPEN, 0, NULL, 0);
|
||
task_ui_notify(EVENT_OTA_TRANS_START, 0, NULL, 0);
|
||
// GoToResouceOTAScreen();
|
||
|
||
error_code = ProcessingFwHeader();
|
||
if(error_code != FENDA_SUCCESS)
|
||
{
|
||
static_print_info("\n ????? DEVICE_FW_OTA_ERROR=%d ????? \n",error_code);
|
||
return error_code;
|
||
}
|
||
|
||
if(IfBreakPointValid())
|
||
{
|
||
static_print_info("read fileOffset from BreakPointInfo = %x\r\n",g_otaBreakPoint.fileOffset);
|
||
g_otaCtrlBlock.pkt.offset = g_otaBreakPoint.fileOffset;
|
||
g_otaCtrlBlock.newFwFlashInfo.offset = g_otaBreakPoint.fileOffset;
|
||
}
|
||
else
|
||
{
|
||
//保存包头 saimen add
|
||
error_code = OtaWrite2Flash(len, buf, g_otaCtrlBlock.newFwFlashInfo.addr + g_otaCtrlBlock.newFwFlashInfo.offset,
|
||
((g_otaCtrlBlock.newFwFlashInfo.offset + len) == g_otaCtrlBlock.HeaderInfo.fwLength));
|
||
if (error_code != FENDA_SUCCESS)
|
||
{
|
||
static_print_info("\n ?????OTA FLASH WRITE ERROR ????? \n");
|
||
return error_code;
|
||
}
|
||
else
|
||
{
|
||
g_otaCtrlBlock.pkt.offset += len;//更新申请数据的地址
|
||
g_otaCtrlBlock.newFwFlashInfo.offset += len;
|
||
}
|
||
}
|
||
|
||
// Length of application firmware
|
||
g_otaCtrlBlock.pkt.ApplyLen = g_otaCtrlBlock.pkt.FileSize - g_otaCtrlBlock.pkt.offset;
|
||
g_otaCtrlBlock.pkt.ApplyLen = g_otaCtrlBlock.pkt.ApplyLen > APPLY_FW_DATA_LEN ? APPLY_FW_DATA_LEN:g_otaCtrlBlock.pkt.ApplyLen;
|
||
/* 因断点续传信息获取,第一包数据在此处申请 */
|
||
DeviceRequestOTAFileData(g_otaCtrlBlock.pkt.offset, g_otaCtrlBlock.pkt.ApplyLen,
|
||
g_otaCtrlBlock.pkt.FileSize, g_otaCtrlBlock.pkt.offset);
|
||
#endif
|
||
}
|
||
break;
|
||
|
||
case OTA_STATE_FW_DATA:
|
||
//static_print_info("ota write2flash len %x addr %x\n",len,
|
||
// g_otaCtrlBlock.newFwFlashInfo.addr + g_otaCtrlBlock.newFwFlashInfo.offset);
|
||
error_code = OtaWrite2Flash(len, buf, g_otaCtrlBlock.newFwFlashInfo.addr + g_otaCtrlBlock.newFwFlashInfo.offset,
|
||
((g_otaCtrlBlock.newFwFlashInfo.offset + len) == g_otaCtrlBlock.HeaderInfo.fwLength));
|
||
if (error_code != FENDA_SUCCESS)
|
||
{
|
||
static_print_info("\n ?????OTA FLASH WRITE ERROR ????? \n");
|
||
return error_code;
|
||
}
|
||
else
|
||
{
|
||
g_otaCtrlBlock.pkt.offset += len;//更新申请数据的地址
|
||
g_otaCtrlBlock.newFwFlashInfo.offset += len;
|
||
}
|
||
if(g_otaCtrlBlock.pkt.offset >= g_otaCtrlBlock.pkt.FileSize)
|
||
{// get the last pkg
|
||
static_print_info("ReceivedSuccess. pkt.offset = %x,\r\n", g_otaCtrlBlock.pkt.offset);
|
||
|
||
g_otaCtrlBlock.crc_verify = OtaVerifyFirmwareCrc();
|
||
g_otaCtrlBlock.ota_status = OTA_STATE_FW_RESET;
|
||
return error_code;
|
||
}
|
||
// Length of application firmware
|
||
g_otaCtrlBlock.pkt.ApplyLen = (g_otaCtrlBlock.pkt.FileSize) - g_otaCtrlBlock.pkt.offset;
|
||
g_otaCtrlBlock.pkt.ApplyLen = g_otaCtrlBlock.pkt.ApplyLen > APPLY_FW_DATA_LEN ? APPLY_FW_DATA_LEN : g_otaCtrlBlock.pkt.ApplyLen;
|
||
|
||
task_ui_notify(EVENT_OTA_TRANSMITTING, (g_otaCtrlBlock.pkt.offset * 100) / g_otaCtrlBlock.pkt.FileSize, NULL, 0);
|
||
|
||
break;
|
||
|
||
case OTA_STATE_FW_VERIFY:
|
||
break;
|
||
|
||
case OTA_STATE_FW_RESET:
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return error_code;
|
||
}
|
||
|
||
/*!
|
||
* updata user boot --saimen
|
||
*/
|
||
void ota_user_boot (void)
|
||
{
|
||
uint32_t ui32_crc;
|
||
uint8_t rw_boot_times = 3;
|
||
static uint32_t boot_run_addr = 0x00018000;
|
||
uint32_t r_boot_addr = 0;
|
||
uint32_t w_boot_addr = 0;
|
||
uint32_t rw_boot_len = 0;
|
||
uint32_t op_len = 0;
|
||
uint8_t *p_boot_data = otaFlashOp.writeBuffer;
|
||
|
||
if(g_otaCtrlBlock.HeaderInfo.fwStartAddr == boot_run_addr && g_otaCtrlBlock.HeaderInfo.storageType == FW_SOUR_CS_FLASH)//user boot addr
|
||
{
|
||
while(rw_boot_times--)
|
||
{
|
||
r_boot_addr = g_otaCtrlBlock.HeaderInfo.storageAddr + g_otaCtrlBlock.HeaderInfo.secInfoLen;
|
||
w_boot_addr = boot_run_addr;
|
||
ui32_crc = 0;
|
||
for(rw_boot_len = g_otaCtrlBlock.HeaderInfo.secInfoLen;rw_boot_len<g_otaCtrlBlock.HeaderInfo.fwLength;)
|
||
{
|
||
op_len = ((g_otaCtrlBlock.HeaderInfo.fwLength - rw_boot_len) > MCU_ROM_PAGE_SIZE)? MCU_ROM_PAGE_SIZE:(g_otaCtrlBlock.HeaderInfo.fwLength - rw_boot_len);
|
||
g_pFlash->flash_read_page(r_boot_addr, (uint32_t *)p_boot_data, op_len);
|
||
rom_api_erase(w_boot_addr);
|
||
rom_api_write(w_boot_addr, p_boot_data, op_len);
|
||
r_boot_addr += op_len;
|
||
w_boot_addr += op_len;
|
||
rw_boot_len += op_len;
|
||
static_print_remind("r_boot_addr=0x%x,w_boot_addr=0x%x,op_len=0x%x\n",r_boot_addr,w_boot_addr,op_len);
|
||
}
|
||
ui32_crc = crc32_ex(ui32_crc, (uint8_t *)boot_run_addr, g_otaCtrlBlock.HeaderInfo.fwLength - g_otaCtrlBlock.HeaderInfo.secInfoLen);
|
||
if(ui32_crc == g_otaCtrlBlock.HeaderInfo.fwCrc)
|
||
{
|
||
break;
|
||
}
|
||
static_print_remind("error:obj_crc=0x%x,temp_crc=0x%x\n",g_otaCtrlBlock.HeaderInfo.fwCrc,ui32_crc);
|
||
}
|
||
}
|
||
}
|
||
/*!
|
||
* brief: Update Flag Page with Firmware Information, for OTA service call.
|
||
*/
|
||
void OtaUpdateFwInfo(void)
|
||
{
|
||
uint32_t ui32CRC = 0;
|
||
uint32_t otaPtrPageAddr = (USER_BOOTLOADER_MBR_ADDR & ~(AM_HAL_FLASH_PAGE_SIZE - 1));
|
||
|
||
g_boot_mbr_info.carry_fw_flag = 0x10;
|
||
g_boot_mbr_info.formal.fw_sour_addr = (g_otaCtrlBlock.newFwFlashInfo.addr + g_otaCtrlBlock.HeaderInfo.secInfoLen);
|
||
g_boot_mbr_info.formal.fw_dest_addr = g_otaCtrlBlock.HeaderInfo.fwStartAddr;
|
||
g_boot_mbr_info.formal.fw_sour_cs = g_otaCtrlBlock.HeaderInfo.storageType;
|
||
g_boot_mbr_info.formal.fw_dest_cs = FW_SOUR_CS_ROM;
|
||
//g_boot_mbr_info.formal.fw_reserve1 = ;
|
||
g_boot_mbr_info.formal.fw_bytes = g_otaCtrlBlock.HeaderInfo.fwLength -g_otaCtrlBlock.HeaderInfo.secInfoLen;
|
||
g_boot_mbr_info.formal.fw_crc32 = g_otaCtrlBlock.HeaderInfo.fwCrc;
|
||
|
||
ui32CRC = 0;
|
||
ui32CRC = crc32_ex(ui32CRC, (uint8_t *)&g_boot_mbr_info, sizeof(g_boot_mbr_info) - 4);
|
||
g_boot_mbr_info.crc32 = ui32CRC;
|
||
|
||
static_print_remind("*****************************************************\n");
|
||
static_print_remind("OtaUpdateFwInfo()\n");
|
||
static_print_remind("carry_fw_flag=0x%x\n", g_boot_mbr_info.carry_fw_flag);
|
||
static_print_remind("fw_sour_addr=0x%x\n", g_boot_mbr_info.formal.fw_sour_addr);
|
||
static_print_remind("fw_dest_addr=0x%x\n", g_boot_mbr_info.formal.fw_dest_addr);
|
||
static_print_remind("fw_sour_cs=0x%x\n", g_boot_mbr_info.formal.fw_sour_cs);
|
||
static_print_remind("fw_dest_cs=0x%x\n", g_boot_mbr_info.formal.fw_dest_cs);
|
||
static_print_remind("fw_reserve1=0x%x\n", g_boot_mbr_info.formal.fw_reserve1);
|
||
static_print_remind("fw_bytes=0x%x\n", g_boot_mbr_info.formal.fw_bytes);
|
||
static_print_remind("fw_crc32=0x%x\n", g_boot_mbr_info.formal.fw_crc32);
|
||
static_print_remind("MBR CRC=0x%x\n",g_boot_mbr_info.crc32);
|
||
static_print_remind("*****************************************************\n");
|
||
|
||
|
||
// Copy the OTA descriptor
|
||
memcpy(otaFlashOp.writeBuffer, &g_boot_mbr_info, sizeof(g_boot_mbr_info));
|
||
|
||
// Write the flash Page
|
||
if(g_otaCtrlBlock.HeaderInfo.fwStartAddr < 0x28000)
|
||
{
|
||
//saimen add
|
||
static_print_remind("warning:boot ota addr=0x%x--size=%d--crc=0x%x\n",
|
||
g_otaCtrlBlock.HeaderInfo.fwStartAddr,g_otaCtrlBlock.HeaderInfo.fwLength,g_otaCtrlBlock.HeaderInfo.fwCrc);
|
||
ota_user_boot();
|
||
}
|
||
else
|
||
{
|
||
am_bootloader_program_flash_page(otaPtrPageAddr, (uint32_t *)otaFlashOp.writeBuffer, AMOTAS_TEMP_BUFSIZE);
|
||
}
|
||
}
|
||
|
||
/*!
|
||
* brief: Update Flag Page with Break Point Information .
|
||
*/
|
||
void OtaUpdateBreakPoint(void)
|
||
{
|
||
uint32_t BreakPointPtrPageAddr = (USER_OTA_BREAK_POINT_ADDR & ~(AM_HAL_FLASH_PAGE_SIZE - 1));
|
||
uint32_t otaPtrOffset = USER_OTA_BREAK_POINT_ADDR - BreakPointPtrPageAddr;
|
||
|
||
memcpy(otaFlashOp.writeBuffer, (uint8_t *)BreakPointPtrPageAddr, AM_HAL_FLASH_PAGE_SIZE);
|
||
static_print_remind("addr = %x, off = %x\r\n", BreakPointPtrPageAddr, otaPtrOffset);
|
||
|
||
memcpy(&otaFlashOp.writeBuffer[otaPtrOffset], (uint8_t *)&g_otaBreakPoint, sizeof(g_otaBreakPoint));
|
||
|
||
am_bootloader_program_flash_page(BreakPointPtrPageAddr, (uint32_t *)otaFlashOp.writeBuffer, AM_HAL_FLASH_PAGE_SIZE);
|
||
}
|
||
|
||
|