forked from xuos/xiuos
Add version rollback function for OTA
This commit is contained in:
parent
84f78b6435
commit
0ecb29c887
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue