1. 增加完备Flash服务
This commit is contained in:
parent
54c9dc52a7
commit
e1d52c26de
@ -1,20 +1,21 @@
|
|||||||
/**
|
/**
|
||||||
* 日期: 2025-11-27
|
* 日期: 2025-11-27
|
||||||
* 作者: coffee
|
* 作者: coffee
|
||||||
* 描述: Flash通用服务模块, 用于保证性Flash操作
|
* 描述: Flash通用服务模块, 用于保证Flash操作的完备性, 支持任意长度数据读写
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __H_FLASH_SERVER_H__
|
#ifndef __H_FLASH_SERVER_H__
|
||||||
#define __H_FLASH_SERVER_H__
|
#define __H_FLASH_SERVER_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
///< Flash块大小, 按块操作, 2的幂关系
|
///< Flash块大小, 按块操作, 2的幂关系
|
||||||
#ifndef HFLASH_BLOCK_SIZE
|
#ifndef HFLASH_BLOCK_SIZE
|
||||||
#define HFLASH_BLOCK_SIZE (4096)
|
#define HFLASH_BLOCK_SIZE (4096)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///< 获取缓存内存, 需要大于Flash一块大小
|
///< 获取缓存内存, 需要能申请到大于等于Flash一块大小
|
||||||
#ifndef HFLASH_MALLOC
|
#ifndef HFLASH_MALLOC
|
||||||
#define HFLASH_MALLOC(size) malloc(size)
|
#define HFLASH_MALLOC(size) malloc(size)
|
||||||
#endif
|
#endif
|
||||||
@ -34,9 +35,6 @@
|
|||||||
#define HFLASH_SYNC_TIME 2000
|
#define HFLASH_SYNC_TIME 2000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
///< Flash地址类型
|
///< Flash地址类型
|
||||||
typedef uint32_t HFlashAddr_t;
|
typedef uint32_t HFlashAddr_t;
|
||||||
|
|
||||||
@ -54,9 +52,10 @@ typedef union HFlashPageInfo {
|
|||||||
} HFlashPageInfo;
|
} HFlashPageInfo;
|
||||||
|
|
||||||
typedef struct HFlashCacheInfo {
|
typedef struct HFlashCacheInfo {
|
||||||
HFlashPageInfo info; ///< 页表信息
|
HFlashPageInfo info; ///< 页表信息
|
||||||
uint32_t pos : 19; ///< 存储页表信息的位置
|
uint32_t pos : 19; ///< 存储页表信息的位置
|
||||||
uint32_t heat : 4; ///< 热度优先级
|
uint32_t heat : 4; ///< 热度优先级
|
||||||
|
uint32_t waitWrite : 1; ///< 延后写入, 一般适用于流式操作或者延后复写
|
||||||
} HFlashCacheInfo;
|
} HFlashCacheInfo;
|
||||||
|
|
||||||
|
|
||||||
@ -115,18 +114,18 @@ void HFlashSetPageAddr(HFlashAddr_t addr, uint32_t size);
|
|||||||
void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size);
|
void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashProtectAddr 设置保护地址, 内部会使用双备份区域
|
* @brief HFlashSetProtectAddr 设置保护地址, 内部会使用双备份区域
|
||||||
* @param addr 地址
|
* @param addr 地址
|
||||||
* @param size 大小
|
* @param size 大小
|
||||||
*/
|
*/
|
||||||
void HFlashProtectAddr(HFlashAddr_t addr, uint32_t size);
|
void HFlashSetProtectAddr(HFlashAddr_t addr, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashProtectBackupAddr 设置保护备份地址
|
* @brief HFlashSetProtectBackupAddr 设置保护备份地址
|
||||||
* @param addr 地址
|
* @param addr 地址
|
||||||
* @param size 大小, 必须和保护地址大小相同
|
* @param size 大小, 必须和保护地址大小相同
|
||||||
*/
|
*/
|
||||||
void HFlashProtectBackupAddr(HFlashAddr_t addr, uint32_t size);
|
void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashInitCheck 在HFlashRegister前需要初始化检查, 用于检查页表是否可用, 不可用则需要初始化
|
* @brief HFlashInitCheck 在HFlashRegister前需要初始化检查, 用于检查页表是否可用, 不可用则需要初始化
|
||||||
@ -145,8 +144,9 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size);
|
|||||||
* @param addr 需要注册的地址
|
* @param addr 需要注册的地址
|
||||||
* @param data 写入数据
|
* @param data 写入数据
|
||||||
* @param size 写入数据大小
|
* @param size 写入数据大小
|
||||||
|
* @return 1: 写入成功 0: 写入失败
|
||||||
*/
|
*/
|
||||||
void HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashWriteOffset 写入从原始地址偏移后的地方写入数据, 如果偏移后的写入大小超过原未使用, 超出部分会自动写入0填充
|
* @brief HFlashWriteOffset 写入从原始地址偏移后的地方写入数据, 如果偏移后的写入大小超过原未使用, 超出部分会自动写入0填充
|
||||||
@ -154,16 +154,39 @@ void HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
|||||||
* @param offset 地址偏移
|
* @param offset 地址偏移
|
||||||
* @param data 写入数据
|
* @param data 写入数据
|
||||||
* @param size 写入数据大小
|
* @param size 写入数据大小
|
||||||
|
* @return 1: 写入成功 0: 写入失败
|
||||||
*/
|
*/
|
||||||
void HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size);
|
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数据, 不校验任何东西, 正常情况下不建议使用
|
* @brief HFlashRawWrite 原始写入Flash数据, 不校验任何东西, 正常情况下不建议使用
|
||||||
* @param addr 地址
|
* @param addr 地址
|
||||||
* @param data 写入数据
|
* @param data 写入数据
|
||||||
* @param size 写入数据大小
|
* @param size 写入数据大小
|
||||||
|
* @return 1: 写入成功 0: 写入失败
|
||||||
*/
|
*/
|
||||||
void HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
uint8_t HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashRead 读取Flash数据
|
* @brief HFlashRead 读取Flash数据
|
||||||
@ -172,7 +195,7 @@ void HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
|||||||
* @param size 读取数据大小
|
* @param size 读取数据大小
|
||||||
* @return 1: 读取成功 0: 读取失败
|
* @return 1: 读取成功 0: 读取失败
|
||||||
*/
|
*/
|
||||||
void HFlashRead(HFlashAddr_t addr, void *data, uint32_t size);
|
uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashReadOffset 读取从原始地址偏移后的地方的数据
|
* @brief HFlashReadOffset 读取从原始地址偏移后的地方的数据
|
||||||
@ -182,15 +205,35 @@ void HFlashRead(HFlashAddr_t addr, void *data, uint32_t size);
|
|||||||
* @param size 读取数据大小
|
* @param size 读取数据大小
|
||||||
* @return 1: 读取成功 0: 读取失败
|
* @return 1: 读取成功 0: 读取失败
|
||||||
*/
|
*/
|
||||||
void HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size);
|
uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashRawRead 原始读取Flash数据, 不校验任何东西, 正常情况下不建议使用
|
* @brief HFlashRawRead 原始读取Flash数据, 不校验任何东西, 正常情况下不建议使用
|
||||||
* @param addr 地址
|
* @param addr 地址
|
||||||
* @param data 读取数据写入的缓存内存
|
* @param data 读取数据写入的缓存内存
|
||||||
* @param size 读取数据大小
|
* @param size 读取数据大小
|
||||||
|
* @return 1: 读取成功 0: 读取失败
|
||||||
*/
|
*/
|
||||||
void HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size);
|
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 HFlashGetCrc32 获取Flash数据的CRC32值
|
* @brief HFlashGetCrc32 获取Flash数据的CRC32值
|
||||||
|
|||||||
@ -26,11 +26,16 @@ uint32_t HSCrc32Get()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// 计算最小值
|
||||||
#define FLASH_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b)))))
|
#define FLASH_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b)))))
|
||||||
|
|
||||||
// #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1);
|
// #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1);
|
||||||
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__);
|
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
// 最大热度
|
||||||
|
#define MAX_HEAT ((1 << 4) - 1)
|
||||||
|
|
||||||
|
// 检查是不是4对齐
|
||||||
#define IS_NOT_4(size) ((size & (4 - 1)) != 0)
|
#define IS_NOT_4(size) ((size & (4 - 1)) != 0)
|
||||||
|
|
||||||
union PageInfo {
|
union PageInfo {
|
||||||
@ -84,7 +89,7 @@ static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (addrEnd > sInfo.protectAddr + sInfo.protectSize) {
|
if (addrEnd > sInfo.protectAddr + sInfo.protectSize) {
|
||||||
FATAL_ERROR("addr[0x%08x] size[%d] overflow protect", addr, size);
|
FATAL_ERROR("addr[0x%08x][0x%08x] size[%d][%d] overflow protect", addr, sInfo.protectAddr, size, sInfo.protectSize);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +227,7 @@ static uint8_t WriteFlashValue(uint32_t addr, uint32_t size, uint8_t value)
|
|||||||
|
|
||||||
static void SyncBackup()
|
static void SyncBackup()
|
||||||
{
|
{
|
||||||
|
LogD("Start sync Backup");
|
||||||
if (sBackupTimer != HTIMER_INVALID) {
|
if (sBackupTimer != HTIMER_INVALID) {
|
||||||
HTimerRemove(sBackupTimer);
|
HTimerRemove(sBackupTimer);
|
||||||
sBackupTimer = HTIMER_INVALID;
|
sBackupTimer = HTIMER_INVALID;
|
||||||
@ -234,7 +240,7 @@ static void SyncBackup()
|
|||||||
|
|
||||||
for (uint16_t i = 0; i < HVectorGetUseLen(sNeedBackupOffset); ++i) {
|
for (uint16_t i = 0; i < HVectorGetUseLen(sNeedBackupOffset); ++i) {
|
||||||
const uint32_t addr = HVectorGetData(sNeedBackupOffset, i);
|
const uint32_t addr = HVectorGetData(sNeedBackupOffset, i);
|
||||||
const uint32_t destAddr = sInfo.protectAddr + (addr - sInfo.pageAddr);
|
const uint32_t destAddr = sInfo.protectBackupAddr + (addr - sInfo.protectAddr);
|
||||||
RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE);
|
RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +251,7 @@ static void SyncBackup()
|
|||||||
sPageInfo.needBackupPage = 0;
|
sPageInfo.needBackupPage = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _AddBackupAddr(uint32_t addr)
|
static void StartBackupTimer()
|
||||||
{
|
{
|
||||||
if (sBackupTimer != HTIMER_INVALID) {
|
if (sBackupTimer != HTIMER_INVALID) {
|
||||||
HTimerRemove(sBackupTimer);
|
HTimerRemove(sBackupTimer);
|
||||||
@ -253,20 +259,30 @@ static void _AddBackupAddr(uint32_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sBackupTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_TIME, SyncBackup, kHTimerOnce);
|
sBackupTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_TIME, SyncBackup, kHTimerOnce);
|
||||||
const HVectorLenType index = HVectorFindData(sNeedBackupOffset, addr);
|
}
|
||||||
if (index == HVECTOR_ERROR) {
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HVectorAddData(sNeedBackupOffset, addr)) {
|
static void _AddBackupAddr(uint32_t addr)
|
||||||
return ;
|
{
|
||||||
}
|
do {
|
||||||
|
const HVectorLenType index = HVectorFindData(sNeedBackupOffset, addr);
|
||||||
|
if (index != HVECTOR_ERROR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// 添加数据失败, 缓存已满, 需要先同步再添加
|
if (HVectorAddData(sNeedBackupOffset, addr)) {
|
||||||
SyncBackup();
|
break;
|
||||||
if (HVectorAddData(sNeedBackupOffset, addr) == 0) {
|
}
|
||||||
LogE("add wait sync addr[0x%08x], faild", addr);
|
|
||||||
}
|
// 添加数据失败, 缓存已满, 需要先同步再添加
|
||||||
|
SyncBackup();
|
||||||
|
if (HVectorAddData(sNeedBackupOffset, addr) == 0) {
|
||||||
|
LogE("add wait sync addr[0x%08x], faild", addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
LogD("Add wait sync addr[0x%08x], size[%d]", addr, HVectorGetUseLen(sNeedBackupOffset));
|
||||||
|
StartBackupTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddBackupAddr(uint32_t addr, uint32_t size)
|
static void AddBackupAddr(uint32_t addr, uint32_t size)
|
||||||
@ -346,7 +362,7 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_
|
|||||||
result = 1;
|
result = 1;
|
||||||
_FlashError:
|
_FlashError:
|
||||||
HFLASH_FREE(buff);
|
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]", srcAddr, dstAddr, size, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,6 +426,13 @@ static void WritePage(uint32_t index, HFlashPageInfo *info)
|
|||||||
UpdatePageInfo();
|
UpdatePageInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WriteCachePage(HFlashCacheInfo *info)
|
||||||
|
{
|
||||||
|
++info->info.modifyCount;
|
||||||
|
info->waitWrite = 0;
|
||||||
|
WritePage(info->pos, &info->info);
|
||||||
|
}
|
||||||
|
|
||||||
/// 检查是否重叠, 重叠返回1, 非重叠返回0
|
/// 检查是否重叠, 重叠返回1, 非重叠返回0
|
||||||
static uint8_t IsOverLap(HFlashAddr_t srcAddr, uint32_t size, HFlashAddr_t dstAddr, uint32_t dstSize)
|
static uint8_t IsOverLap(HFlashAddr_t srcAddr, uint32_t size, HFlashAddr_t dstAddr, uint32_t dstSize)
|
||||||
{
|
{
|
||||||
@ -530,15 +553,16 @@ static uint8_t _FindCacheHelper(uint32_t index, HFlashPageInfo *info, void *user
|
|||||||
static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
||||||
{
|
{
|
||||||
uint8_t currMin = 0xFF;
|
uint8_t currMin = 0xFF;
|
||||||
|
uint8_t fastCoolDown = 0;
|
||||||
HFlashCacheInfo cache;
|
HFlashCacheInfo cache;
|
||||||
for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
|
for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
|
||||||
currMin = FLASH_MIN(uint8_t, currMin, sInfo.pageCache[i].heat);
|
currMin = FLASH_MIN(uint8_t, currMin, sInfo.pageCache[i].heat);
|
||||||
|
fastCoolDown = fastCoolDown || sInfo.pageCache[i].heat >= MAX_HEAT;
|
||||||
if (sInfo.pageCache[i].info.addr != addr) {
|
if (sInfo.pageCache[i].info.addr != addr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sInfo.pageCache[i].heat = FLASH_MIN(uint8_t, sInfo.pageCache[i].heat + 1, ((1 << 5) - 1));
|
sInfo.pageCache[i].heat = FLASH_MIN(uint8_t, sInfo.pageCache[i].heat + 1, MAX_HEAT);
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
return &sInfo.pageCache[i];
|
return &sInfo.pageCache[i];
|
||||||
}
|
}
|
||||||
@ -555,9 +579,11 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 没有找到, 先降低温度
|
// 没有找到, 先降低温度
|
||||||
if (sInfo.pageCacheUseNum && currMin > 0) {
|
if (sInfo.pageCacheUseNum && (currMin > 0 || fastCoolDown)) {
|
||||||
|
// 达到最大热度, 需要快速降温
|
||||||
|
const uint16_t mask = -((uint16_t)fastCoolDown);
|
||||||
for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
|
for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
|
||||||
sInfo.pageCache[i].heat -= currMin;
|
sInfo.pageCache[i].heat = ((sInfo.pageCache[i].heat >> 1) & mask) | ((sInfo.pageCache[i].heat - currMin) & ~mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,6 +596,11 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
|||||||
++sInfo.pageCacheUseNum;
|
++sInfo.pageCacheUseNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果是延迟写入的, 需要先写入再替换
|
||||||
|
if (sInfo.pageCache[index].waitWrite) {
|
||||||
|
WriteCachePage(&sInfo.pageCache[index]);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&sInfo.pageCache[index], &cache, sizeof(HFlashCacheInfo));
|
memcpy(&sInfo.pageCache[index], &cache, sizeof(HFlashCacheInfo));
|
||||||
return &sInfo.pageCache[index];
|
return &sInfo.pageCache[index];
|
||||||
}
|
}
|
||||||
@ -607,13 +638,13 @@ void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size)
|
|||||||
sInfo.pageSize = size;
|
sInfo.pageSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashProtectAddr(HFlashAddr_t addr, uint32_t size)
|
void HFlashSetProtectAddr(HFlashAddr_t addr, uint32_t size)
|
||||||
{
|
{
|
||||||
sInfo.protectAddr = addr;
|
sInfo.protectAddr = addr;
|
||||||
sInfo.protectSize = size;
|
sInfo.protectSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashProtectBackupAddr(HFlashAddr_t addr, uint32_t size)
|
void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size)
|
||||||
{
|
{
|
||||||
if (sInfo.protectSize != size) {
|
if (sInfo.protectSize != size) {
|
||||||
FATAL_ERROR("protect size not match[%d][%d]", sInfo.protectSize, size);
|
FATAL_ERROR("protect size not match[%d][%d]", sInfo.protectSize, size);
|
||||||
@ -697,8 +728,8 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sPageInfo.needBackupPage = 1;
|
sPageInfo.needBackupPage = 1;
|
||||||
cache = FindCache(addr);
|
StartBackupTimer();
|
||||||
RestoreBackup(sInfo.protectAddr, sInfo.protectBackupAddr, sInfo.protectSize);
|
// RestoreBackup(sInfo.protectAddr, sInfo.protectBackupAddr, sInfo.protectSize);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,26 +765,25 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
|||||||
LogE("addr[0x%08x] size[%d] crc32 not match", cache->info.addr, cache->info.size);
|
LogE("addr[0x%08x] size[%d] crc32 not match", cache->info.addr, cache->info.size);
|
||||||
cache->info.useSize = 0;
|
cache->info.useSize = 0;
|
||||||
cache->info.crc32 = GetFlashCrc32(cache->info.addr, cache->info.useSize);
|
cache->info.crc32 = GetFlashCrc32(cache->info.addr, cache->info.useSize);
|
||||||
WritePage(cache->pos, &cache->info);
|
WriteCachePage(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
// 检查是否存在致命性错误, 使用的地址不在注册页表中
|
// 检查是否存在致命性错误, 使用的地址不在注册页表中
|
||||||
|
uint8_t result = 0;
|
||||||
HFlashCacheInfo *cache = FindCache(addr);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
if (cache == NULL) {
|
if (cache == NULL) {
|
||||||
FATAL_ERROR("addr[0x%08x] not register", addr);
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
return ;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查写入数据大小是否超出注册提供的大小范围
|
// 检查写入数据大小是否超出注册提供的大小范围
|
||||||
if (cache->info.size < size) {
|
if (cache->info.size < size) {
|
||||||
FATAL_ERROR("addr[0x%08x] size[%d] overflow", addr, size);
|
FATAL_ERROR("addr[0x%08x] size[%d] overflow", addr, size);
|
||||||
return ;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
++cache->info.modifyCount;
|
|
||||||
|
|
||||||
// 更新使用长度
|
// 更新使用长度
|
||||||
if (cache->info.useSize < size) {
|
if (cache->info.useSize < size) {
|
||||||
cache->info.useSize = size;
|
cache->info.useSize = size;
|
||||||
@ -764,32 +794,33 @@ void HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
|||||||
HSCrc32Update((uint8_t *)data, size);
|
HSCrc32Update((uint8_t *)data, size);
|
||||||
cache->info.crc32 = HSCrc32Get();
|
cache->info.crc32 = HSCrc32Get();
|
||||||
|
|
||||||
WriteFlash(addr, data, size);
|
result = WriteFlash(addr, data, size);
|
||||||
WritePage(cache->pos, &cache->info);
|
WriteCachePage(cache);
|
||||||
|
|
||||||
// 检查是否在保护区域, 需要的话需要写入等待备份
|
// 检查是否在保护区域, 需要的话需要写入等待备份
|
||||||
if (IsProtect(addr, size)) {
|
if (IsProtect(addr, size)) {
|
||||||
AddBackupAddr(addr, size);
|
AddBackupAddr(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
|
uint8_t result = 0;
|
||||||
HFlashCacheInfo *cache = FindCache(addr);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
if (cache == NULL) {
|
if (cache == NULL) {
|
||||||
FATAL_ERROR("addr[0x%08x] not register", addr);
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
return ;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t useSize = offset + size;
|
const uint32_t useSize = offset + size;
|
||||||
// 检查写入数据大小是否超出注册提供的大小范围
|
// 检查写入数据大小是否超出注册提供的大小范围
|
||||||
if (cache->info.size < useSize) {
|
if (cache->info.size < useSize) {
|
||||||
FATAL_ERROR("addr[0x%08x] size[%d] overflow", addr, useSize);
|
FATAL_ERROR("addr[0x%08x] size[%d] overflow", addr, useSize);
|
||||||
return ;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
++cache->info.modifyCount;
|
|
||||||
|
|
||||||
// 更新使用长度, 将跨越的部分填充0
|
// 更新使用长度, 将跨越的部分填充0
|
||||||
if (cache->info.useSize < useSize) {
|
if (cache->info.useSize < useSize) {
|
||||||
if (cache->info.useSize < offset) {
|
if (cache->info.useSize < offset) {
|
||||||
@ -800,27 +831,79 @@ void HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
cache->info.crc32 = GetFlashCrc32(addr, useSize);
|
cache->info.crc32 = GetFlashCrc32(addr, useSize);
|
||||||
WriteFlash(addr + offset, data, size);
|
result = WriteFlash(addr + offset, data, size);
|
||||||
WritePage(cache->pos, &cache->info);
|
WriteCachePage(cache);
|
||||||
|
|
||||||
// 检查是否在保护区域, 需要的话需要写入等待备份
|
// 检查是否在保护区域, 需要的话需要写入等待备份
|
||||||
if (IsProtect(addr, size)) {
|
if (IsProtect(addr, size)) {
|
||||||
AddBackupAddr(addr, useSize);
|
AddBackupAddr(addr, useSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
void HFlashStreamBegin(HFlashAddr_t addr)
|
||||||
{
|
{
|
||||||
WriteFlash(addr, data, size);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
|
if (cache == NULL) {
|
||||||
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->waitWrite = 1;
|
||||||
|
cache->info.crc32 = 0xFFFFFFFF;
|
||||||
|
cache->info.useSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashRead(HFlashAddr_t addr, void *data, uint32_t size)
|
uint8_t HFlashStreamWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
||||||
|
{
|
||||||
|
uint8_t result = 0;
|
||||||
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
|
if (cache == NULL) {
|
||||||
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->info.useSize + size > cache->info.size) {
|
||||||
|
LogE("addr[0x%08x] size[%d][%d] overflow", addr, cache->info.useSize + size, cache->info.size);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteFlash(addr + cache->info.useSize, data, size);
|
||||||
|
cache->info.useSize += size;
|
||||||
|
++cache->info.modifyCount;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HFlashStreamEnd(HFlashAddr_t addr)
|
||||||
|
{
|
||||||
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
|
if (cache == NULL) {
|
||||||
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->waitWrite = 0;
|
||||||
|
cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize);
|
||||||
|
if (IsProtect(addr, cache->info.useSize)) {
|
||||||
|
AddBackupAddr(addr, cache->info.useSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteCachePage(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
||||||
|
{
|
||||||
|
return WriteFlash(addr, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
HFlashCacheInfo *cache = FindCache(addr);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
if (cache == NULL) {
|
if (cache == NULL) {
|
||||||
FATAL_ERROR("addr[0x%08x] not register", addr);
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
memset(data, 0, size);
|
memset(data, 0, size);
|
||||||
return ;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 超出部分填充0
|
// 超出部分填充0
|
||||||
@ -829,22 +912,22 @@ void HFlashRead(HFlashAddr_t addr, void *data, uint32_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize);
|
const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize);
|
||||||
ReadFlash(addr, data, readSize);
|
return ReadFlash(addr, data, readSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
HFlashCacheInfo *cache = FindCache(addr);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
if (cache == NULL) {
|
if (cache == NULL) {
|
||||||
FATAL_ERROR("addr[0x%08x] not register", addr);
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
memset(data, 0, size);
|
memset(data, 0, size);
|
||||||
return ;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取的偏移量超出使用长度
|
// 读取的偏移量超出使用长度
|
||||||
if (cache->info.useSize < offset) {
|
if (cache->info.useSize < offset) {
|
||||||
memset(data, 0, size);
|
memset(data, 0, size);
|
||||||
return ;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取的数据超出使用长度, 将使用长度后面填充0
|
// 读取的数据超出使用长度, 将使用长度后面填充0
|
||||||
@ -854,12 +937,36 @@ void HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t s
|
|||||||
memset((uint8_t *)data + size - remain, 0, remain);
|
memset((uint8_t *)data + size - remain, 0, remain);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadFlash(addr, data, size - remain);
|
return ReadFlash(addr + offset, data, size - remain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size)
|
uint8_t HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
ReadFlash(addr, data, size);
|
return ReadFlash(addr, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData)
|
||||||
|
{
|
||||||
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
|
if (cache == NULL) {
|
||||||
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->info.version == newVersion) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint16_t oldVersion = cache->info.version;
|
||||||
|
cache->waitWrite = 1;
|
||||||
|
cache->info.version = newVersion;
|
||||||
|
if (callback) {
|
||||||
|
callback(addr, oldVersion, newVersion, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->waitWrite) {
|
||||||
|
WriteCachePage(cache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t HFlashGetCrc32(HFlashAddr_t addr)
|
uint32_t HFlashGetCrc32(HFlashAddr_t addr)
|
||||||
@ -872,3 +979,4 @@ uint32_t HFlashGetCrc32(HFlashAddr_t addr)
|
|||||||
|
|
||||||
return cache->info.crc32;
|
return cache->info.crc32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user