From 247e211168d99f1cd27b5a6b8da5401fba734377 Mon Sep 17 00:00:00 2001 From: coffee Date: Sat, 6 Dec 2025 09:53:23 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E8=BF=98=E9=9C=80=E8=A6=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=B8=80=E7=89=88,=20=E5=85=88=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HFlashServer.h | 3 +- src/HFlashServer.c | 173 ++++++++++++++++++++++------------------- 2 files changed, 94 insertions(+), 82 deletions(-) diff --git a/include/HFlashServer.h b/include/HFlashServer.h index cb83568..acaa7cd 100644 --- a/include/HFlashServer.h +++ b/include/HFlashServer.h @@ -22,7 +22,7 @@ #define HFLASH_BLOCK_SIZE (4096) #endif -///< 获取缓存内存, 需要能申请到大于等于(Flash一块大小 + 1024) +///< 获取缓存内存, 需要能申请到大于等于(Flash一块大小) #ifndef HFLASH_MALLOC #ifdef USE_STD_MEM #define HFLASH_MALLOC(size) malloc(size) @@ -72,6 +72,7 @@ typedef struct HFlashCacheInfo { uint32_t pos : 19; ///< 存储页表信息的位置 uint32_t heat : 4; ///< 热度优先级 uint32_t waitWrite : 1; ///< 延后写入, 一般适用于流式操作或者延后复写 + uint32_t waitCrc : 1; ///< 延后CRC } HFlashCacheInfo; diff --git a/src/HFlashServer.c b/src/HFlashServer.c index f1a8119..fef1768 100644 --- a/src/HFlashServer.c +++ b/src/HFlashServer.c @@ -132,13 +132,12 @@ static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size) return 1; } -static inline uint32_t Aligned4K(uint32_t value) +static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size) { - return (value + (HFLASH_BLOCK_SIZE - 1)) & ~(HFLASH_BLOCK_SIZE - 1); -} + if (size == 0) { + return 1; + } -static uint8_t ReadFlash(HFlashAddr_t addr, void *data, uint32_t size) -{ if (sInfo.read == NULL) { FATAL_ERROR("read is null"); return 0; @@ -148,7 +147,7 @@ static uint8_t ReadFlash(HFlashAddr_t addr, void *data, uint32_t size) return sInfo.read(addr, dataPtr, size); } -static uint8_t EraseFlash(HFlashAddr_t addr) +static uint8_t EraseFlashCall(HFlashAddr_t addr) { if (sInfo.erase == NULL) { FATAL_ERROR("erase is null"); @@ -158,6 +157,21 @@ static uint8_t EraseFlash(HFlashAddr_t addr) return sInfo.erase(addr); } +static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size) +{ + if (size == 0) { + return 1; + } + + if (sInfo.write == NULL) { + FATAL_ERROR("write is null"); + return 0; + } + + uint8_t *dataPtr = (uint8_t *)data; + return sInfo.write(addr, dataPtr, size); +} + /** * @brief 写入数据到Flash * @param addr 写入的Flash地址 @@ -168,11 +182,6 @@ static uint8_t EraseFlash(HFlashAddr_t addr) */ static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, void(*call)(void *dest, const void *src, uint16_t buffSize, void *userData), void *userData) { - if (sInfo.write == NULL) { - FATAL_ERROR("write is null"); - return 0; - } - uint8_t *dataPtr = (uint8_t *)data; uint32_t adjustAddr = addr & ~(HFLASH_BLOCK_SIZE - 1); const uint16_t offset = addr - adjustAddr; @@ -185,18 +194,18 @@ static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, voi } // 先写入首个未对齐的块 - if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { + if (ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { LogE("addr[0x%08x], read faild", adjustAddr); goto _flashError; } - if (EraseFlash(adjustAddr) == 0) { + if (EraseFlashCall(adjustAddr) == 0) { LogE("addr[0x%08x], erase faild", adjustAddr); goto _flashError; } call(buff + offset, dataPtr, remain, userData); - if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { + if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { LogE("addr[0x%08x], write faild", adjustAddr); goto _flashError; } @@ -206,13 +215,13 @@ static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, voi adjustAddr += HFLASH_BLOCK_SIZE; dataPtr += remain; for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE, dataPtr += HFLASH_BLOCK_SIZE) { - if (EraseFlash(adjustAddr) == 0) { + if (EraseFlashCall(adjustAddr) == 0) { LogE("addr[0x%08x], erase faild", adjustAddr); goto _flashError; } call(buff, dataPtr, HFLASH_BLOCK_SIZE, userData); - if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { + if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { LogE("addr[0x%08x], write faild", adjustAddr); goto _flashError; } @@ -220,18 +229,18 @@ static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, voi // 操作最后一个未对齐的块 if (size) { - if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { + if (ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { LogE("addr[0x%08x], read faild", adjustAddr); goto _flashError; } - if (EraseFlash(adjustAddr) == 0) { + if (EraseFlashCall(adjustAddr) == 0) { LogE("addr[0x%08x], erase faild", adjustAddr); goto _flashError; } call(buff, dataPtr, size, userData); - if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { + if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) { LogE("addr[0x%08x], write faild", adjustAddr); goto _flashError; } @@ -244,36 +253,6 @@ _flashError: return result; } -/** - * @brief 地址对齐写入 - * @brief addr 写入地址, 需要页对齐 - * @brief data 写入数据 - * @brief size 写入数据大小, 需要页对齐 - * @return 1写入成功, 0写入失败 - */ -static uint8_t WriteAlignData(HFlashAddr_t addr, const void *data, uint32_t size) -{ - if (IS_NOT_4K(addr) || IS_NOT_4K(size)) { - LogE("not align 4k"); - return 0; - } - - uint8_t *buff = (uint8_t *)data; - for (uint32_t i = 0; i < size; i += HFLASH_BLOCK_SIZE) { - if (EraseFlash(addr + i) == 0) { - LogE("addr[0x%08x], erase faild", addr + i); - return 0; - } - - if (sInfo.write(addr, buff + i, HFLASH_BLOCK_SIZE) == 0) { - LogE("addr[0x%08x], write faild", addr + i); - return 0; - } - } - - return 1; -} - static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, void *userData) { (void)userData; @@ -337,9 +316,7 @@ static void SyncBackup() HVectorClear(sNeedBackupOffset); // 备份页表数据 - uint32_t backSize = Aligned4K(AdjustPageAddr(sPageInfo.useNum + 1)); - backSize = FLASH_MIN(uint32_t, backSize, sInfo.pageSize); - RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, backSize); + RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, AdjustPageByte(sPageInfo.useNum + 1)); sPageInfo.needBackupPage = 0; } @@ -415,7 +392,7 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size) for (uint32_t i = 0; i < size; i += HFLASH_BLOCK_SIZE) { const uint32_t remain = FLASH_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE); - if (ReadFlash(addr + i, buff, remain) == 0) { + if (ReadFlashCall(addr + i, buff, remain) == 0) { LogE("addr[0x%08x][0x%08x], size[%d] read faild", addr, addr + i, remain); break; } @@ -478,41 +455,75 @@ static void AddDelayCrc32(HFlashAddr_t addr) StartDelayCrc32Timer(); } -static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size) +static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t copySize) { - // 检查是不是页对齐数据, 是的话不用再回读写, 直接读写 - const uint8_t isAlignPage = (IS_NOT_4K(dstAddr) == 0 && IS_NOT_4K(size) == 0); - const uint16_t mallocSize = isAlignPage ? 4096 : 1024; - uint8_t *buff = (uint8_t *)HFLASH_MALLOC(mallocSize); + if (copySize == 0) { + LogD("addr[0x%08x], write size[%d] is 0", srcAddr, copySize); + return 1; + } + + uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE); if (buff == NULL) { - LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, size); + LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, copySize); return 0; } uint8_t result = 0; - uint32_t i = 0; - uint32_t remain = 0; - for (; i < size; i += mallocSize) { - remain = FLASH_MIN(uint32_t, size - i, mallocSize); - result = result || ReadFlash(srcAddr + i, buff, remain) == 0; - if (isAlignPage) { - // 是对齐大小直接回写 - result = result || WriteAlignData(dstAddr + i, buff, remain) == 0; - } else { - result = result || WriteFlash(dstAddr + i, buff, remain) == 0; - } + uint32_t adjustAddr = dstAddr & ~(HFLASH_BLOCK_SIZE - 1); + uint32_t size = copySize; + uint32_t srcOffset = 0; + // 如果地址不是对齐页的, 先处理残余数据到对齐页 + if (adjustAddr != dstAddr) { + const uint16_t offset = dstAddr - adjustAddr; + const uint32_t remain = offset + size > HFLASH_BLOCK_SIZE ? HFLASH_BLOCK_SIZE - offset : size; + // 先读取到对齐页, 然后将未对齐的数据重写 + result = ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0; + result = result || ReadFlashCall(srcAddr + srcOffset, buff + offset, remain) == 0; + result = result || EraseFlashCall(adjustAddr) == 0; + result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0; if (result) { - LogE("read addr[0x%08x], write addr[0x%08x], write size[%d] faild", srcAddr + i, dstAddr + i, remain); result = 0; + LogE("addr[0x%08x], write size[%d] faild", srcAddr, size); goto _FlashError; } + + size -= remain; + adjustAddr += HFLASH_BLOCK_SIZE; + srcOffset += remain; + } + + // 中间对齐页直接读原地址页, 擦写目标页 + for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE, srcOffset += HFLASH_BLOCK_SIZE) { + result = result || ReadFlashCall(srcAddr + srcOffset, buff, HFLASH_BLOCK_SIZE) == 0; + result = result || EraseFlashCall(adjustAddr) == 0; + result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0; + if (result) { + result = 0; + LogE("addr[0x%08x], write size[%d] faild", srcAddr, size); + goto _FlashError; + } + } + + // 最后不对齐的数据 + if (size) { + result = result || ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0; + result = result || ReadFlashCall(srcAddr + srcOffset, buff, size) == 0; + result = result || EraseFlashCall(adjustAddr) == 0; + result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0; + if (result) { + result = 0; + LogE("addr[0x%08x], write size[%d] faild", srcAddr, size); + goto _FlashError; + } + + size = 0; } result = 1; _FlashError: HFLASH_FREE(buff); - LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d], result[%d], malloc[%d]", srcAddr, dstAddr, size, result, mallocSize); + LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d][%d], result[%d]", srcAddr, dstAddr, size, copySize, result); return result; } @@ -545,7 +556,7 @@ static void ReadPage(uint32_t index, HFlashPageInfo *info) } const HFlashAddr_t addr = AdjustPageAddrOffset(sInfo.pageAddr, index); - ReadFlash(addr, info, sizeof(HFlashPageInfo)); + ReadFlashCall(addr, info, sizeof(HFlashPageInfo)); } static void WritePage(uint32_t index, HFlashPageInfo *info) @@ -617,7 +628,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo uint8_t result = 0; for (uint32_t i = 0; i < sPageInfo.useNum; i += pageNum) { const uint32_t num = FLASH_MIN(uint32_t, sPageInfo.useNum - i, pageNum); - if (ReadFlash(AdjustPageAddrOffset(sInfo.pageAddr, i), buff, AdjustPageByte(num)) == 0) { + if (ReadFlashCall(AdjustPageAddrOffset(sInfo.pageAddr, i), buff, AdjustPageByte(num)) == 0) { LogE("read page table[0x%08x] faild", AdjustPageAddrOffset(sInfo.pageAddr, i)); break; } @@ -916,7 +927,7 @@ void HFlashInitCheck() const uint32_t num = sInfo.pageSize / sizeof(HFlashPageInfo); do { - if (ReadFlash(sInfo.pageAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) { + if (ReadFlashCall(sInfo.pageAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) { LogE("Read page table[0x%08x] faild", sInfo.pageAddr); break; } @@ -934,7 +945,7 @@ void HFlashInitCheck() LogD("page table is invalid, check backup table"); // 备份校验 - if (ReadFlash(sInfo.pageBackupAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) { + if (ReadFlashCall(sInfo.pageBackupAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) { LogE("Read backup page table[0x%08x] faild", sInfo.pageBackupAddr); break; } @@ -949,8 +960,8 @@ void HFlashInitCheck() break; } - // 备份校验通过, 恢复备份数据 - RestoreBackup(sInfo.pageBackupAddr, sInfo.pageAddr, sPageInfo.useNum); + // 备份校验通过, 恢复全备份数据 + RestoreBackup(sInfo.pageBackupAddr, sInfo.pageAddr, sInfo.pageSize); return ; } while (0); @@ -1221,7 +1232,7 @@ uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size) } const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize); - return ReadFlash(addr, data, readSize); + return ReadFlashCall(addr, data, readSize); } uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size) @@ -1247,12 +1258,12 @@ uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_ size -= remain; } - return ReadFlash(addr + offset, data, size); + return ReadFlashCall(addr + offset, data, size); } uint8_t HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size) { - return ReadFlash(addr, data, size); + return ReadFlashCall(addr, data, size); } void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData)