From 150d642f22e48a048db9520e053089e99b467015 Mon Sep 17 00:00:00 2001 From: coffee Date: Fri, 5 Dec 2025 11:19:08 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=A2=9E=E5=8A=A0=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=97=A5=E5=BF=97=202.=20=E4=BC=98=E5=8C=96Flash=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HDLog.h | 25 +++++++-- include/HFlashServer.h | 2 +- src/HDLog.c | 30 +++++++++++ src/HFlashServer.c | 112 +++++++++++++++++++++++++++++++++-------- 4 files changed, 145 insertions(+), 24 deletions(-) diff --git a/include/HDLog.h b/include/HDLog.h index 881da37..4e54ba5 100644 --- a/include/HDLog.h +++ b/include/HDLog.h @@ -5,6 +5,7 @@ #include #include +#include // 使用宏开关管理日志 #ifndef LOG_CLOSE_OUT @@ -13,6 +14,7 @@ #define USE_HD_LOG_DATA (1) #define USE_HD_TRACE (1) #define USE_HD_FPGA_CHECK (1) +#define USE_HD_OPT_LOG (1) #endif // 当前检查栈数量的线程总数 @@ -89,6 +91,13 @@ #endif #define InitLogData() HDLogInit(NULL) +// 操作日志 +#if USE_HD_OPT_LOG +#define LogOpt(format, ...) HDLogOptOut(format, ##__VA_ARGS__) +#else +#define LogOpt(...) +#endif + typedef enum eLogLevel { kLogLevelSwitch = 0, ///< 日志开关 kLogLevelColor, ///< 彩色日志 @@ -120,17 +129,27 @@ void HDLogOptFlashInit(); void HDLogInit(uint32_t (*getTime)()); /** - * @brief 获取当前时间 - * @return 当前时间 + * @brief 设置操作日志输出回调 + * @param call 日志输出调用 + */ +void HDLogSetOptCall(void (*call)(const char *format, va_list args)); + +/** + * @brief 获取运行时间 + * @return 运行时间 */ uint32_t HDLogGetTime(); /** * @brief 格式打印 **/ -__attribute__ ((format(printf, 6, 7))) void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *funcName, int line, const char *format, ...); +/** + * @brief 操作日志格式打印 + */ +void HDLogOptOut(const char *format, ...); + /** * @brief 打印FPGA * @param data FPGA数据 diff --git a/include/HFlashServer.h b/include/HFlashServer.h index d136345..cb83568 100644 --- a/include/HFlashServer.h +++ b/include/HFlashServer.h @@ -22,7 +22,7 @@ #define HFLASH_BLOCK_SIZE (4096) #endif -///< 获取缓存内存, 需要能申请到大于等于Flash一块大小 +///< 获取缓存内存, 需要能申请到大于等于(Flash一块大小 + 1024) #ifndef HFLASH_MALLOC #ifdef USE_STD_MEM #define HFLASH_MALLOC(size) malloc(size) diff --git a/src/HDLog.c b/src/HDLog.c index 53a54f6..a9e5ff8 100644 --- a/src/HDLog.c +++ b/src/HDLog.c @@ -55,11 +55,24 @@ static HShellMatch sLogMatch[] = { #endif }; +///< 日志级别 static HBIT_DEFINE(sLogItem, kLogLevelMax); + +///< 获取运行时间回调 static uint32_t (*sGetTime)() = NULL; + +///< 日志操作回调 +static void (*sOperateCall)(const char *format, va_list args) = NULL; + +///< 获取当前任务回调 static HDLogGetTaskType_t sGetCurrTask = NULL; + +///< 获取当前任务栈回调 static HDLogGetStackSizeType_t sGetCurrStackSize = NULL; + +///< 获取Flash配置回调 static HDLogFlashOpt_t sFlashCall = NULL; + #if USE_SYS_CHECK_HEAP static HDLogGetStackSizeType_t sGetCurrHeapSize = NULL; #endif @@ -252,6 +265,11 @@ void HDLogInit(uint32_t (*getTime)()) #endif } +void HDLogSetOptCall(void (*call)(const char *format, va_list args)) +{ + sOperateCall = call; +} + uint32_t HDLogGetTime() { if (sGetTime) @@ -351,6 +369,18 @@ void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *func LOG_UNLOCK(); } +void HDLogOptOut(const char *format, ...) +{ + va_list args; + va_start(args, format); + if (sOperateCall) + { + sOperateCall(format, args); + } + + va_end(args); +} + static void HDLogFpgaError(const uint8_t *data, int len, uint8_t isWrite, uint8_t checkFpga) { if (checkFpga == 0) diff --git a/src/HFlashServer.c b/src/HFlashServer.c index e2feba7..f1a8119 100644 --- a/src/HFlashServer.c +++ b/src/HFlashServer.c @@ -47,19 +47,22 @@ uint32_t HSCrc32Get() // 检查是不是4对齐 #define IS_NOT_4(size) ((size & (4 - 1)) != 0) +#define IS_NOT_4K(size) ((size & (HFLASH_BLOCK_SIZE - 1)) != 0) enum eShell { kShellPageInfo, ///< 查看页表信息 kShellDelUseDataPage, ///< 删除页表使用数据 kShellDelPage, ///< 删除页 + kShellResetPage, ///< 重置页 kShellMax, }; static HShellMatch sShellMatch[] = { HSHELL_MATCH_ITEM(kShellPageInfo, "pageInfo"), - HSHELL_MATCH_ITEM(kShellDelUseDataPage, "pagedelUseData"), + HSHELL_MATCH_ITEM(kShellDelUseDataPage, "pageDelUseData"), HSHELL_MATCH_ITEM(kShellDelPage, "pageDel"), + HSHELL_MATCH_ITEM(kShellResetPage, "pageReset"), }; @@ -129,6 +132,11 @@ static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size) return 1; } +static inline uint32_t Aligned4K(uint32_t value) +{ + return (value + (HFLASH_BLOCK_SIZE - 1)) & ~(HFLASH_BLOCK_SIZE - 1); +} + static uint8_t ReadFlash(HFlashAddr_t addr, void *data, uint32_t size) { if (sInfo.read == NULL) { @@ -236,6 +244,36 @@ _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; @@ -258,6 +296,21 @@ static uint8_t WriteFlashValue(uint32_t addr, uint32_t size, uint8_t value) return WriteData(addr, NULL, size, _WriteFalshValueHelper, &value); } +static inline uint32_t AdjustPageAddr(uint32_t addr) +{ + return addr + sizeof(sPageInfo); +} + +static inline uint32_t AdjustPageAddrOffset(uint32_t addr, uint32_t offset) +{ + return addr + sizeof(sPageInfo) + offset * sizeof(HFlashPageInfo); +} + +static inline uint32_t AdjustPageByte(uint32_t index) +{ + return index * sizeof(HFlashPageInfo); +} + static void SyncBackup() { LogD("Start sync Backup"); @@ -284,7 +337,9 @@ static void SyncBackup() HVectorClear(sNeedBackupOffset); // 备份页表数据 - RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, sInfo.pageSize); + uint32_t backSize = Aligned4K(AdjustPageAddr(sPageInfo.useNum + 1)); + backSize = FLASH_MIN(uint32_t, backSize, sInfo.pageSize); + RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, backSize); sPageInfo.needBackupPage = 0; } @@ -425,7 +480,9 @@ static void AddDelayCrc32(HFlashAddr_t addr) static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size) { - const uint16_t mallocSize = 1024; + // 检查是不是页对齐数据, 是的话不用再回读写, 直接读写 + 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 (buff == NULL) { LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, size); @@ -438,7 +495,12 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_ 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; + if (isAlignPage) { + // 是对齐大小直接回写 + result = result || WriteAlignData(dstAddr + i, buff, remain) == 0; + } else { + result = result || WriteFlash(dstAddr + i, buff, remain) == 0; + } if (result) { LogE("read addr[0x%08x], write addr[0x%08x], write size[%d] faild", srcAddr + i, dstAddr + i, remain); @@ -450,25 +512,10 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_ result = 1; _FlashError: HFLASH_FREE(buff); - LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d], result[%d]", srcAddr, dstAddr, size, result); + LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d], result[%d], malloc[%d]", srcAddr, dstAddr, size, result, mallocSize); return result; } -static inline uint32_t AdjustPageAddr(uint32_t addr) -{ - return addr + sizeof(sPageInfo); -} - -static inline uint32_t AdjustPageAddrOffset(uint32_t addr, uint32_t offset) -{ - return addr + sizeof(sPageInfo) + offset * sizeof(HFlashPageInfo); -} - -static inline uint32_t AdjustPageByte(uint32_t index) -{ - return index * sizeof(HFlashPageInfo); -} - ///< 恢复指定页表 static uint8_t RestorePage(uint32_t index) { @@ -741,12 +788,20 @@ void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size) 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); + } + sInfo.pageAddr = addr; sInfo.pageSize = size; } void HFlashSetPageBackupAddr(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); + } + if (sInfo.pageSize != size) { FATAL_ERROR("page size not match[%d][%d]", sInfo.pageSize, size); return ; @@ -758,12 +813,20 @@ void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size) void HFlashSetProtectAddr(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); + } + sInfo.protectAddr = addr; sInfo.protectSize = size; } void HFlashSetProtectBackupAddr(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); + } + if (sInfo.protectSize != size) { FATAL_ERROR("protect size not match[%d][%d]", sInfo.protectSize, size); return ; @@ -823,6 +886,15 @@ static void Shell(HSHELL_FUNC_ARGS) cache->info.invalid = 1; WriteCachePage(cache); } break; + case kShellResetPage: { + if (arg1 >= sPageInfo.pageNum) { + HSHELL_PRINTFL("index[%d] over max[%d]", arg1, sPageInfo.pageNum); + return ; + } + + sPageInfo.useNum = arg1; + UpdatePageInfo(); + } break; default: break; }