forked from xuos/xiuos
Optimize OTA information structure and flash_write function
This commit is contained in:
parent
6074b2b147
commit
cfadebc3e8
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue