Optimize OTA information structure and flash_write function

This commit is contained in:
wgzAIIT 2023-04-23 16:33:22 +08:00
parent 6074b2b147
commit cfadebc3e8
4 changed files with 118 additions and 107 deletions

View File

@ -369,17 +369,35 @@ struct InitSequenceDesc _board_init[] =
#ifdef BSP_USING_OTA
static void OtaCmd(void)
{
int32_t Size;
int32_t size;
ota_info_t ota_info;
FLASH_Init();
UartConfig();
UpdateOTAStatus(OTA_STATUS_DOWNLOADING);
Size = SerialDownload(DOWN_FLAH_ADDRESS);
UpdateOTAStatus(OTA_STATUS_DOWNLOADED);
if(Size > 0)
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
ota_info.status = OTA_STATUS_DOWNLOADING;
UpdateOTAFlag(&ota_info);
size = SerialDownload(DOWN_FLAH_ADDRESS);
ota_info.status = OTA_STATUS_DOWNLOADED;
UpdateOTAFlag(&ota_info);
if(size > 0)
{
UpdateOTAFlag(Size, 0x11223344, OTA_STATUS_READY, "OTA Test!","No error!");
ota_info.down.size = size;
ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, size);
ota_info.down.version = 0x11223344;
strncpy(ota_info.down.description, "OTA Test!",sizeof(ota_info.down.description));
ota_info.status = OTA_STATUS_READY;
strncpy(ota_info.error_message, "Download the firmware to the download partition successfully!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
else
{
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Failed to download firmware to download partition!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
FLASH_DeInit();
__set_FAULTMASK(1);
@ -437,4 +455,10 @@ void InitBoardHardware()
}
KPrintf("board init done.\n");
KPrintf("start kernel...\n");
#ifdef BSP_USING_OTA
FLASH_Init();
//跳转成功将对应跳转失败标志清零
FLASH_DeInit();
#endif
}

View File

@ -684,7 +684,7 @@ status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len)
* : Flash指定长度的空间
* : addr:
byte_cnt:,4k字节为最小擦除单位
* : None
* : kStatus_Success
* : 4k字节的4k字节
*******************************************************************************/
status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt)
@ -708,16 +708,30 @@ status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt)
/*******************************************************************************
* : flash_write
* : FLASH_WritePage功能相同Flash一个页
* : flash起始地址写入指定长度的数据
* : addr:
buf:
len:(256)
byte_cnt:
* : kStatus_Success
* : 256
*******************************************************************************/
status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt)
{
return FLASH_WritePage(start_addr, (void *)buf, byte_cnt);
uint32_t size;
status_t status;
while(byte_cnt > 0)
{
size = byte_cnt > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE : byte_cnt;
status = FLASH_WritePage(start_addr, (void *)buf, size);
if(status != kStatus_Success)
{
return status;
}
start_addr += size;
buf += size;
byte_cnt -= size;
}
return kStatus_Success;
}

View File

