diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c index 69f663516..9cb1b3af1 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c @@ -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 } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c index 93938e5ed..dfb8965fe 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/flash.c @@ -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ʱӵIJʱģʽ,ѡSDRDDRģʽ -* ֵ: ִгɹ״ֵ̬Ϊ 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;//RAM4K + 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 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) diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/imxrt_ota.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/imxrt_ota.c index 872b1e66c..618515719 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/imxrt_ota.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/imxrt_ota.c @@ -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е,FlashFlagеϢǷа汾 -* : -* ֵ: -* ע : úú۽ζת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״̬Ϊ׼״̬APPdownload汾ͬ,ſԽ + // 如果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.downloadXiUOS 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; // downloadXiUOS 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 { - // downloadCRCУʧܣʧ + // 如果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)); diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c index 7af9c9231..add7cfb5f 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/common/mcuboot.c @@ -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; diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/imxrt_ota.h b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/imxrt_ota.h index 099aca3f0..30d4c8de5 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/imxrt_ota.h +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/include/imxrt_ota.h @@ -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;