Add version rollback function for OTA

This commit is contained in:
huang 2023-05-04 10:16:09 +08:00 committed by wgzAIIT
parent 84f78b6435
commit 0ecb29c887
5 changed files with 243 additions and 187 deletions

View File

@ -459,6 +459,10 @@ void InitBoardHardware()
#ifdef BSP_USING_OTA
FLASH_Init();
//跳转成功将对应跳转失败标志清零
ota_info_t ota_info;
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
ota_info.lastjumpflag=0x00000000;
UpdateOTAFlag(&ota_info);
FLASH_DeInit();
#endif
}

View File

@ -58,11 +58,11 @@ static const lookuptable_t FlashLookupTable={
/*******************************************************************************
* : Flexspi_Nor_Wait_Busy
* : FlexSPI NOR Flash忙碌状态结束
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
* : Flexspi_Nor_Wait_Busy
* : FlexSPI NOR Flash忙碌状态结束
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
*******************************************************************************/
static status_t Flexspi_Nor_Wait_Busy(uint32_t instance, uint32_t baseAddr)
{
@ -101,11 +101,11 @@ static status_t Flexspi_Nor_Wait_Busy(uint32_t instance, uint32_t baseAddr)
/*******************************************************************************
* : Flexspi_Nor_Write_Enable
* : 使 FlexSPI NOR Flash的写入操作
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
* : Flexspi_Nor_Write_Enable
* : 使 FlexSPI NOR Flash的写入操作
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
*******************************************************************************/
static status_t Flexspi_Nor_Write_Enable(uint32_t instance, uint32_t baseAddr)
{
@ -125,12 +125,12 @@ static status_t Flexspi_Nor_Write_Enable(uint32_t instance, uint32_t baseAddr)
/*******************************************************************************
* : flexspi_clock_config
* : FlexSPI模块的时钟
* : instance:FlexSPI实例号
freq:FlexSPI时钟频率
sampleClkMode:FlexSPI时钟的采样时钟模式,SDR或DDR模式
* : kStatus_Success
* : flexspi_clock_config
* : FlexSPI模块的时钟
* : instance:FlexSPI实例号
freq:FlexSPI时钟频率
sampleClkMode:FlexSPI时钟的采样时钟模式,SDR或DDR模式
* : kStatus_Success
*******************************************************************************/
static void flexspi_clock_config(uint32_t instance, uint32_t freq, uint32_t sampleClkMode)
{
@ -210,10 +210,10 @@ static void flexspi_clock_config(uint32_t instance, uint32_t freq, uint32_t samp
/*******************************************************************************
* : flexspi_clock_gate_enable
* : FlexSPI模块的时钟门控
* :
* :
* : flexspi_clock_gate_enable
* : FlexSPI模块的时钟门控
* :
* :
*******************************************************************************/
static void flexspi_clock_gate_enable(void)
{
@ -222,10 +222,10 @@ static void flexspi_clock_gate_enable(void)
/*******************************************************************************
* : flexspi_clock_gate_disable
* : FlexSPI模块的时钟门控
* :
* :
* : flexspi_clock_gate_disable
* : FlexSPI模块的时钟门控
* :
* :
*******************************************************************************/
static void flexspi_clock_gate_disable(void)
{
@ -234,12 +234,12 @@ static void flexspi_clock_gate_disable(void)
/*******************************************************************************
* : flexspi_get_clock
* : FlexSPI时钟频率
* : instance:FlexSPI实例号
type:
freq:
* : kStatus_Success
* : flexspi_get_clock
* : FlexSPI时钟频率
* : instance:FlexSPI实例号
type:
freq:
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_get_clock(uint32_t instance, flexspi_clock_type_t type, uint32_t *freq)
{
@ -291,13 +291,13 @@ static status_t flexspi_get_clock(uint32_t instance, flexspi_clock_type_t type,
/*******************************************************************************
* : flexspi_get_ticks
* : FlexSPI时钟周期数
* : ticks:
intervalNs:ns
freq:FlexSPI时钟频率MHz
unit:,,ns为单位
* : kStatus_Success
* : flexspi_get_ticks
* : FlexSPI时钟周期数
* : ticks:
intervalNs:ns
freq:FlexSPI时钟频率MHz
unit:,,ns为单位
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_get_ticks(uint32_t *ticks, uint32_t intervalNs, uint32_t freq, uint32_t unit)
{
@ -330,11 +330,11 @@ static status_t flexspi_get_ticks(uint32_t *ticks, uint32_t intervalNs, uint32_t
/*******************************************************************************
* : flexspi_configure_dll
* : FLEXSPI存储器的DLL()
* : instance:FLEXSPI实例号
config:
* : kStatus_Success
* : flexspi_configure_dll
* : FLEXSPI存储器的DLL()
* : instance:FLEXSPI实例号
config:
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_configure_dll(uint32_t instance, flexspi_mem_config_t *config)
{
@ -473,11 +473,11 @@ static status_t flexspi_configure_dll(uint32_t instance, flexspi_mem_config_t *c
/*******************************************************************************
* : flexspi_config_mcr1
* : FlexSPI模块的MCR1寄存器
* : instance:FLEXSPI实例号
onfig指向FlexSPI存储器配置结构体的指针
* : kStatus_Success
* : flexspi_config_mcr1
* : FlexSPI模块的MCR1寄存器
* : instance:FLEXSPI实例号
onfig指向FlexSPI存储器配置结构体的指针
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_config_mcr1(uint32_t instance, flexspi_mem_config_t *config)
{
@ -513,10 +513,10 @@ static status_t flexspi_config_mcr1(uint32_t instance, flexspi_mem_config_t *con
/*******************************************************************************
* : FLASH_GetSectorSize
* :
* :
* : ,HYPER FLASH为64K字节,NOR FLASH为4K字节
* : FLASH_GetSectorSize
* :
* :
* : ,HYPER FLASH为64K字节,NOR FLASH为4K字节
*******************************************************************************/
uint32_t FLASH_GetSectorSize(void)
{
@ -529,10 +529,10 @@ uint32_t FLASH_GetSectorSize(void)
/*******************************************************************************
* : FLASH_GetProgramCmd
* :
* :
* : ,HYPER FLASH为512字节,NOR FLASH为256字节
* : FLASH_GetProgramCmd
* :
* :
* : ,HYPER FLASH为512字节,NOR FLASH为256字节
*******************************************************************************/
uint32_t FLASH_GetProgramCmd(void)
{
@ -548,10 +548,10 @@ uint32_t FLASH_GetProgramCmd(void)
/*******************************************************************************
* : FLASH_Init
* : Flash接口初始化,Flash相关操作前进行调用
* :
* :
* : FLASH_Init
* : Flash接口初始化,Flash相关操作前进行调用
* :
* :
*******************************************************************************/
void FLASH_Init(void)
{
@ -567,10 +567,10 @@ void FLASH_Init(void)
/*******************************************************************************
* : FLASH_DeInit
* : Flash接口反初始化Flash相关操作后进行调用
* :
* :
* : FLASH_DeInit
* : Flash接口反初始化Flash相关操作后进行调用
* :
* :
*******************************************************************************/
void FLASH_DeInit(void)
{
@ -583,11 +583,11 @@ void FLASH_DeInit(void)
/*******************************************************************************
* : FLASH_EraseSector
* : Flash扇区
* : addr:
* : None
* : :30ms~200/400ms
* : FLASH_EraseSector
* : Flash扇区
* : addr:
* : None
* : :30ms~200/400ms
*******************************************************************************/
uint8_t FLASH_EraseSector(uint32_t addr)
{
@ -613,13 +613,13 @@ uint8_t FLASH_EraseSector(uint32_t addr)
/*******************************************************************************
* : FLASH_WritePage
* : Flash一个页
* : addr:
buf:
len:(256)
* : kStatus_Success
* : 256
* : FLASH_WritePage
* : Flash一个页
* : addr:
buf:
len:(256)
* : kStatus_Success
* : 256
*******************************************************************************/
uint8_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len)
{
@ -648,12 +648,12 @@ uint8_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len)
/*******************************************************************************
* : FLASH_Read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
* : FLASH_Read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
*******************************************************************************/
status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len)
{
@ -680,12 +680,12 @@ status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len)
/*******************************************************************************
* : flash_erase
* : Flash指定长度的空间
* : addr:
byte_cnt:,4k字节为最小擦除单位
* : kStatus_Success
* : 4k字节的4k字节
* : flash_erase
* : Flash指定长度的空间
* : addr:
byte_cnt:,4k字节为最小擦除单位
* : kStatus_Success
* : 4k字节的4k字节
*******************************************************************************/
status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt)
{
@ -707,12 +707,12 @@ status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt)
/*******************************************************************************
* : flash_write
* : flash起始地址写入指定长度的数据
* : addr:
buf:
byte_cnt:
* : kStatus_Success
* : flash_write
* : flash起始地址写入指定长度的数据
* : addr:
buf:
byte_cnt:
* : kStatus_Success
*******************************************************************************/
status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt)
{
@ -736,12 +736,12 @@ status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt)
/*******************************************************************************
* : flash_read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
* : flash_read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
*******************************************************************************/
status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len)
{
@ -768,12 +768,12 @@ status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len)
/*******************************************************************************
* : flash_copy
* : flash数据在分区之间的拷贝
* : srcAddr:flash的起始地址
dstAddr:flash的起始地址;
imageSize:flash空间大小,
* : kStatus_Success
* : flash_copy
* : flash数据在分区之间的拷贝
* : srcAddr:flash的起始地址
dstAddr:flash的起始地址;
imageSize:flash空间大小,
* : kStatus_Success
*******************************************************************************/
status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize)
{
@ -834,11 +834,11 @@ status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize)
/*******************************************************************************
* : NOR_FLASH_Erase
* : Flash指定长度的空间,imageSize
* : addr:
imageSize:
* : None
* : NOR_FLASH_Erase
* : Flash指定长度的空间,imageSize
* : addr:
imageSize:
* : None
*******************************************************************************/
status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize)
{
@ -860,13 +860,13 @@ status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize)
/*******************************************************************************
* : NorFlash_Write_PageProgram
* : Flash指定长度的数据
* : pBuffer:
WriteAddr:
NumByteToWrite:(256)
* : kStatus_Success
* : 256
* : NorFlash_Write_PageProgram
* : Flash指定长度的数据
* : pBuffer:
WriteAddr:
NumByteToWrite:(256)
* : kStatus_Success
* : 256
*******************************************************************************/
void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
@ -883,24 +883,24 @@ void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t Num
/*******************************************************************************
* : NorFlash_Write_NoCheck
* : W25QXX从指定地址开始指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* :
* : 0XFF,0XFF处写入的数据将失败!
,,!
* : NorFlash_Write_NoCheck
* : W25QXX从指定地址开始指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* :
* : 0XFF,0XFF处写入的数据将失败!
,,!
*******************************************************************************/
void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t pageRemain;
pageRemain = 256 - WriteAddr%256;//单页剩余的字节数
pageRemain = 256 - WriteAddr%256;//单页剩余的字节数
if(NumByteToWrite <= pageRemain)
{
pageRemain = NumByteToWrite;//不大于256个字节
pageRemain = NumByteToWrite;//不大于256个字节
}
while(1)
@ -908,21 +908,21 @@ void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByte
NorFlash_Write_PageProgram(pBuffer,WriteAddr,pageRemain);
if(NumByteToWrite == pageRemain)
{
break;//写入结束了
break;//写入结束了
}
else //NumByteToWrite>pageRemain
{
pBuffer += pageRemain;
WriteAddr += pageRemain;
NumByteToWrite -= pageRemain;//减去已经写入了的字节数
NumByteToWrite -= pageRemain;//减去已经写入了的字节数
if(NumByteToWrite > 256)
{
pageRemain = 256;//一次可以写入256个字节
pageRemain = 256;//一次可以写入256个字节
}
else
{
pageRemain = NumByteToWrite;//不够256个字节了
pageRemain = NumByteToWrite;//不够256个字节了
}
}
}
@ -930,13 +930,13 @@ void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByte
/*******************************************************************************
* : NorFlash_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* : None
* :
* : NorFlash_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* : None
* :
*******************************************************************************/
void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
@ -946,61 +946,61 @@ void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
uint16_t i;
uint8_t *NorFlash_BUF = 0;
NorFlash_BUF = NorFlash_BUFFER;//RAM缓冲区4K
NorFlash_BUF = NorFlash_BUFFER;//RAM缓冲区4K
WriteAddr &= 0x0FFFFFFF;
secPos = WriteAddr/SECTOR_SIZE;//扇区地址
secOff = WriteAddr%SECTOR_SIZE;//在扇区内的偏移
secRemain = SECTOR_SIZE - secOff;//扇区剩余空间大小
secPos = WriteAddr/SECTOR_SIZE;//扇区地址
secOff = WriteAddr%SECTOR_SIZE;//在扇区内的偏移
secRemain = SECTOR_SIZE - secOff;//扇区剩余空间大小
if(NumByteToWrite <= secRemain)
{
secRemain = NumByteToWrite;//不大于4096个字节
secRemain = NumByteToWrite;//不大于4096个字节
}
while(1)
{
FLASH_Read(FLASH_BASE + secPos*SECTOR_SIZE, (void *)NorFlash_BUF, SECTOR_SIZE);//读出整个扇区的内容
for(i=0;i<secRemain;i++)//校验数据
FLASH_Read(FLASH_BASE + secPos*SECTOR_SIZE, (void *)NorFlash_BUF, SECTOR_SIZE);//读出整个扇区的内容
for(i=0;i<secRemain;i++)//校验数据
{
if(NorFlash_BUF[secOff+i] != 0xFF)
{
break;//需要擦除
break;//需要擦除
}
}
if(i < secRemain)//需要擦除
if(i < secRemain)//需要擦除
{
FLASH_EraseSector(FLASH_BASE + secPos*SECTOR_SIZE);
for(i=0;i<secRemain;i++)//复制
for(i=0;i<secRemain;i++)//复制
{
NorFlash_BUF[i+secOff] = pBuffer[i];
}
NorFlash_Write_NoCheck(NorFlash_BUF,FLASH_BASE + secPos*SECTOR_SIZE,SECTOR_SIZE);//写入整个扇区
NorFlash_Write_NoCheck(NorFlash_BUF,FLASH_BASE + secPos*SECTOR_SIZE,SECTOR_SIZE);//写入整个扇区
}
else
{
NorFlash_Write_NoCheck(pBuffer,FLASH_BASE + WriteAddr,secRemain);//写已经擦除了的,直接写入扇区剩余区间.
NorFlash_Write_NoCheck(pBuffer,FLASH_BASE + WriteAddr,secRemain);//写已经擦除了的,直接写入扇区剩余区间.
}
if(NumByteToWrite == secRemain)
{
break;//写入结束了
break;//写入结束了
}
else//写入未结束
else//写入未结束
{
secPos++;//扇区地址增1
secOff=0;//偏移位置为0
secPos++;//扇区地址增1
secOff=0;//偏移位置为0
pBuffer += secRemain;//指针偏移
WriteAddr += secRemain;//写地址偏移
NumByteToWrite -= secRemain;//字节数递减
pBuffer += secRemain;//指针偏移
WriteAddr += secRemain;//写地址偏移
NumByteToWrite -= secRemain;//字节数递减
if(NumByteToWrite > SECTOR_SIZE)
{
secRemain = SECTOR_SIZE;//下一个扇区还是写不完
secRemain = SECTOR_SIZE;//下一个扇区还是写不完
}
else
{
secRemain = NumByteToWrite;//下一个扇区可以写完了
secRemain = NumByteToWrite;//下一个扇区可以写完了
}
}
}
@ -1008,12 +1008,12 @@ void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
/*******************************************************************************
* : NOR_FLASH_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : FlashAddress:Flash地址的指针
Data:
DataLength:
* : 0
* : NOR_FLASH_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : FlashAddress:Flash地址的指针
Data:
DataLength:
* : 0
*******************************************************************************/
#ifndef USE_HIGHT_SPEED_TRANS
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength)

View File

@ -94,11 +94,11 @@ static const uint32_t crc32tab[] = {
/*******************************************************************************
* : calculate_crc32
* : Flash内存地址范围中数据的CRC32校验和
* : addr:Flash地址的起始位置
len:CRC32的数据长度
* : CRC32值
* : calculate_crc32
* : Flash内存地址范围中数据的CRC32校验和
* : addr:Flash地址的起始位置
len:CRC32的数据长度
* : CRC32值
*******************************************************************************/
uint32_t calculate_crc32(uint32_t addr, uint32_t len)
{
@ -115,10 +115,10 @@ uint32_t calculate_crc32(uint32_t addr, uint32_t len)
/*******************************************************************************
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
*******************************************************************************/
status_t UpdateOTAFlag(ota_info_t *ptr)
{
@ -135,31 +135,31 @@ status_t UpdateOTAFlag(ota_info_t *ptr)
}
/*******************************************************************************
* : UpdateApplication
* : bootloader里进行调用,Flash中Flag分区中的信息决定是否进行版本更新
* :
* :
* : app分区
* : UpdateApplication
* : bootloader里进行调用,Flash中Flag分区中的信息决定是否进行版本更新
* :
* :
* : app分区
*******************************************************************************/
void UpdateApplication(void)
{
status_t status;
ota_info_t ota_info; // 定义OTA信息结构体
ota_info_t ota_info; // 定义OTA信息结构体
// 从Flash中读取OTA信息
// 从Flash中读取OTA信息
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
// 如果OTA升级状态为准备状态且APP分区与download分区版本不同,才可以进行升级
// 如果OTA升级状态为准备状态且APP分区与download分区版本不同,才可以进行升级
if((ota_info.status == OTA_STATUS_READY) && (ota_info.os.crc32 != ota_info.down.crc32))
{
Serial_PutString("\r\n------Start to update the app!------\r\n");
// 校验downlad分区固件CRC
// 校验downlad分区固件CRC
if(calculate_crc32(DOWN_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32)
{
ota_info.status = OTA_STATUS_UPDATING;
UpdateOTAFlag(&ota_info);
// 1.如果CRC校验通过,开始升级,逐字节拷贝Flash,先备份当前XiUOS System分区内容
// 1.如果CRC校验通过,开始升级,逐字节拷贝Flash,先备份当前XiUOS System分区内容
status = flash_copy(XIUOS_FLAH_ADDRESS, BAKUP_FLAH_ADDRESS, ota_info.os.size);
if((status == kStatus_Success) &&(calculate_crc32(BAKUP_FLAH_ADDRESS, ota_info.os.size) == ota_info.os.crc32))
{
@ -179,7 +179,7 @@ void UpdateApplication(void)
goto finish;
}
// 2.拷贝download分区到XiUOS System分区
// 2.拷贝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))
{
@ -189,7 +189,7 @@ void UpdateApplication(void)
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
ota_info.status == OTA_STATUS_IDLE; // 拷贝download分区到XiUOS System分区成功,将OTA升级状态设置为IDLE
UpdateOTAFlag(&ota_info);
}
else
@ -206,7 +206,7 @@ void UpdateApplication(void)
}
else
{
// 如果download分区CRC校验失败升级失败
// 如果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));

View File

@ -39,9 +39,53 @@ static void InitialVersion(void)
}
}
static void BackupVersion(void)
{
status_t status;
ota_info_t ota_info;
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
ota_info.status = OTA_STATUS_BACKUP;
UpdateOTAFlag(&ota_info);
status = 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))
{
Serial_PutString("\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;
ota_info.lastjumpflag=0xABABABAB;
strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description));
UpdateOTAFlag(&ota_info);
}
else
{
Serial_PutString("\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);
}
}
void jump_to_application(void)
{
ota_info_t ota_info;
FLASH_Init();
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
if (ota_info.lastjumpflag!=0x00000000)
{
Serial_PutString("\r\n------Bootloader false, begin backup!------\r\n");
BackupVersion();
}
else
{
ota_info.lastjumpflag=0xABABABAB;
UpdateOTAFlag(&ota_info);
}
FLASH_DeInit();
SCB->VTOR = (uint32_t)XIUOS_FLAH_ADDRESS;
asm volatile("LDR R0, = 0x60100000");
@ -77,19 +121,25 @@ void BootLoaderJumpApp(void)
ImxrtMsDelay(10);
}
while(1)
{
if((ret)&&(ch1 == 0x20))
{
Serial_PutString("\r\nPlease slecet:");
Serial_PutString("\r\n 1:run app");
Serial_PutString("\r\n 2:update app");
Serial_PutString("\r\n 3:reboot \r\n");
ch2 = GetKey();
switch(ch2)
{
case 0x31:
jump_to_application();
break;
@ -106,6 +156,7 @@ void BootLoaderJumpApp(void)
{
UpdateApplication();
}
FLASH_DeInit();
jump_to_application();
break;

View File

@ -33,6 +33,7 @@ typedef enum {
OTA_STATUS_DOWNLOADING, // 正在下载固件
OTA_STATUS_DOWNLOADED, // 固件下载完成
OTA_STATUS_UPDATING, // 正在进行OTA升级
OTA_STATUS_BACKUP, // 正在版本回退
OTA_STATUS_ERROR, // 出现错误,升级失败
} ota_status_t;