@ -100,7 +100,7 @@ static const uint32_t crc32tab[] = {
len:CRC32的数据长度
* : CRC32值
*******************************************************************************/
static uint32_t calculate_crc32(uint32_t addr, uint32_t len)
uint32_t calculate_crc32(uint32_t addr, uint32_t len)
{
uint32_t crc = 0xFFFFFFFF;
uint8_t byte = 0xFF;
@ -114,52 +114,26 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len)
}
/*******************************************************************************
* : UpdateOTAStatus
* : OTA的状态信息
* : status:
* :
*******************************************************************************/
void UpdateOTAStatus(ota_status_t status)
{
ota_info_t ota_info;
//从Flash中读取OTA信息
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
ota_info.status = status;
flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
flash_write(FLAG_FLAH_ADDRESS,(void *)&ota_info,sizeof(ota_info_t));
}
/*******************************************************************************
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : app_size:,
version:
status:OTA的状态信息
description:
error_message:
* :
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
*******************************************************************************/
void UpdateOTAFlag(uint32_t app_size, uint32_t version, uint32_t status, uint8_t* description, uint8_t* error_message)
status_t UpdateOTAFlag(ota_info_t *ptr)
{
ota_info_t ota_info; // 定义OTA信息结构体
status_t status;
// 从Flash中读取OTA信息
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
ota_info.app_size = app_size;
ota_info.crc = calculate_crc32(DOWN_FLAH_ADDRESS, app_size);
ota_info.version = version;
strncpy(ota_info.description, description,sizeof(ota_info.description));
ota_info.status = status;
strncpy(ota_info.error_message, error_message,sizeof(ota_info.error_message));
status = flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
if(status != kStatus_Success)
{
return status;
}
status = flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t));
flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
flash_write(FLAG_FLAH_ADDRESS,(void *)&ota_info,sizeof(ota_info_t));
return status;
}
/*******************************************************************************
* : UpdateApplication
* : bootloader里进行调用,Flash中Flag分区中的信息决定是否进行版本更新
@ -179,61 +153,44 @@ void UpdateApplication(void)
if(ota_info.status == OTA_STATUS_READY)
{
Serial_PutString("\r\n------Start to update the app!------\r\n");
// 校验固件CRC
if(calculate_crc32(DOWN_FLAH_ADDRESS, ota_info.app_size) == ota_info.crc)
// 校验downlad分区固件CRC
if(calculate_crc32(DOWN_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32)
{
// 如果CRC校验通过,开始升级,逐字节搬移
UpdateOTAStatus(OTA_STATUS_UPDATING);
status = flash_copy(XIUOS_FLAH_ADDRESS,BAKUP_FLAH_ADDRESS,ota_info.app_size);
if(status != kStatus_Success)
ota_info.status = OTA_STATUS_UPDATING;
UpdateOTAFlag(&ota_info);
// 拷贝download分区到XiUOS System分区
status = flash_copy(DOWN_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.down.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32))
{
Serial_PutString("------Backup app failed!------\r\n");
goto finish;
Serial_PutString("\r\n------The download partition is copied successfully!------\r\n");
ota_info.os.size = ota_info.down.size;
ota_info.os.crc32 = ota_info.down.crc32;
ota_info.os.version = ota_info.down.version;
strncpy(ota_info.os.description, ota_info.down.description, sizeof(ota_info.down.description));
ota_info.status == OTA_STATUS_IDLE; // 拷贝download分区到XiUOS System分区成功,将OTA升级状态设置为IDLE
UpdateOTAFlag(&ota_info);
}
status = flash_copy(DOWN_FLAH_ADDRESS,XIUOS_FLAH_ADDRESS,ota_info.app_size);
if(status != kStatus_Success)
else
{
Serial_PutString("------Firmware partition copy failed!------\r\n");
Serial_PutString("\r\n------The download partition copy failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "The download partition copy failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
goto finish;
}
// 校验搬移后的固件CRC
if(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.app_size) == ota_info.crc)
{
ota_info.status = OTA_STATUS_IDLE; // 将OTA升级状态设置为IDLE
memset(ota_info.error_message,0,sizeof(ota_info.error_message)); // 清空错误信息
// 将更新后的OTA信息写入Flash中
flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
flash_write(FLAG_FLAH_ADDRESS,(void *)&ota_info,sizeof(ota_info_t));
Serial_PutString("\r\n------Update completed!------\r\n");
goto finish;
}
else
{
// 如果搬移后的固件CRC校验失败升级失败
ota_info.status = OTA_STATUS_ERROR; // 将OTA升级状态设置为ERROR
memset(ota_info.error_message,0,sizeof(ota_info.error_message));
snprintf((char *)ota_info.error_message, sizeof(ota_info.error_message), "APP Firmware CRC check failed!"); // 记录错误信息
// 将更新后的OTA信息写入Flash中
flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
flash_write(FLAG_FLAH_ADDRESS,(void *)&ota_info,sizeof(ota_info_t));
Serial_PutString("\r\n------APP Firmware CRC check failed!------\r\n");
goto finish;
}
Serial_PutString("\r\n------Update completed!------\r\n");
goto finish;
}
else
{
// 如果CRC校验失败升级失败
ota_info.status = OTA_STATUS_ERROR; // 将OTA升级状态设置为ERROR
memset(ota_info.error_message,0,sizeof(ota_info.error_message));
snprintf((char *)ota_info.error_message, sizeof(ota_info.error_message), "Download Firmware CRC check failed"); // 记录错误信息
// 将更新后的OTA信息写入Flash中
flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
flash_write(FLAG_FLAH_ADDRESS,(void *)&ota_info,sizeof(ota_info_t));
// 如果download分区CRC校验失败升级失败
Serial_PutString("\r\n------Download Firmware CRC check failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Download Firmware CRC check failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
goto finish;
}
}

View File

@ -26,27 +26,43 @@
#include "flash.h"
#include "ymodem.h"
/* OTA升级过程中的状态描述 */
typedef enum {
OTA_STATUS_IDLE = 0, // 空闲状态没有进行OTA升级
OTA_STATUS_READY, // 准备状态可以进行OTA升级
OTA_STATUS_DOWNLOADING, // 正在下载固件
OTA_STATUS_DOWNLOADED, // 固件下载完成,可以进行升级
OTA_STATUS_UPDATING, // 正在进行OTA升级
OTA_STATUS_ERROR, // 出现错误,升级失败
OTA_STATUS_IDLE = 0, // 空闲状态没有进行OTA升级
OTA_STATUS_READY, // 准备状态可以进行OTA升级
OTA_STATUS_DOWNLOADING, // 正在下载固件
OTA_STATUS_DOWNLOADED, // 固件下载完成,可以进行升级
OTA_STATUS_UPDATING, // 正在进行OTA升级
OTA_STATUS_ERROR, // 出现错误,升级失败
} ota_status_t;
/* Flash分区中保存固件的属性描述 */
typedef struct {
uint32_t app_size; // 应用程序大小
uint32_t crc; // 应用程序CRC校验值
uint32_t version; // 应用程序版本号
uint32_t status; // 升级状态
uint8_t description[64]; // 应用程序升级说明最多64个字符
uint8_t error_message[64]; // 错误信息最多64个字符
uint32_t size; // 应用程序大小,记录分区固件的大小
uint32_t crc32; // 应用程序CRC32校验值,记录分区固件的crc32值
uint32_t version; // 应用程序版本号,记录分区固件的版本号
uint32_t reserve; // 保留字段
uint8_t description[128]; // 固件的描述信息,最多128个字符
} firmware_t;
/* OTA升级过程中的信息结构体 */
typedef struct {
firmware_t os; // XiUOS System分区属性信息
firmware_t bak; // Bakup分区属性信息
firmware_t down; // Download分区属性信息
uint32_t status; // 升级状态,取值来自于ota_status_t类型
uint32_t initversion; // 恢复出厂设置的标志,0xFFFFFFFF代表未烧写过,烧写过以后设置为0x12345678
uint32_t jumpfailed; // bootloaer跳转失败的标志,bootloader里置0xabababab,跳转成功后置0x00000000
uint32_t reserve; // 保留字段
uint8_t error_message[128]; // 错误信息,最多128个字符
} ota_info_t;
void UpdateOTAStatus(ota_status_t status);
void UpdateOTAFlag(uint32_t app_size, uint32_t version, uint32_t status, uint8_t* description, uint8_t* error_message);
uint32_t calculate_crc32(uint32_t addr, uint32_t len);
status_t UpdateOTAFlag(ota_info_t *ptr);
void UpdateApplication(void);
#endif