From 276218d3e038aeefd3da5fa6cff8f2dd8da5dfbb Mon Sep 17 00:00:00 2001 From: coffee Date: Wed, 3 Dec 2025 10:31:36 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=95=BF=E5=BA=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HFlashServer.h | 9 ++++- src/HFlashServer.c | 79 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/include/HFlashServer.h b/include/HFlashServer.h index 008056f..d3567da 100644 --- a/include/HFlashServer.h +++ b/include/HFlashServer.h @@ -272,10 +272,17 @@ uint32_t HFlashGetUseSize(HFlashAddr_t addr); uint32_t HFlashGetSize(HFlashAddr_t addr); /** - * @brief HFlashGetCrc32 获取Flash数据的CRC32值 + * @brief HFlashGetCrc32 获取页表记录的CRC32值 * @param addr 需要注册的地址 * @return CRC32 */ uint32_t HFlashGetCrc32(HFlashAddr_t addr); +/** + * @brief HFlashCalcCrc32 计算Flash数据的CRC32值 + * @param addr 需要注册的地址 + * @return CRC32 + */ +uint32_t HFlashCalcCrc32(HFlashAddr_t addr); + #endif // __H_FLASH_SERVER_H__ diff --git a/src/HFlashServer.c b/src/HFlashServer.c index deb9479..15cca52 100644 --- a/src/HFlashServer.c +++ b/src/HFlashServer.c @@ -4,6 +4,8 @@ #include "HDLog.h" #include "HVector.h" #include "HTimer.h" +#include "HShellLex.h" +#include #ifndef USE_STD_MEM #include "HDSendBuffer.h" @@ -46,6 +48,17 @@ uint32_t HSCrc32Get() // 检查是不是4对齐 #define IS_NOT_4(size) ((size & (4 - 1)) != 0) +enum eShell +{ + kShellPageInfo, ///< 查看页表信息 + kShellMax, +}; + +static HShellMatch sShellMatch[] = { + HSHELL_MATCH_ITEM(kShellPageInfo, "pageInfo"), +}; + + union PageInfo { uint8_t reverse[32]; ///< 每页的信息占用32字节 struct __attribute__((packed)) { @@ -672,8 +685,41 @@ void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size) sInfo.protectSize = size; } +static uint8_t _Print(uint32_t index, HFlashPageInfo *info, void *userData) +{ + uint32_t *arg1 = (uint32_t *)userData; + if (*arg1 == -1) { + HSHELL_PRINTFL("page[%d], addr[0x%08x], useSize[0x%x], size[0x%x], modifyCount[%d], crc32[0x%x], version[%d]", index, info->addr, info->useSize, info->size, info->modifyCount, info->crc32, info->version); + return 0; + } + + if (index == *arg1) { + HSHELL_PRINTFL("page[%d], addr[0x%08x], useSize[0x%x], size[0x%x], modifyCount[%d], crc32[0x%x], version[%d]", index, info->addr, info->useSize, info->size, info->modifyCount, info->crc32, info->version); + return 1; + } + + return 0; +} + +static void Shell(HSHELL_FUNC_ARGS) +{ + uint32_t arg1 = 0; + if (HSHellToUint32(tokens, tokensLen, 0, &arg1) == 0) { + arg1 = -1; + } + + switch (key) { + case kShellPageInfo: { + ScanPage(_Print, &arg1); + } break; + default: + break; + } +} + void HFlashInitCheck() { + HSHellRegister(sShellMatch, sizeof(sShellMatch) / sizeof(HShellMatch), Shell, 0); if (sInfo.pageCache == NULL || sInfo.pageCacheSize == 0) { FATAL_ERROR("pageCache is null"); return ; @@ -803,12 +849,22 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size) LogE("addr[0x%08x] size[%d] crc32 not match, restore faild", cache->info.addr, cache->info.size); RestorePage(cache->pos); ReadPage(cache->pos, &cache->info); - if (contentCrc == cache->info.crc32) { + do { + // 如果恢复页表数据后, 大小不一致, 说明用户在调整大小, 放弃数据, 不恢复 + if (cache->info.size != size) { + break; + } + + // 恢复后数据校验不一致, 需要重置 + if (contentCrc != cache->info.crc32) { + break; + } + return ; - } + } while (0); // 恢复后数据还是错误的, 需要将该页表数据重新初始化 - LogE("addr[0x%08x] size[%d] crc32 not match", cache->info.addr, cache->info.size); + LogE("addr[0x%08x] size[%d] newSize[%d] crc32 not match", cache->info.addr, cache->info.size, size); memset(cache->info.reverse, 0, sizeof(cache->info)); cache->info.addr = addr; cache->info.useSize = 0; @@ -833,14 +889,14 @@ uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size) return result; } - // 更新使用长度 + // 更新使用长度, 直接重写比较短的数据不要影响使用长度 if (cache->info.useSize < size) { cache->info.useSize = size; } // 更新crc, 写入数据后再更新页表 HSCrc32Reset(); - HSCrc32Update((uint8_t *)data, size); + HSCrc32Update((uint8_t *)data, cache->info.useSize); cache->info.crc32 = HSCrc32Get(); result = WriteFlash(addr, data, size); @@ -879,8 +935,8 @@ uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32 cache->info.useSize = useSize; } - cache->info.crc32 = GetFlashCrc32(addr, useSize); result = WriteFlash(addr + offset, data, size); + cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize); WriteCachePage(cache); // 检查是否在保护区域, 需要的话需要写入等待备份 @@ -1065,3 +1121,14 @@ uint32_t HFlashGetCrc32(HFlashAddr_t addr) return cache->info.crc32; } +uint32_t HFlashCalcCrc32(HFlashAddr_t addr) +{ + HFlashCacheInfo *cache = FindCache(addr); + if (cache == NULL) { + FATAL_ERROR("addr[0x%08x] not register", addr); + return 0xFFFFFFFF; + } + + return GetFlashCrc32(addr, cache->info.useSize); +} +