HCoreBase/include/HFlashServer.h

316 lines
9.5 KiB
C

/**
* 日期: 2025-11-27
* 作者: coffee
* 描述: Flash通用服务模块, 用于保证Flash操作的完备性, 支持任意长度数据读写, 因内部使用延后处理, 需要重启时必须调用同步
*/
#ifndef __H_FLASH_SERVER_H__
#define __H_FLASH_SERVER_H__
// #define USE_STD_MEM
#include <stdint.h>
#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_CACHE_PAGE_TIME
#define HFLASH_SYNC_CACHE_PAGE_TIME 600
#endif
///< 同步页表信息时间ms
#ifndef HFLASH_SYNC_PAGE_INFO_TIME
#define HFLASH_SYNC_PAGE_INFO_TIME 800
#endif
///< 同步备份页表信息时间ms
#ifndef HFLASH_SYNC_BACKUP_TIME
#define HFLASH_SYNC_BACKUP_TIME 1000
#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; ///< 修改次数
uint8_t invalid : 1; ///< 无效标志
};
} HFlashPageInfo;
typedef struct HFlashCacheInfo {
HFlashPageInfo info; ///< 页表信息
uint32_t pos : 19; ///< 存储页表信息的位置
uint32_t heat : 4; ///< 热度优先级
uint32_t waitWrite : 1; ///< 延后写入, 一般适用于流式操作或者延后复写
uint32_t waitCrc : 1; ///< 延后CRC
} 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, const 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, const void *data, uint32_t size);
/**
* @brief HFlashWriteRawOffset 写入原始地址偏移后的位置写入Flash数据, 超出部分不自动填充, 仅提供给一些库使用, 正常情况请勿使用
* @param addr 需要注册的地址
* @param offset 地址偏移
* @param data 写入数据
* @param size 写入数据大小
* @return 1: 写入成功 0: 写入失败
*/
uint8_t HFlashWriteRawOffset(HFlashAddr_t addr, uint32_t offset, const 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, const 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, const 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 获取页表记录的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);
/**
* @brief HFlashSync 执行同步写入Flash数据, 在重启前需要执行
*/
void HFlashSync();
#endif // __H_FLASH_SERVER_H__