Optimize ota function

This commit is contained in:
wgzAIIT 2023-06-15 16:43:02 +08:00
parent 26f74120db
commit ed1c5eea1f
2 changed files with 218 additions and 202 deletions

View File

@ -14,9 +14,27 @@ menu "OTA function"
config MCUBOOT_APPLICATION
bool "Config as application."
endchoice
if MCUBOOT_APPLICATION
menu "The way of OTA firmware upgrade."
config OTA_BY_IAP
bool "Through serial port IAP."
default y
config OTA_BY_TCPSERVER
bool "Through the public network TCP server."
default n
select SUPPORT_CONNECTION_FRAMEWORK
select CONNECTION_ADAPTER_4G
endchoice
config OTA_BY_PLATFORM
bool "Through IoT management platform."
default n
select SUPPORT_CONNECTION_FRAMEWORK
select CONNECTION_ADAPTER_4G
endmenu
endif
menu "Flash area address and size configuration."

View File

@ -33,20 +33,12 @@
* Private Function Prototypes
****************************************************************************/
static uint32_t calculate_crc32(uint32_t addr, uint32_t len);
static uint16_t calculate_crc16(uint8_t * data, uint32_t len);
static void UpdateNewApplication(void);
static status_t UpdateOTAFlag(ota_info_t *ptr);
static void InitialVersion(void);
static void BackupVersion(void);
static void BootLoaderJumpApp(void);
static status_t UpdateOTAFlag(ota_info_t *ptr);
static void app_ota_by_iap(void);
static void UpdateNewApplication(void);
static void Update(void);
#ifdef CONNECTION_ADAPTER_4G
static void get_start_signal(struct Adapter* adapter);
static int ota_data_recv(struct Adapter* adapter);
static void app_ota_by_4g(void);
#endif
static void BootLoaderJumpApp(void);
/****************************************************************************
* Private Data
@ -67,8 +59,6 @@ static const mcuboot_t mcuboot =
mcuboot_jump,
mcuboot_delay
};
static const uint32_t crc32tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
@ -104,10 +94,6 @@ static const uint32_t crc32tab[] = {
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#ifdef CONNECTION_ADAPTER_4G
static ota_data start_msg;
static ota_data recv_msg;
#endif
/*******************************************************************************
* : calculate_crc32
@ -131,28 +117,83 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len)
/*******************************************************************************
* : calculate_crc16
* : crc16的值,OTA传输过程中数据帧的校验
* : data:buffer
len:CRC16的数据长度
* : CRC16值
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
*******************************************************************************/
static uint16_t calculate_crc16(uint8_t * data, uint32_t len)
static status_t UpdateOTAFlag(ota_info_t *ptr)
{
uint16_t reg_crc=0xFFFF;
while(len--)
status_t status;
status = mcuboot.op_flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
if(status != kStatus_Success)
{
reg_crc ^= *data++;
for(int j=0;j<8;j++)
{
if(reg_crc & 0x01)
reg_crc=reg_crc >>1 ^ 0xA001;
else
reg_crc=reg_crc >>1;
}
return status;
}
status = mcuboot.op_flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t));
return status;
}
/*******************************************************************************
* : InitialVersion
* : APP分区的初始化版本,0x1
* :
* :
*******************************************************************************/
static void InitialVersion(void)
{
int32_t size;
ota_info_t ota_info;
memset(&ota_info, 0, sizeof(ota_info_t));
size = mcuboot.download_by_serial(XIUOS_FLAH_ADDRESS);
if(size > 0)
{
ota_info.os.size = size;
ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size);
ota_info.os.version = 0x1;
strncpy(ota_info.os.description, "The initial firmware.", sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);
}
}
/*******************************************************************************
* : BackupVersion
* : 退,APP存在bug导致无法跳转需调用此函数进行版本回退
* :
* :
*******************************************************************************/
static void BackupVersion(void)
{
status_t status;
ota_info_t ota_info;
memset(&ota_info, 0, sizeof(ota_info_t));
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.status = OTA_STATUS_BACKUP;
UpdateOTAFlag(&ota_info);
status = mcuboot.op_flash_copy(BAKUP_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.bak.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.bak.size) == ota_info.bak.crc32))
{
mcuboot.print_string("\r\n------Backup app version success!------\r\n");
ota_info.os.size = ota_info.bak.size;
ota_info.os.crc32 = ota_info.bak.crc32;
ota_info.os.version = ota_info.bak.version;
strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description));
UpdateOTAFlag(&ota_info);
}
else
{
mcuboot.print_string("\r\n------Backup app version failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Backup app version failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
KPrintf("crc = [0x%x]\n",reg_crc);
return reg_crc;
}
@ -248,62 +289,28 @@ finish:
/*******************************************************************************
* : InitialVersion
* : APP分区的初始化版本,0x1
* : Update
* :
* :
* :
*******************************************************************************/
static void InitialVersion(void)
static void Update(void)
{
int32_t size;
ota_info_t ota_info;
memset(&ota_info, 0, sizeof(ota_info_t));
size = mcuboot.download_by_serial(XIUOS_FLAH_ADDRESS);
if(size > 0)
{
ota_info.os.size = size;
ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size);
ota_info.os.version = 0x1;
strncpy(ota_info.os.description, "The initial firmware.", sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);
}
}
/*******************************************************************************
* : BackupVersion
* : 退,APP存在bug导致无法跳转需调用此函数进行版本回退
* :
* :
*******************************************************************************/
static void BackupVersion(void)
{
status_t status;
ota_info_t ota_info;
mcuboot.flash_init();
memset(&ota_info, 0, sizeof(ota_info_t));
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.status = OTA_STATUS_BACKUP;
UpdateOTAFlag(&ota_info);
status = mcuboot.op_flash_copy(BAKUP_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.bak.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.bak.size) == ota_info.bak.crc32))
/* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */
if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32))
{
mcuboot.print_string("\r\n------Backup app version success!------\r\n");
ota_info.os.size = ota_info.bak.size;
ota_info.os.crc32 = ota_info.bak.crc32;
ota_info.os.version = ota_info.bak.version;
strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description));
UpdateOTAFlag(&ota_info);
mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n");
InitialVersion();
}
else
{
mcuboot.print_string("\r\n------Backup app version failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Backup app version failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
UpdateNewApplication();
}
mcuboot.flash_deinit();
}
@ -336,27 +343,7 @@ static void BootLoaderJumpApp(void)
}
/*******************************************************************************
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
*******************************************************************************/
static status_t UpdateOTAFlag(ota_info_t *ptr)
{
status_t status;
status = mcuboot.op_flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
if(status != kStatus_Success)
{
return status;
}
status = mcuboot.op_flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t));
return status;
}
#ifdef OTA_BY_IAP
/*********************************************************************************
* : app_ota_by_iap
* : ota升级,,iap方式传输bin文件
@ -397,118 +384,42 @@ static void app_ota_by_iap(void)
mcuboot.op_reset();
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),iap, app_ota_by_iap, ota by iap function);
#endif
#ifdef OTA_BY_TCPSERVER
static uint16_t calculate_crc16(uint8_t * data, uint32_t len);
static void get_start_signal(struct Adapter* adapter);
static int ota_data_recv(struct Adapter* adapter);
static ota_data start_msg;
static ota_data recv_msg;
/*******************************************************************************
* : app_clear_jumpflag
* : app成功后,app中调用将lastjumpflag重置为0XCDCDCDCD
* :
* :
* : calculate_crc16
* : crc16的值,OTA传输过程中数据帧的校验
* : data:buffer
len:CRC16的数据长度
* : CRC16值
*******************************************************************************/
void app_clear_jumpflag(void)
static uint16_t calculate_crc16(uint8_t * data, uint32_t len)
{
ota_info_t ota_info;
mcuboot.flash_init();
//跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG
memset(&ota_info, 0, sizeof(ota_info_t));
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.lastjumpflag = JUMP_SUCCESS_FLAG;
UpdateOTAFlag(&ota_info);
mcuboot.flash_deinit();
}
/*******************************************************************************
* : Update
* :
* :
* :
*******************************************************************************/
static void Update(void)
{
ota_info_t ota_info;
mcuboot.flash_init();
memset(&ota_info, 0, sizeof(ota_info_t));
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
/* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */
if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32))
uint16_t reg_crc=0xFFFF;
while(len--)
{
mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n");
InitialVersion();
}
else
{
UpdateNewApplication();
}
mcuboot.flash_deinit();
}
/*******************************************************************************
* : ota_entry
* : bootloader的入口函数
* :
* :
*******************************************************************************/
void ota_entry(void)
{
uint8_t ch1, ch2;
uint32_t ret;
uint32_t timeout = 1000;
mcuboot.board_init();
mcuboot.print_string("Please press 'space' key into menu in 10s !!!\r\n");
while(timeout)
{
ret = (SerialKeyPressed((uint8_t*)&ch1));
if(ret) break;
timeout--;
mcuboot.op_delay(10);
}
while(1)
{
if((ret)&&(ch1 == 0x20))
reg_crc ^= *data++;
for(int j=0;j<8;j++)
{
mcuboot.print_string("\r\nPlease slecet:");
mcuboot.print_string("\r\n 1:run app");
mcuboot.print_string("\r\n 2:update app");
mcuboot.print_string("\r\n 3:reboot \r\n");
ch2 = GetKey();
switch(ch2)
{
case 0x31:
BootLoaderJumpApp();
break;
case 0x32:
Update();
BootLoaderJumpApp();
break;
case 0x33:
mcuboot.op_reset();
default:
break;
}
if(reg_crc & 0x01)
reg_crc=reg_crc >>1 ^ 0xA001;
else
reg_crc=reg_crc >>1;
}
//10s内不按下空格键默然进行升级,升级完成后跳转
else
{
Update();
BootLoaderJumpApp();
}
}
KPrintf("crc = [0x%x]\n",reg_crc);
return reg_crc;
}
#ifdef CONNECTION_ADAPTER_4G
/*******************************************************************************
* : get_start_signal
* : 4G方式从服务端接收开始信号
@ -727,4 +638,91 @@ static void app_ota_by_4g(void)
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota_by_4g, ota by 4g function);
#endif
#endif
#ifdef OTA_BY_PLATFORM
#endif
/*******************************************************************************
* : app_clear_jumpflag
* : app成功后,app中调用将lastjumpflag重置为0XCDCDCDCD
* :
* :
*******************************************************************************/
void app_clear_jumpflag(void)
{
ota_info_t ota_info;
mcuboot.flash_init();
//跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG
memset(&ota_info, 0, sizeof(ota_info_t));
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.lastjumpflag = JUMP_SUCCESS_FLAG;
UpdateOTAFlag(&ota_info);
mcuboot.flash_deinit();
}
/*******************************************************************************
* : ota_entry
* : bootloader的入口函数
* :
* :
*******************************************************************************/
void ota_entry(void)
{
uint8_t ch1, ch2;
uint32_t ret;
uint32_t timeout = 1000;
mcuboot.board_init();
mcuboot.print_string("Please press 'space' key into menu in 10s !!!\r\n");
while(timeout)
{
ret = (SerialKeyPressed((uint8_t*)&ch1));
if(ret) break;
timeout--;
mcuboot.op_delay(10);
}
while(1)
{
if((ret)&&(ch1 == 0x20))
{
mcuboot.print_string("\r\nPlease slecet:");
mcuboot.print_string("\r\n 1:run app");
mcuboot.print_string("\r\n 2:update app");
mcuboot.print_string("\r\n 3:reboot \r\n");
ch2 = GetKey();
switch(ch2)
{
case 0x31:
BootLoaderJumpApp();
break;
case 0x32:
Update();
BootLoaderJumpApp();
break;
case 0x33:
mcuboot.op_reset();
default:
break;
}
}
//10s内不按下空格键默然进行升级,升级完成后跳转
else
{
Update();
BootLoaderJumpApp();
}
}
}