/** * 日期: 2025-11-27 * 作者: coffee * 描述: Flash通用服务模块, 用于保证Flash操作的完备性, 支持任意长度数据读写 */ #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) #endif ///< 获取缓存内存, 需要能申请到大于等于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 #ifndef HFLASH_TIMER_ID #define HFLASH_TIMER_ID 0 #endif ///< 同步时间ms #ifndef HFLASH_SYNC_TIME #define HFLASH_SYNC_TIME 2000 #endif ///< Flash地址类型 typedef uint32_t HFlashAddr_t; ///< Flash页表信息 typedef union HFlashPageInfo { uint8_t reverse[32]; ///< 每页的信息占用32字节 struct __attribute__((packed)) { HFlashAddr_t addr; ///< 地址 uint32_t crc32; ///< 使用大小内容的CRC32 uint32_t size : 24; ///< 大小 uint32_t useSize : 24; ///< 使用大小 uint16_t version; ///< 当前页数据的版本 uint32_t modifyCount; ///< 修改次数 }; } HFlashPageInfo; typedef struct HFlashCacheInfo { HFlashPageInfo info; ///< 页表信息 uint32_t pos : 19; ///< 存储页表信息的位置 uint32_t heat : 4; ///< 热度优先级 uint32_t waitWrite : 1; ///< 延后写入, 一般适用于流式操作或者延后复写 } HFlashCacheInfo; /** * @brief HFlashEraseCallback 擦除回调 * @param addr Flash地址 * @return 1: 擦除成功 0: 擦除失败 */ typedef uint8_t (*HFlashEraseCallback)(HFlashAddr_t addr); /** * @brief HFlashReadCallback 读取回调 * @param addr Flash地址 * @param data Flash读取写入的缓存数据内存 * @param size 缓存大小 * @return 1: 读取成功 0: 读取失败 */ typedef uint8_t (*HFlashReadCallback)(HFlashAddr_t addr, uint8_t *data, uint32_t size); /** * @brief HFlashWriteCallback 写入回调 * @param addr Flash地址 * @param data Flash读取写入的缓存数据内存 * @param size 缓存大小 * @return 1: 写入成功 0: 写入失败 */ typedef uint8_t (*HFlashWriteCallback)(HFlashAddr_t addr, uint8_t *data, uint32_t size); /** * @brief HFlashInitCallback 设置Flash初始化回调 * @param read 读取回调 * @param write 写入回调 * @param erase 擦除回调 */ void HFlashInitCallback(HFlashReadCallback read, HFlashWriteCallback write, HFlashEraseCallback erase); /** * @brief HFlashSetPageCache 设置页表缓存, 内部不构建内存, 由外部分配 * @param pageInfo 页表信息缓存 * @param size 大小 */ void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size); /** * @brief HFlashSetPageAddr 设置页表地址 * @param addr 地址 * @param size 大小 */ void HFlashSetPageAddr(HFlashAddr_t addr, uint32_t size); /** * @brief HFlashSetPageBackupAddr 设置页表备份地址, 需要先设置页表再设置备份 * @param addr 地址 * @param size 大小, 必须和页表地址大小相同 */ void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size); /** * @brief HFlashSetProtectAddr 设置保护地址, 内部会使用双备份区域 * @param addr 地址 * @param size 大小 */ void HFlashSetProtectAddr(HFlashAddr_t addr, uint32_t size); /** * @brief HFlashSetProtectBackupAddr 设置保护备份地址, 需要先设置保护地址再设置备份 * @param addr 地址 * @param size 大小, 必须和保护地址大小相同 */ void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size); /** * @brief HFlashInitCheck 在HFlashRegister前需要初始化检查, 用于检查页表是否可用, 不可用则需要初始化 */ void HFlashInitCheck(); /** * @brief HFlashRegister 注册地址到页表, 如果大小和之前不一致会丢弃原数据更新 * 但保护区域是特殊的, 请勿缩小保护区域的使用大小 * @param addr 地址 * @param size 该地址占用的大小 */ void HFlashRegister(HFlashAddr_t addr, uint32_t size); /** * @brief HFlashWrite 写入Flash数据 * @param addr 需要注册的地址 * @param data 写入数据 * @param size 写入数据大小 * @return 1: 写入成功 0: 写入失败 */ uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size); /** * @brief HFlashWriteOffset 写入从原始地址偏移后的地方写入数据, 如果偏移后的写入大小超过原未使用, 超出部分会自动写入0填充 * @param addr 需要注册的地址 * @param offset 地址偏移 * @param data 写入数据 * @param size 写入数据大小 * @return 1: 写入成功 0: 写入失败 */ uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size); /** * @brief HFlashStreamBegin 开始流式写入, 重置使用长度 * @param addr 需要注册的地址 */ void HFlashStreamBegin(HFlashAddr_t addr); /** * @brief HFlashStreamWrite 不断添加数据, 不立刻计算CRC, 调度长度和写入Flash数据即可 * @param addr 需要注册的地址 * @param data 写入数据 * @param size 写入数据大小 * @return 1: 写入成功 0: 写入失败 */ uint8_t HFlashStreamWrite(HFlashAddr_t addr, void *data, uint32_t size); /** * @brief HFlashStreamEnd 结束流式写入, 计算CRC * @param addr 需要注册的地址 */ void HFlashStreamEnd(HFlashAddr_t addr); /** * @brief HFlashRawWrite 原始写入Flash数据, 不校验任何东西, 正常情况下不建议使用 * @param addr 地址 * @param data 写入数据 * @param size 写入数据大小 * @return 1: 写入成功 0: 写入失败 */ uint8_t HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size); /** * @brief HFlashRead 读取Flash数据 * @param addr 需要注册的地址 * @param data 读取数据写入的缓存内存 * @param size 读取数据大小 * @return 1: 读取成功 0: 读取失败 */ uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size); /** * @brief HFlashReadOffset 读取从原始地址偏移后的地方的数据 * @param addr 需要注册的地址 * @param offset 地址偏移 * @param data 读取数据写入的缓存内存 * @param size 读取数据大小 * @return 1: 读取成功 0: 读取失败 */ uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size); /** * @brief HFlashRawRead 原始读取Flash数据, 不校验任何东西, 正常情况下不建议使用 * @param addr 地址 * @param data 读取数据写入的缓存内存 * @param size 读取数据大小 * @return 1: 读取成功 0: 读取失败 */ uint8_t HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size); /** * @brief HFlashUpdateVersionCallback 更新版本号回调 * @param addr 需要注册的地址 * @param oldVersion 旧版本号 * @param newVersion 新版本号 * @param userData 用户数据 */ typedef void (*HFlashUpdateVersionCallback)(HFlashAddr_t addr, uint16_t oldVersion, uint16_t newVersion, void *userData); /** * @brief HFlashUpdateVersion 更新版本号, 版本号不同时会触发回调 * 如果旧版本比新版本大, 需要考虑使用当前版本的数据来兼容 * 如果旧版本比新版本小, 需要考虑使用将数据升级到新版本去 * @param addr 需要注册的地址 * @param newVersion 新版本号 * @param callback 回调函数 * @param userData 用户数据 */ 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 需要注册的地址 * @return CRC32 */ uint32_t HFlashGetCrc32(HFlashAddr_t addr); #endif // __H_FLASH_SERVER_H__