From 06486210e11d192503da201c19ef4d85fa97298e Mon Sep 17 00:00:00 2001 From: coffee Date: Thu, 25 Dec 2025 16:20:51 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E6=94=B9Flash=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HFlashMem.h | 22 ++++++++++ include/HFlashServer.h | 2 +- src/HFlashMem.c | 69 ++++++++++++++++++++++++++++++++ src/HFlashServer.c | 91 +++++++++++++++++++++++++++++++++++------- 4 files changed, 169 insertions(+), 15 deletions(-) diff --git a/include/HFlashMem.h b/include/HFlashMem.h index b34784d..b6edfaa 100644 --- a/include/HFlashMem.h +++ b/include/HFlashMem.h @@ -79,9 +79,31 @@ uint8_t HFlashMemWrite(uint32_t addr, const void *buf, uint32_t len); */ uint8_t HFlashMemSetValue(uint32_t addr, uint8_t value, uint32_t len); +/** + * @brief Flash数据拷贝 + * @param srcAddr 源地址 + * @param destAddr 目标地址 + * @param len 拷贝长度 + */ +uint8_t HFlashMemAddrCopy(uint32_t srcAddr, uint32_t destAddr, uint32_t len); + +/** + * @brief Flash数据映射回调 + * @param addr 地址 + * @param call 回调函数, 终止继续读取返回非0, 每次按页读取, 请根据偏移进行判断 + * @param arg 回调函数参数 + * @return call返回值 + */ +uint8_t HFlashMemMMapCall(uint32_t addr, uint8_t(*call)(uint32_t addr, uint32_t offset, const uint8_t *data, uint16_t len, void *arg), void *arg); + /** * @brief 同步脏页写入Flash */ void HFlashMemSync(); +/** + * @brief 释放缓存页 + */ +void HFlashFreeCache(); + #endif // __H_FLASH_MEM_H__ diff --git a/include/HFlashServer.h b/include/HFlashServer.h index 7571492..4defd24 100644 --- a/include/HFlashServer.h +++ b/include/HFlashServer.h @@ -17,7 +17,7 @@ #endif ///< 使用Flash内存映射功能 -// #define USE_FLASH_MEM +#define USE_FLASH_MEM ///< Flash块大小, 按块操作, 2的幂关系 #ifndef HFLASH_BLOCK_SIZE diff --git a/src/HFlashMem.c b/src/HFlashMem.c index 09358c8..1c05dfa 100644 --- a/src/HFlashMem.c +++ b/src/HFlashMem.c @@ -386,7 +386,76 @@ uint8_t HFlashMemSetValue(uint32_t addr, uint8_t value, uint32_t len) return WriteData(addr, NULL, len, _MemSetValueHelper, &value); } +static void _MemAddrCopy(void *dest, const void *src, uint32_t len, void *userData) +{ + uint32_t srcAddr = *(uint32_t *)userData; + HFlashMemRead(srcAddr + (long)src, dest, len); +} + +uint8_t HFlashMemAddrCopy(uint32_t srcAddr, uint32_t destAddr, uint32_t len) +{ + if (sOpts == NULL) { + return 0; + } + + return WriteData(destAddr, NULL, len, _MemAddrCopy, &srcAddr); +} + +uint8_t HFlashMemMMapCall(uint32_t addr, uint8_t(*call)(uint32_t addr, uint32_t offset, const uint8_t *data, uint16_t len, void *arg), void *arg) +{ + if (sOpts == NULL || call == NULL) { + return 0; + } + + uint32_t offset = 0; + HFlashMemCache *cache = NULL; + uint16_t len = 0; + uint8_t result = 0; + + // 先处理未对齐的部分 + if (addr != Align4K(addr)) { + cache = FindCache(addr + offset, 1); + if (cache == NULL) { + LogE("addr[0x%08x], find cache faild", addr); + return 0; + } + + len = HFLASH_BLOCK_SIZE - (addr - cache->addr); + result = call(addr, offset, GetMMap(cache->offset) + (addr - cache->addr), len, arg); + offset += len; + } + + if (result) { + return result; + } + + // 剩余处理对齐部分 + while (result == 0) { + cache = FindCache(addr + offset, 1); + if (cache == NULL) { + LogE("addr[0x%08x], find cache faild", addr + offset); + return 0; + } + + result = call(addr + offset, offset, GetMMap(cache->offset), HFLASH_BLOCK_SIZE ,arg); + if (result) { + break; + } + + offset += HFLASH_BLOCK_SIZE; + } + + return result; +} + void HFlashMemSync() { SyncCache(); } + +void HFlashFreeCache() +{ + HFlashMemSync(); + sInfo.useNum = 0; +} + diff --git a/src/HFlashServer.c b/src/HFlashServer.c index 27f9890..b2b6fb1 100644 --- a/src/HFlashServer.c +++ b/src/HFlashServer.c @@ -38,12 +38,18 @@ uint32_t HSCrc32Get() #endif // 计算最小值 -#define FLASH_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b))))) +#define FAST_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b))))) -#ifdef USE_STD_MEM +#ifdef USE_FATAL_NOT_LOOP #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); #else -#define FATAL_ERROR(format, ...) while (1) { LogE(format, ##__VA_ARGS__); HShellRun(); }; +__attribute__((weak)) +void HDMainLoopCallOverride(uint8_t event) +{ + (void)(event); + HShellRun(); +} +#define FATAL_ERROR(format, ...) while (1) { LogE(format, ##__VA_ARGS__); HDMainLoopCallOverride(0); }; #endif // 最大热度 @@ -80,9 +86,11 @@ union PageInfo { }; struct Info { +#ifndef USE_FLASH_MEM HFlashReadCallback read; ///< 读取回调 HFlashWriteCallback write; ///< 写入回调 HFlashEraseCallback erase; ///< 擦除回调 +#endif HFlashAddr_t pageAddr; ///< 页表地址 HFlashAddr_t pageBackupAddr; ///< 页表备份地址 uint32_t pageSize; ///< 页大小 @@ -141,7 +149,9 @@ static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size) if (size == 0) { return 1; } - +#ifdef USE_FLASH_MEM + return HFlashMemRead(addr, data, size); +#else if (sInfo.read == NULL) { FATAL_ERROR("read is null"); return 0; @@ -149,8 +159,10 @@ static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size) uint8_t *dataPtr = (uint8_t *)data; return sInfo.read(addr, dataPtr, size); +#endif } +#ifndef USE_FLASH_MEM static uint8_t EraseFlashCall(HFlashAddr_t addr) { if (sInfo.erase == NULL) { @@ -160,7 +172,6 @@ static uint8_t EraseFlashCall(HFlashAddr_t addr) return sInfo.erase(addr); } - static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size) { if (size == 0) { @@ -175,7 +186,9 @@ static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size uint8_t *dataPtr = (uint8_t *)data; return sInfo.write(addr, dataPtr, size); } +#endif +#ifndef USE_FLASH_MEM /** * @brief 写入数据到Flash * @param addr 写入的Flash地址 @@ -256,31 +269,40 @@ _flashError: HFLASH_FREE(buff); return result; } +#endif +#ifndef USE_FLASH_MEM static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, void *userData) { (void)userData; memcpy(dest, src, buffSize); } +#endif static uint8_t WriteFlash(HFlashAddr_t addr, const void *data, uint32_t size) { #ifdef USE_FLASH_MEM - HFlashMemWrite(addr, data, size); + return HFlashMemWrite(addr, data, size); #else return WriteData(addr, data, size, _WriteFlashHelper, NULL); #endif } +#ifndef USE_FLASH_MEM static void _WriteFalshValueHelper(void *dest, const void *src, uint16_t size, void *userData) { uint8_t *value = (uint8_t *)userData; memset(dest, *value, size); } +#endif static uint8_t WriteFlashValue(uint32_t addr, uint32_t size, uint8_t value) { +#ifdef USE_FLASH_MEM + return HFlashMemSetValue(addr, value, size); +#else return WriteData(addr, NULL, size, _WriteFalshValueHelper, &value); +#endif } static inline uint32_t AdjustPageAddr(uint32_t addr) @@ -383,6 +405,14 @@ static void AddBackupAddr(uint32_t addr, uint32_t size) } } +static uint8_t _CalcCrc32(uint32_t addr, uint32_t offset, const uint8_t *data, uint16_t len, void *args) +{ + uint32_t needLen = *(uint32_t *)args; + uint32_t calcLen = FAST_MIN(uint32_t, (needLen - offset), len); + HSCrc32Update(data, calcLen); + return needLen <= offset + len; +} + static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size) { if (size == 0) { @@ -390,6 +420,12 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size) } HSCrc32Reset(); +#ifdef USE_FLASH_MEM + if (HFlashMemMMapCall(addr, _CalcCrc32, &size) == 0) { + LogE("addr[0x%08x], size[%d] mmap faild", addr, size); + return 0xFFFFFFFF; + } +#else uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE); if (buff == NULL) { LogE("addr[0x%08x], write size[%d] malloc faild", addr, size); @@ -397,7 +433,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); + const uint32_t remain = FAST_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE); if (ReadFlashCall(addr + i, buff, remain) == 0) { LogE("addr[0x%08x][0x%08x], size[%d] read faild", addr, addr + i, remain); break; @@ -407,6 +443,7 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size) } HFLASH_FREE(buff); +#endif return HSCrc32Get(); } @@ -416,7 +453,9 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_ LogD("addr[0x%08x], write size[%d] is 0", srcAddr, copySize); return 1; } - +#ifdef USE_FLASH_MEM + return HFlashMemAddrCopy(srcAddr, dstAddr, copySize); +#else uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE); if (buff == NULL) { LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, copySize); @@ -480,6 +519,7 @@ _FlashError: HFLASH_FREE(buff); LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d][%d], result[%d]", srcAddr, dstAddr, size, copySize, result); return result; +#endif } ///< 恢复指定页表 @@ -628,7 +668,24 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo return 0; } - const uint32_t pageNum = FLASH_MIN(uint32_t, sPageInfo.useNum, (HFLASH_BLOCK_SIZE / sizeof(HFlashPageInfo))); +#ifdef USE_FLASH_MEM + HFlashPageInfo page; + uint8_t result = 0; + for (uint32_t i = 0; i < sPageInfo.useNum; ++i) { + if (HFlashMemRead(AdjustPageAddrOffset(sInfo.pageAddr, i), &page, sizeof(HFlashPageInfo)) == 0) { + LogE("read page table[0x%08x] faild", AdjustPageAddrOffset(sInfo.pageAddr, i)); + return 0; + } + + result = call(i, &page, userData); + if (result) { + break; + } + } + + return result; +#else + const uint32_t pageNum = FAST_MIN(uint32_t, sPageInfo.useNum, (HFLASH_BLOCK_SIZE / sizeof(HFlashPageInfo))); HFlashPageInfo *buff = (HFlashPageInfo *)HFLASH_MALLOC(pageNum * sizeof(HFlashPageInfo)); if (buff == NULL) { LogE("malloc faild"); @@ -637,7 +694,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); + const uint32_t num = FAST_MIN(uint32_t, sPageInfo.useNum - i, pageNum); if (ReadFlashCall(AdjustPageAddrOffset(sInfo.pageAddr, i), buff, AdjustPageByte(num)) == 0) { LogE("read page table[0x%08x] faild", AdjustPageAddrOffset(sInfo.pageAddr, i)); break; @@ -658,6 +715,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo HFLASH_FREE(buff); return result; +#endif } ///< 检查是否重叠, 重叠返回1 @@ -740,13 +798,13 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr) uint8_t fastCoolDown = 0; HFlashCacheInfo cache; for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) { - currMin = FLASH_MIN(uint8_t, currMin, sInfo.pageCache[i].heat); + currMin = FAST_MIN(uint8_t, currMin, sInfo.pageCache[i].heat); fastCoolDown = fastCoolDown || sInfo.pageCache[i].heat >= MAX_HEAT; if (sInfo.pageCache[i].info.addr != addr) { continue; } - sInfo.pageCache[i].heat = FLASH_MIN(uint8_t, sInfo.pageCache[i].heat + 1, MAX_HEAT); + sInfo.pageCache[i].heat = FAST_MIN(uint8_t, sInfo.pageCache[i].heat + 1, MAX_HEAT); if (i == 0) { return &sInfo.pageCache[i]; } @@ -775,7 +833,7 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr) memset(&cache, 0, sizeof(HFlashCacheInfo)); cache.info.addr = addr; if (ScanPage(_FindCacheHelper, &cache)) { - const uint16_t index = FLASH_MIN(uint16_t, sInfo.pageCacheUseNum, sInfo.pageCacheSize - 1); + const uint16_t index = FAST_MIN(uint16_t, sInfo.pageCacheUseNum, sInfo.pageCacheSize - 1); if (sInfo.pageCacheUseNum < sInfo.pageCacheSize) { ++sInfo.pageCacheUseNum; } @@ -802,9 +860,11 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr) void HFlashInitCallback(HFlashReadCallback read, HFlashWriteCallback write, HFlashEraseCallback erase) { +#ifndef USE_FLASH_MEM sInfo.read = read; sInfo.write = write; sInfo.erase = erase; +#endif } void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size) @@ -1244,7 +1304,7 @@ uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size) memset((uint8_t *)data + cache->info.useSize, 0, size - cache->info.useSize); } - const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize); + const uint32_t readSize = FAST_MIN(uint32_t, size, cache->info.useSize); return ReadFlashCall(addr, data, readSize); } @@ -1361,4 +1421,7 @@ void HFlashSync() SyncCachePage(); SyncPageInfo(); SyncBackup(); +#ifdef USE_FLASH_MEM + HFlashMemSync(); +#endif }