diff --git a/include/HFlashServer.h b/include/HFlashServer.h index 53c95f9..008056f 100644 --- a/include/HFlashServer.h +++ b/include/HFlashServer.h @@ -8,8 +8,15 @@ #ifndef __H_FLASH_SERVER_H__ #define __H_FLASH_SERVER_H__ +// #define USE_STD_MEM + #include +#ifndef USE_STD_MEM +#include "HDSendBuffer.h" +#endif + + ///< Flash块大小, 按块操作, 2的幂关系 #ifndef HFLASH_BLOCK_SIZE #define HFLASH_BLOCK_SIZE (4096) @@ -17,12 +24,20 @@ ///< 获取缓存内存, 需要能申请到大于等于Flash一块大小 #ifndef HFLASH_MALLOC +#ifdef USE_STD_MEM #define HFLASH_MALLOC(size) malloc(size) +#else +#define HFLASH_MALLOC(size) HDSendBufferGet(size) +#endif #endif ///< 释放缓存 #ifndef HFLASH_FREE +#ifdef USE_STD_MEM #define HFLASH_FREE(ptr) free(ptr) +#else +#define HFLASH_FREE(ptr) HDSendBufferFree(ptr) +#endif #endif ///< 定时器ID @@ -133,7 +148,8 @@ void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size); void HFlashInitCheck(); /** - * @brief HFlashRegister 注册地址到页表 + * @brief HFlashRegister 注册地址到页表, 如果大小和之前不一致会丢弃原数据更新 + * 但保护区域是特殊的, 请勿缩小保护区域的使用大小 * @param addr 地址 * @param size 该地址占用的大小 */ @@ -235,6 +251,26 @@ typedef void (*HFlashUpdateVersionCallback)(HFlashAddr_t addr, uint16_t oldVersi */ void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData); +/** + * @brief HFlashDeleteFile 删除地址内容 + * @param addr 需要注册的地址 + */ +void HFlashDeleteData(HFlashAddr_t addr); + +/** + * @brief HFlashGetUseSize 获取Flash数据的使用大小 + * @param addr 需要注册的地址 + * @return 使用大小 + */ +uint32_t HFlashGetUseSize(HFlashAddr_t addr); + +/** + * @brief HFlashGetSize 获取Flash数据的大小 + * @param addr 需要注册的地址 + * @return 大小 + */ +uint32_t HFlashGetSize(HFlashAddr_t addr); + /** * @brief HFlashGetCrc32 获取Flash数据的CRC32值 * @param addr 需要注册的地址 diff --git a/src/HFlashServer.c b/src/HFlashServer.c index 07ec161..6dbfb6a 100644 --- a/src/HFlashServer.c +++ b/src/HFlashServer.c @@ -5,8 +5,13 @@ #include "HVector.h" #include "HTimer.h" +#ifndef USE_STD_MEM +#include "HDSendBuffer.h" +#include "HSCrc32.h" +#endif -#if 1 + +#ifdef USE_STD_MEM #include static uint32_t sCrcValue; void HSCrc32Reset() @@ -29,8 +34,11 @@ uint32_t HSCrc32Get() // 计算最小值 #define FLASH_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b))))) -// #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1); +#ifdef USE_STD_MEM #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); +#else +#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1); +#endif // 最大热度 #define MAX_HEAT ((1 << 4) - 1) @@ -74,6 +82,7 @@ static HVECTOR_DEFINE32(sNeedBackupOffset, 10); static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size); +static void StartBackupTimer(); ///< 检查地址是否在双备份保护区内 static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size) @@ -241,7 +250,11 @@ static void SyncBackup() for (uint16_t i = 0; i < HVectorGetUseLen(sNeedBackupOffset); ++i) { const uint32_t addr = HVectorGetData(sNeedBackupOffset, i); const uint32_t destAddr = sInfo.protectBackupAddr + (addr - sInfo.protectAddr); - RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE); + if (RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE) == 0) { + LogE("RestorePage faild, addr[0x%08x]", addr); + StartBackupTimer(); + return ; + } } HVectorClear(sNeedBackupOffset); @@ -338,7 +351,8 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size) static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size) { - uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE); + const uint16_t mallocSize = 1024; + uint8_t *buff = (uint8_t *)HFLASH_MALLOC(mallocSize); if (buff == NULL) { LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, size); return 0; @@ -347,8 +361,8 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_ uint8_t result = 0; uint32_t i = 0; uint32_t remain = 0; - for (; i < size; i += HFLASH_BLOCK_SIZE) { - remain = FLASH_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE); + for (; i < size; i += mallocSize) { + remain = FLASH_MIN(uint32_t, size - i, mallocSize); result = result || ReadFlash(srcAddr + i, buff, remain) == 0; result = result || WriteFlash(dstAddr + i, buff, remain) == 0; @@ -504,6 +518,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo return result; } +///< 检查是否重叠, 重叠返回1 static uint8_t _CreatePageInfoHelper(uint32_t index, HFlashPageInfo *info, void *userData) { HFlashPageInfo *cache = (HFlashPageInfo *)userData; @@ -734,13 +749,33 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size) return ; } + // 检查是否需要更新页表存储的大小 + if (size != cache->info.size) { + LogD("Update addr[0x%08x] size[%d], useSize[%d], oldSize[%d]", addr, size, cache->info.useSize, cache->info.size); + cache->info.size = size; + + // 检查页表地址是否和当前页表地址范围内存在重叠 + if (ScanPage(_CreatePageInfoHelper, &cache->info)) { + FATAL_ERROR("addr[0x%08x] size[%d] exist range Error", addr, size); + return ; + } + + cache->waitWrite = 1; + } + + // 已使用空间大于容量, 页表数据异常或者容量被缩小, 丢弃数据, 如果是保护区域下面会恢复 + if (cache->info.useSize > size) { + LogE("addr[0x%08x] useSize[%d] > size[%d]", addr, cache->info.useSize, size); + cache->info.useSize = 0; + } + // 检查是否在保护区域, 不是保护区域不需要检查crc校验 if (IsProtect(addr, size) == 0) { return ; } // 检查保护区域的crc是否相同 - if (GetFlashCrc32(addr, size) == cache->info.crc32) { + if (GetFlashCrc32(addr, cache->info.useSize) == cache->info.crc32) { return ; } @@ -749,7 +784,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size) RestoreBackup(sInfo.protectBackupAddr + (cache->info.addr - sInfo.protectAddr), cache->info.addr, cache->info.size); // 如果恢复后还校验失败, 那就恢复对应页表 - const uint32_t contentCrc = GetFlashCrc32(cache->info.addr, cache->info.size); + const uint32_t contentCrc = GetFlashCrc32(cache->info.addr, cache->info.useSize); if (contentCrc == cache->info.crc32) { return ; } @@ -975,6 +1010,40 @@ void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVer } } +void HFlashDeleteData(HFlashAddr_t addr) +{ + HFlashCacheInfo *cache = FindCache(addr); + if (cache == NULL) { + FATAL_ERROR("addr[0x%08x] not register", addr); + return ; + } + + cache->info.useSize = 0; + WriteCachePage(cache); +} + +uint32_t HFlashGetUseSize(HFlashAddr_t addr) +{ + HFlashCacheInfo *cache = FindCache(addr); + if (cache == NULL) { + FATAL_ERROR("addr[0x%08x] not register", addr); + return 0; + } + + return cache->info.useSize; +} + +uint32_t HFlashGetSize(HFlashAddr_t addr) +{ + HFlashCacheInfo *cache = FindCache(addr); + if (cache == NULL) { + FATAL_ERROR("addr[0x%08x] not register", addr); + return 0; + } + + return cache->info.size; +} + uint32_t HFlashGetCrc32(HFlashAddr_t addr) { HFlashCacheInfo *cache = FindCache(addr);