From df494faf2d509a721beab474de60378eb29d9398 Mon Sep 17 00:00:00 2001 From: coffee Date: Thu, 30 Apr 2026 10:54:37 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E9=81=BF=E5=85=8D=E4=B8=8D=E9=97=B4?= =?UTF-8?q?=E6=96=AD=E4=B8=8D=E6=96=AD=E6=89=A7=E8=A1=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HFlashServer.h | 48 +++++++++++- src/HFlashMem.c | 146 ++++++++++++++++++++++++----------- src/HFlashServer.c | 167 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 294 insertions(+), 67 deletions(-) diff --git a/include/HFlashServer.h b/include/HFlashServer.h index bbe7a8e..cf5852c 100644 --- a/include/HFlashServer.h +++ b/include/HFlashServer.h @@ -12,6 +12,15 @@ #include +// 使用位图模块映射保护区 +#ifndef HFLASH_USE_BITMAP +#define HFLASH_USE_BITMAP 1 +#endif + +#if HFLASH_USE_BITMAP +#include "HBitMap.h" +#endif + // 使用HShell #ifndef HFLASH_USE_HSHELL #define HFLASH_USE_HSHELL 1 @@ -24,7 +33,7 @@ #ifndef USE_STD_MEM #ifndef HFLASH_USE_FLASH_MEM -#include "HDSendBuffer.h" +#include "HSendBuffer.h" #endif // HFLASH_USE_FLASH_MEM #endif @@ -39,7 +48,7 @@ #ifdef USE_STD_MEM #define HFLASH_MALLOC(size) malloc(size) #else -#define HFLASH_MALLOC(size) HDSendBufferGet(size) +#define HFLASH_MALLOC(size) HSendBufferGet(size) #endif // USE_STD_MEM #endif // HFLASH_MALLOC @@ -48,7 +57,7 @@ #ifdef USE_STD_MEM #define HFLASH_FREE(ptr) free(ptr) #else -#define HFLASH_FREE(ptr) HDSendBufferFree(ptr) +#define HFLASH_FREE(ptr) HSendBufferFree(ptr) #endif // USE_STD_MEM #endif // HFLASH_FREE #endif // HFLASH_USE_FLASH_MEM @@ -90,10 +99,34 @@ typedef union HFlashPageInfo { }; } HFlashPageInfo; +#if HFLASH_USE_BITMAP +///< 计算保护区备份跨度大小, 传入原始保护区 addr/size 即可 +#define HFLASH_CALC_PROTECT_SPAN_SIZE(addr, size) \ + ((uint32_t)((((((uint64_t)(addr)) & ((uint64_t)HFLASH_BLOCK_SIZE - 1u)) + (uint64_t)(size)) + \ + (uint64_t)HFLASH_BLOCK_SIZE - 1u) & ~((uint64_t)HFLASH_BLOCK_SIZE - 1u))) + +///< 计算保护区位图大小数组, size 需要传保护区备份跨度大小 +#define HFLASH_CALC_BITMAP_SIZE(size) \ + (HBITMAP_CALC_LEN(((uint32_t)(size) + HFLASH_BLOCK_SIZE - 1u) / HFLASH_BLOCK_SIZE)) + +///< 直接通过保护区 addr/size 计算位图数组大小 +#define HFLASH_CALC_PROTECT_BITMAP_SIZE(addr, size) \ + HFLASH_CALC_BITMAP_SIZE(HFLASH_CALC_PROTECT_SPAN_SIZE((addr), (size))) + +///< 便于静态定义保护区位图数组 +#define HFLASH_PROTECT_BITMAP_DEFINE(name, addr, size) \ + HBitMapType name[HFLASH_CALC_PROTECT_BITMAP_SIZE((addr), (size))] +#else +#define HFLASH_CALC_BITMAP_SIZE(size) 0 +#define HFLASH_CALC_PROTECT_BITMAP_SIZE(addr, size) 0 +#endif typedef struct HFlashProtectInfo { HFlashAddr_t addr; ///< 保护区地址 uint32_t size; ///< 保护区大小 HFlashAddr_t backupAddr; ///< 保护区备份地址 +#if HFLASH_USE_BITMAP + HBitMapType *bitMap; ///< 保护区需保存的位图, 4k基准 +#endif } HFlashProtectInfo; typedef struct HFlashCacheInfo { @@ -160,6 +193,15 @@ uint16_t HFlashGetVersion(HFlashAddr_t addr, HFlashVersionInfo *info); */ void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size); +/** + * @brief HFlashInitProtectCache 初始化保护区缓存, 内部不构建内存, 由外部分配 + * 需要在设置保护地址前调用, 会将内存清零 + * @param protectInfo 保护区描述缓存 + * @param bitMap 位图 + * @param size 保护区备份跨度大小, 推荐使用 HFLASH_CALC_PROTECT_SPAN_SIZE(addr, size) 计算 + */ +void HFlashInitProtectCache(HFlashProtectInfo *protectInfo, void *bitMap, uint32_t size); + /** * @brief HFlashSetProtectCache 设置保护区描述缓存, 内部不构建内存, 由外部分配 * 需要在设置保护地址前调用 diff --git a/src/HFlashMem.c b/src/HFlashMem.c index 709563d..504b775 100644 --- a/src/HFlashMem.c +++ b/src/HFlashMem.c @@ -23,8 +23,8 @@ // 最大热度 #define MAX_HEAT ((1 << 5) - 1) -// 写转读增加热度 -#define WRITE_CONV_READ_ADD_HEAT (2) +// 写回后保留的最低热度, 避免刚刷回立刻被淘汰 +#define WRITE_BACK_KEEP_HEAT (2) // 读最小热度 #define READ_MIN_HEAT (0) @@ -100,8 +100,10 @@ static void SyncCache() sOpts->cache[i].isDirty = 0; sOpts->cache[i].eraseStatus = kEraseWait; - // 写入页转换空闲页, 热度持续增加 - sOpts->cache[i].heat = FAST_MIN(uint8_t, sOpts->cache[i].heat + WRITE_CONV_READ_ADD_HEAT, MAX_HEAT); + // 写回后只保留一个基础热度, 避免被动刷回页持续虚高 + if (sOpts->cache[i].heat < WRITE_BACK_KEEP_HEAT) { + sOpts->cache[i].heat = WRITE_BACK_KEEP_HEAT; + } } } @@ -139,8 +141,10 @@ static void FastSyncCache() sOpts->cache[i].isDirty = 0; sOpts->cache[i].eraseStatus = kEraseWait; - // 写入页转换空闲页, 热度持续增加 - sOpts->cache[i].heat = FAST_MIN(uint8_t, sOpts->cache[i].heat + WRITE_CONV_READ_ADD_HEAT, MAX_HEAT); + // 写回后只保留一个基础热度, 避免被动刷回页持续虚高 + if (sOpts->cache[i].heat < WRITE_BACK_KEEP_HEAT) { + sOpts->cache[i].heat = WRITE_BACK_KEEP_HEAT; + } break; } @@ -204,8 +208,10 @@ static void CheckSyncCache() sOpts->cache[i].isDirty = 0; sOpts->cache[i].eraseStatus = kEraseWait; - // 写入页转换空闲页, 热度持续增加 - sOpts->cache[i].heat = FAST_MIN(uint8_t, sOpts->cache[i].heat + WRITE_CONV_READ_ADD_HEAT, MAX_HEAT); + // 写回后只保留一个基础热度, 避免被动刷回页持续虚高 + if (sOpts->cache[i].heat < WRITE_BACK_KEEP_HEAT) { + sOpts->cache[i].heat = WRITE_BACK_KEEP_HEAT; + } } if (needErase != sInfo.useNum) { @@ -229,7 +235,7 @@ static void StartSyncCache() sCheckTimer = HTIMER_INVALID; } - sCheckTimer = HTimerAdd(HFLASH_TIMER_ID, 0, CheckSyncCache, kHTimerLoop); + sCheckTimer = HTimerAdd(HFLASH_TIMER_ID, 1, CheckSyncCache, kHTimerLoop); } static void ScheduleHeat() @@ -250,6 +256,39 @@ static void ScheduleHeat() sInfo.currHeatTime = HDLogGetTime(); } +static HFlashMemCache *FindCacheByAddr(uint32_t addr) +{ + for (uint16_t i = 0; i < sInfo.useNum; ++i) { + if (addr != sOpts->cache[i].addr) { + continue; + } + + return sOpts->cache + i; + } + + return NULL; +} + +static void ResetCache(HFlashMemCache *cache, uint32_t addr, uint16_t index) +{ + memset(cache, 0, sizeof(HFlashMemCache)); + cache->addr = addr; + cache->offset = index; + cache->heat = READ_MIN_HEAT; +} + +static HFlashMemCache *AllocCache(void) +{ + if (sInfo.useNum >= sOpts->cacheSize) { + return NULL; + } + + const uint16_t index = sInfo.useNum; + ++sInfo.useNum; + ResetCache(sOpts->cache + index, 0, index); + return sOpts->cache + index; +} + static HFlashMemCache *FindMinHeatCache() { int16_t index = -1; @@ -290,45 +329,25 @@ static HFlashMemCache *FindReadCache(uint32_t addr, uint8_t needRead) return NULL; } - for (uint16_t i = 0; i < sInfo.useNum; ++i) { - if (addr != sOpts->cache[i].addr) { - continue; - } - - sOpts->cache[i].heat = FAST_MIN(uint8_t, sOpts->cache[i].heat + 1, MAX_HEAT); - return sOpts->cache + i; + HFlashMemCache *cache = FindCacheByAddr(addr); + if (cache) { + cache->heat = FAST_MIN(uint8_t, cache->heat + 1, MAX_HEAT); + return cache; } - // 如果缓存没有满, 直接增加 if (sInfo.useNum < sOpts->cacheSize) { - const uint16_t index = sInfo.useNum; - ++sInfo.useNum; - if (needRead) { - WatiErase(); - if (sOpts->read(addr, GetMMap(index), HFLASH_BLOCK_SIZE) == 0) { - LogE("addr[0x%08x], read faild", addr); - return NULL; - } - } - - memset(sOpts->cache + index, 0, sizeof(HFlashMemCache)); - sOpts->cache[index].addr = addr; - sOpts->cache[index].offset = index; - sOpts->cache[index].heat = FAST_MIN(uint8_t, sOpts->cache[index].heat + 1, MAX_HEAT); - return sOpts->cache + index; + cache = AllocCache(); + } + if (cache == NULL) { + cache = FindMinHeatCache(); } - // 查找空闲的最低热度页 - HFlashMemCache *cache = FindMinHeatCache(); - if (cache == NULL || cache->heat > READ_MIN_HEAT) { + if (cache == NULL) { return NULL; } const uint16_t index = cache->offset; - memset(cache, 0, sizeof(HFlashMemCache)); - cache->addr = addr; - cache->offset = index; - cache->heat = READ_MIN_HEAT; + ResetCache(cache, addr, index); if (needRead) { WatiErase(); @@ -338,6 +357,7 @@ static HFlashMemCache *FindReadCache(uint32_t addr, uint8_t needRead) } } + cache->heat = FAST_MIN(uint8_t, cache->heat + 1, MAX_HEAT); return cache; } @@ -349,8 +369,29 @@ static HFlashMemCache *FindWriteCache(uint32_t addr, uint8_t needRead) return NULL; } - HFlashMemCache *cache = FindReadCache(addr, needRead); + HFlashMemCache *cache = FindCacheByAddr(addr); if (cache) { + cache->heat = FAST_MIN(uint8_t, cache->heat + 1, MAX_HEAT); + return cache; + } + + if (sInfo.useNum < sOpts->cacheSize) { + cache = AllocCache(); + if (cache == NULL) { + return NULL; + } + + const uint16_t index = cache->offset; + ResetCache(cache, addr, index); + if (needRead) { + WatiErase(); + if (sOpts->read(addr, GetMMap(index), HFLASH_BLOCK_SIZE) == 0) { + LogE("addr[0x%08x], read faild", addr); + return NULL; + } + } + + cache->heat = FAST_MIN(uint8_t, cache->heat + 1, MAX_HEAT); return cache; } @@ -364,10 +405,7 @@ static HFlashMemCache *FindWriteCache(uint32_t addr, uint8_t needRead) } const uint16_t index = cache->offset; - memset(cache, 0, sizeof(HFlashMemCache)); - cache->addr = addr; - cache->offset = index; - cache->heat = READ_MIN_HEAT; + ResetCache(cache, addr, index); if (needRead) { WatiErase(); // 找到一个空闲且最低温度的 @@ -377,6 +415,7 @@ static HFlashMemCache *FindWriteCache(uint32_t addr, uint8_t needRead) } } + cache->heat = FAST_MIN(uint8_t, cache->heat + 1, MAX_HEAT); return cache; } @@ -501,6 +540,24 @@ void HFlashMemInit(HFlashMemOpts *opts) FATAL_ERROR("flash Size not 4k align"); return ; } + + if (sCheckTimer != HTIMER_INVALID) { + HTimerRemove(sCheckTimer); + sCheckTimer = HTIMER_INVALID; + } + + sInfo.currHeatTime = HDLogGetTime(); + sInfo.needWaitErase = 0; + sInfo.useNum = 0; + for (uint16_t i = 0; i < sOpts->cacheSize; ++i) { + if (sOpts->cache[i].addr == 0 && sOpts->cache[i].eraseStatus == 0 && + sOpts->cache[i].isDirty == 0 && + sOpts->cache[i].heat == 0) { + continue; + } + + sInfo.useNum = i + 1; + } } const HFlashMemOpts *HFlashMemGetOpt() @@ -661,4 +718,3 @@ void HFlashMemFreeCache() sInfo.useNum = 0; sInfo.currHeatTime = HDLogGetTime(); } - diff --git a/src/HFlashServer.c b/src/HFlashServer.c index 54b1dda..7feb14b 100644 --- a/src/HFlashServer.c +++ b/src/HFlashServer.c @@ -2,7 +2,6 @@ #include "HFlashServer.h" #include "HDLog.h" -#include "HVector.h" #include "HTimer.h" #if HFLASH_USE_HSHELL #include "HShellLex.h" @@ -20,6 +19,9 @@ #include "HSCrc32.h" #endif +#if !HFLASH_USE_BITMAP +#include "HVector.h" +#endif #ifdef USE_STD_MEM #include @@ -66,6 +68,11 @@ void HDMainLoopCallOverride(uint8_t event) #define IS_NOT_4K(size) ((size & (HFLASH_BLOCK_SIZE - 1)) != 0) #define ALIGN_4K(size) (((size) + HFLASH_BLOCK_SIZE - 1) & ~(HFLASH_BLOCK_SIZE - 1)) +// 计算bitMap地址 +#define CALC_BITMAP_INDEX(addr) ((addr) >> 12) +// 从bitMap计算flash偏移地址 +#define CALC_FLASH_BITMAP_OFFSET(index) ((index) << 12) + #if HFLASH_USE_HSHELL enum eShell { @@ -133,8 +140,10 @@ static HTimer_t sSyncPageTimer = HTIMER_INVALID; // 同步页表缓存定时器 static HTimer_t sSyncCacheTimer = HTIMER_INVALID; +#if !HFLASH_USE_BITMAP // 存储需要备份的保护区地址页偏移 static HVECTOR_DEFINE32(sNeedBackupOffset, 10); +#endif static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size); static uint8_t RestoreBackupRange(HFlashAddr_t addr, uint32_t size); @@ -152,6 +161,7 @@ static uint32_t GetBackupCrc32(HFlashAddr_t addr, uint32_t size); static uint8_t GetBackupAddr(HFlashAddr_t addr, uint32_t size, HFlashAddr_t *backupAddr); static uint8_t GetProtectBackupRange(HFlashAddr_t addr, uint32_t size, HFlashAddr_t *backupStartAddr, uint32_t *backupSize); static inline uint32_t AdjustProtectBackupSize(HFlashAddr_t addr, uint32_t size); +static void ClearProtectInfoEntry(HFlashProtectInfo *info); static void ResetRuntimeState() { @@ -172,7 +182,15 @@ static void ResetRuntimeState() sSyncCacheTimer = HTIMER_INVALID; } +#if HFLASH_USE_BITMAP + for (uint16_t i = 0; i < sInfo.protectCacheSize; ++i) { + if (sInfo.protectInfo[i].bitMap) { + HBitMapFill(sInfo.protectInfo[i].bitMap, 0); + } + } +#else HVectorClear(sNeedBackupOffset); +#endif } ///< 检查地址是否在双备份保护区内 @@ -513,6 +531,20 @@ static inline uint32_t AdjustProtectBackupSize(HFlashAddr_t addr, uint32_t size) return backupSize; } +static void ClearProtectInfoEntry(HFlashProtectInfo *info) +{ +#if HFLASH_USE_BITMAP + HBitMapType *bitMap = info->bitMap; + memset(info, 0, sizeof(HFlashProtectInfo)); + info->bitMap = bitMap; + if (bitMap != NULL) { + HBitMapFill(bitMap, 0); + } +#else + memset(info, 0, sizeof(HFlashProtectInfo)); +#endif +} + static void SyncBackup() { LogD("Start sync Backup"); @@ -521,6 +553,34 @@ static void SyncBackup() sBackupTimer = HTIMER_INVALID; } +#if HFLASH_USE_BITMAP + for (uint16_t i = 0; i < sInfo.protectUseNum; ++i) { + HFlashAddr_t protectStartAddr = 0; + uint32_t backupSize = 0; + if (GetProtectBackupRange(sInfo.protectInfo[i].addr, sInfo.protectInfo[i].size, &protectStartAddr, &backupSize) == 0) { + return ; + } + + (void)backupSize; + HBitMapIndexType index = 0; + for (;;) { + index = HBitMapFindFirstSetBitIndex(sInfo.protectInfo[i].bitMap, index); + if (index == kHBitMapInvalidIndex) { + break; + } + + const uint32_t addr = protectStartAddr + CALC_FLASH_BITMAP_OFFSET(index); + if (SyncBackupRange(addr, HFLASH_BLOCK_SIZE) == 0) { + LogE("RestorePage faild, addr[0x%08x]", addr); + StartSyncBackupTimer(); + return ; + } + + HBitMapSetBit(sInfo.protectInfo[i].bitMap, index, 0); + ++index; + } + } +#else for (HVectorLenType remain = HVectorGetUseLen(sNeedBackupOffset); remain > 0; --remain) { const uint32_t addr = HVectorGetData(sNeedBackupOffset, remain - 1); if (SyncBackupRange(addr, HFLASH_BLOCK_SIZE) == 0) { @@ -531,6 +591,7 @@ static void SyncBackup() HVectorSetUseLen(sNeedBackupOffset, remain - 1); } +#endif // 备份页表数据 const uint32_t crcValue = GetBackupCrc32(AdjustPageAddr(sInfo.pageAddr), AdjustPageByte(sPageInfo.useNum)); @@ -550,8 +611,27 @@ static void StartSyncBackupTimer() sBackupTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_BACKUP_TIME, SyncBackup, kHTimerOnce); } -static void _AddBackupAddr(uint32_t addr) +static void _AddBackupAddr(uint32_t addr, int16_t protecIndex) { +#if HFLASH_USE_BITMAP + HFlashAddr_t protectStartAddr = 0; + uint32_t backupSize = 0; + HFlashProtectInfo *info = &sInfo.protectInfo[protecIndex]; + if (GetProtectBackupRange(info->addr, info->size, &protectStartAddr, &backupSize) == 0) { + return ; + } + + if (addr < protectStartAddr || addr >= (protectStartAddr + backupSize)) { + LogE("protect bitmap addr[0x%08x] out of range[0x%08x][0x%08x]", + addr, + protectStartAddr, + protectStartAddr + backupSize); + return ; + } + + HBitMapSetBit(info->bitMap, (addr - protectStartAddr) >> 12, 1); + LogD("Add wait sync addr[0x%08x]", addr); +#else do { const HVectorLenType index = HVectorFindData(sNeedBackupOffset, addr); if (index != HVECTOR_ERROR) { @@ -571,12 +651,14 @@ static void _AddBackupAddr(uint32_t addr) } while (0); LogD("Add wait sync addr[0x%08x], size[%d]", addr, HVectorGetUseLen(sNeedBackupOffset)); +#endif StartSyncBackupTimer(); } static void AddBackupAddr(uint32_t addr, uint32_t size) { - if (IsProtect(addr, size) == 0) { + int16_t protectIndex = FindProtectIndex(addr, size); + if (protectIndex < 0) { return ; } @@ -585,24 +667,20 @@ static void AddBackupAddr(uint32_t addr, uint32_t size) const uint16_t offset = addr - adjustAddr; uint32_t remain = offset + size > HFLASH_BLOCK_SIZE ? HFLASH_BLOCK_SIZE - offset : size; - _AddBackupAddr(adjustAddr); + _AddBackupAddr(adjustAddr, protectIndex); size -= remain; adjustAddr += HFLASH_BLOCK_SIZE; for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE) { - _AddBackupAddr(adjustAddr); + _AddBackupAddr(adjustAddr, protectIndex); } if (size) { - _AddBackupAddr(adjustAddr); + _AddBackupAddr(adjustAddr, protectIndex); } } static void AddBackupOffsetAddr(uint32_t addr, uint32_t offset, uint32_t size) { - if (IsProtect(addr, size) == 0) { - return ; - } - AddBackupAddr(addr + offset, size); } @@ -1164,22 +1242,42 @@ void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size) sInfo.pageCacheSize = size; } +void HFlashInitProtectCache(HFlashProtectInfo *protectInfo, void *bitMap, uint32_t size) +{ + memset(protectInfo, 0, sizeof(HFlashProtectInfo)); +#if HFLASH_USE_BITMAP + if (HBitMapInit(bitMap, HFLASH_CALC_BITMAP_SIZE(size)) == 0) { + FATAL_ERROR("bitmap init fail"); + return ; + } + + protectInfo->bitMap = bitMap; +#endif +} + void HFlashSetProtectCache(HFlashProtectInfo *protectInfo, uint16_t size) { ResetRuntimeState(); sInfo.protectInfo = protectInfo; sInfo.protectCacheSize = size; sInfo.protectUseNum = 0; +#if HFLASH_USE_BITMAP + for (uint16_t i = 0; i < size; ++i) { + if (sInfo.protectInfo[i].bitMap != NULL) { + continue; + } - if (protectInfo != NULL && size) { - memset(protectInfo, 0, size * sizeof(HFlashProtectInfo)); + FATAL_ERROR("protect cache[0x%08x] not init", sInfo.protectInfo[i].addr); + return ; } +#endif } void HFlashSetPageAddr(HFlashAddr_t addr, uint32_t size) { if (IS_NOT_4K(addr) || IS_NOT_4K(size)) { FATAL_ERROR("not align page size[0x%08x], size[%x]", addr, size); + return ; } sInfo.pageAddr = addr; @@ -1270,7 +1368,9 @@ void HFlashClearProtectAddr() ResetRuntimeState(); sInfo.protectUseNum = 0; if (sInfo.protectInfo != NULL && sInfo.protectCacheSize) { - memset(sInfo.protectInfo, 0, sInfo.protectCacheSize * sizeof(HFlashProtectInfo)); + for (uint16_t i = 0; i < sInfo.protectCacheSize; ++i) { + ClearProtectInfoEntry(&sInfo.protectInfo[i]); + } } } @@ -1302,6 +1402,13 @@ void HFlashAddProtectAddr(HFlashAddr_t addr, uint32_t size, HFlashAddr_t backupA } HFlashProtectInfo *info = &sInfo.protectInfo[sInfo.protectUseNum]; + ClearProtectInfoEntry(info); +#if HFLASH_USE_BITMAP + if (HBitMapGetBitLen(info->bitMap) < (AdjustProtectBackupSize(addr, size) >> 12)) { + FATAL_ERROR("protect addr[0x%08x] bitmap too small", addr); + return ; + } +#endif info->addr = addr; info->size = size; info->backupAddr = backupAddr; @@ -1318,11 +1425,18 @@ void HFlashDelProtectAddr(HFlashAddr_t addr) ResetRuntimeState(); for (uint16_t i = (uint16_t)index; i + 1 < sInfo.protectUseNum; ++i) { +#if HFLASH_USE_BITMAP + HBitMapType *currBitMap = sInfo.protectInfo[i].bitMap; sInfo.protectInfo[i] = sInfo.protectInfo[i + 1]; + sInfo.protectInfo[i].bitMap = currBitMap; + HBitMapFill(sInfo.protectInfo[i].bitMap, 0); +#else + sInfo.protectInfo[i] = sInfo.protectInfo[i + 1]; +#endif } --sInfo.protectUseNum; - memset(&sInfo.protectInfo[sInfo.protectUseNum], 0, sizeof(HFlashProtectInfo)); + ClearProtectInfoEntry(&sInfo.protectInfo[sInfo.protectUseNum]); } static uint8_t CheckBackupArea() @@ -1537,6 +1651,18 @@ static uint8_t _CheckOverLap(uint32_t index, HFlashPageInfo *info, void *userDat return IsOverLap(info->addr, info->size, cache->info.addr, cache->info.size); } + +static uint8_t HasProtectOverlap(HFlashAddr_t addr, uint32_t size) +{ + for (uint16_t i = 0; i < sInfo.protectUseNum; ++i) { + if (IsOverLap(addr, size, sInfo.protectInfo[i].addr, sInfo.protectInfo[i].size)) { + return 1; + } + } + + return 0; +} + void HFlashRegister(HFlashAddr_t addr, uint32_t size) { if (IS_NOT_4(size)) { @@ -1544,6 +1670,11 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size) return ; } + if (HasProtectOverlap(addr, size) && IsProtect(addr, size) == 0) { + FATAL_ERROR("addr[0x%08x] size[%d] partial overlap protect range", addr, size); + return ; + } + HFlashCacheInfo *cache = FindCache(addr); if (cache == NULL) { // 首次创建页表, 不需要检查 @@ -1646,12 +1777,10 @@ uint8_t HFlashWrite(HFlashAddr_t addr, const void *data, uint32_t size) cache->info.useSize = size; } - // 更新crc, 写入数据后再更新页表 - HSCrc32Reset(); - HSCrc32Update((uint8_t *)data, cache->info.useSize); - cache->info.crc32 = HSCrc32Get(); - result = WriteFlash(addr, data, size); + if (result) { + cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize); + } WriteCachePage(cache); // 检查是否在保护区域, 需要的话需要写入等待备份