1. 修复偏移读取的问题
This commit is contained in:
parent
276218d3e0
commit
a902eb38c8
@ -63,6 +63,7 @@ typedef union HFlashPageInfo {
|
||||
uint32_t useSize : 24; ///< 使用大小
|
||||
uint16_t version; ///< 当前页数据的版本
|
||||
uint32_t modifyCount; ///< 修改次数
|
||||
uint8_t invalid : 1; ///< 无效标志
|
||||
};
|
||||
} HFlashPageInfo;
|
||||
|
||||
@ -162,7 +163,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size);
|
||||
* @param size 写入数据大小
|
||||
* @return 1: 写入成功 0: 写入失败
|
||||
*/
|
||||
uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
||||
uint8_t HFlashWrite(HFlashAddr_t addr, const void *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief HFlashWriteOffset 写入从原始地址偏移后的地方写入数据, 如果偏移后的写入大小超过原未使用, 超出部分会自动写入0填充
|
||||
@ -172,7 +173,17 @@ uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
||||
* @param size 写入数据大小
|
||||
* @return 1: 写入成功 0: 写入失败
|
||||
*/
|
||||
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size);
|
||||
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief HFlashWriteRawOffset 写入原始地址偏移后的位置写入Flash数据, 超出部分不自动填充, 延后计算CRC, 仅提供给一些库使用, 请勿使用
|
||||
* @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 开始流式写入, 重置使用长度
|
||||
@ -187,7 +198,7 @@ void HFlashStreamBegin(HFlashAddr_t addr);
|
||||
* @param size 写入数据大小
|
||||
* @return 1: 写入成功 0: 写入失败
|
||||
*/
|
||||
uint8_t HFlashStreamWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
||||
uint8_t HFlashStreamWrite(HFlashAddr_t addr, const void *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief HFlashStreamEnd 结束流式写入, 计算CRC
|
||||
@ -202,7 +213,7 @@ void HFlashStreamEnd(HFlashAddr_t addr);
|
||||
* @param size 写入数据大小
|
||||
* @return 1: 写入成功 0: 写入失败
|
||||
*/
|
||||
uint8_t HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
||||
uint8_t HFlashRawWrite(HFlashAddr_t addr, const void *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief HFlashRead 读取Flash数据
|
||||
|
||||
@ -39,7 +39,7 @@ uint32_t HSCrc32Get()
|
||||
#ifdef USE_STD_MEM
|
||||
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__);
|
||||
#else
|
||||
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1);
|
||||
#define FATAL_ERROR(format, ...) while (1) { LogE(format, ##__VA_ARGS__); HShellRun(); };
|
||||
#endif
|
||||
|
||||
// 最大热度
|
||||
@ -50,12 +50,16 @@ uint32_t HSCrc32Get()
|
||||
|
||||
enum eShell
|
||||
{
|
||||
kShellPageInfo, ///< 查看页表信息
|
||||
kShellPageInfo, ///< 查看页表信息
|
||||
kShellDelUseDataPage, ///< 删除页表使用数据
|
||||
kShellDelPage, ///< 删除页
|
||||
kShellMax,
|
||||
};
|
||||
|
||||
static HShellMatch sShellMatch[] = {
|
||||
HSHELL_MATCH_ITEM(kShellPageInfo, "pageInfo"),
|
||||
HSHELL_MATCH_ITEM(kShellDelUseDataPage, "pagedelUseData"),
|
||||
HSHELL_MATCH_ITEM(kShellDelPage, "pageDel"),
|
||||
};
|
||||
|
||||
|
||||
@ -90,12 +94,19 @@ static union PageInfo sPageInfo;
|
||||
// 备份定时器
|
||||
static HTimer_t sBackupTimer = HTIMER_INVALID;
|
||||
|
||||
// 需要备份的保护区地址页偏移
|
||||
// 延后计算CRC定时器
|
||||
static HTimer_t sDelayCrc32Timer = HTIMER_INVALID;
|
||||
|
||||
// 存储需要备份的保护区地址页偏移
|
||||
static HVECTOR_DEFINE32(sNeedBackupOffset, 10);
|
||||
|
||||
// 存储需要延后计算CRC的记录地址
|
||||
static HVECTOR_DEFINE32(sDelayCalcCrc32, 3);
|
||||
|
||||
static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size);
|
||||
static void StartBackupTimer();
|
||||
static HFlashCacheInfo *FindCache(HFlashAddr_t addr);
|
||||
static void WriteCachePage(HFlashCacheInfo *info);
|
||||
|
||||
///< 检查地址是否在双备份保护区内
|
||||
static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size)
|
||||
@ -147,7 +158,7 @@ static uint8_t EraseFlash(HFlashAddr_t addr)
|
||||
* @param call 拷贝回调, dest缓存, src已经调整好位置的指针, buffSize需要拷贝的数据大小, userData用户数据
|
||||
* @return 写入是否成功
|
||||
*/
|
||||
static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*call)(void *dest, const void *src, uint16_t buffSize, void *userData), void *userData)
|
||||
static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, void(*call)(void *dest, const void *src, uint16_t buffSize, void *userData), void *userData)
|
||||
{
|
||||
if (sInfo.write == NULL) {
|
||||
FATAL_ERROR("write is null");
|
||||
@ -231,7 +242,7 @@ static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, vo
|
||||
memcpy(dest, src, buffSize);
|
||||
}
|
||||
|
||||
static uint8_t WriteFlash(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
static uint8_t WriteFlash(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||
{
|
||||
return WriteData(addr, data, size, _WriteFlashHelper, NULL);
|
||||
}
|
||||
@ -334,7 +345,6 @@ static void AddBackupAddr(uint32_t addr, uint32_t size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
|
||||
{
|
||||
if (size == 0) {
|
||||
@ -362,6 +372,57 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
|
||||
return HSCrc32Get();
|
||||
}
|
||||
|
||||
static void SyncDelayCrc32()
|
||||
{
|
||||
LogD("Start sync DelayCrc32");
|
||||
if (sDelayCrc32Timer != HTIMER_INVALID) {
|
||||
HTimerRemove(sDelayCrc32Timer);
|
||||
sDelayCrc32Timer = HTIMER_INVALID;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < HVectorGetUseLen(sDelayCalcCrc32); ++i) {
|
||||
const uint32_t addr = HVectorGetData(sDelayCalcCrc32, i);
|
||||
HFlashCacheInfo *cache = FindCache(addr);
|
||||
if (cache == NULL) {
|
||||
LogE("addr[0x%08x], cache not found", addr);
|
||||
continue;
|
||||
}
|
||||
|
||||
cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize);
|
||||
WriteCachePage(cache);
|
||||
}
|
||||
|
||||
HVectorClear(sDelayCalcCrc32);
|
||||
}
|
||||
|
||||
static void StartDelayCrc32Timer()
|
||||
{
|
||||
if (sDelayCrc32Timer != HTIMER_INVALID) {
|
||||
HTimerRemove(sDelayCrc32Timer);
|
||||
sDelayCrc32Timer = HTIMER_INVALID;
|
||||
}
|
||||
|
||||
sDelayCrc32Timer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_TIME, SyncDelayCrc32, kHTimerOnce);
|
||||
}
|
||||
|
||||
static void AddDelayCrc32(HFlashAddr_t addr)
|
||||
{
|
||||
do {
|
||||
const HVectorLenType index = HVectorFindData(sDelayCalcCrc32, addr);
|
||||
if (index != HVECTOR_ERROR) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (HVectorAddData(sDelayCalcCrc32, addr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
SyncDelayCrc32();
|
||||
} while (0);
|
||||
|
||||
StartDelayCrc32Timer();
|
||||
}
|
||||
|
||||
static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size)
|
||||
{
|
||||
const uint16_t mallocSize = 1024;
|
||||
@ -534,10 +595,25 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
|
||||
///< 检查是否重叠, 重叠返回1
|
||||
static uint8_t _CreatePageInfoHelper(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||
{
|
||||
if (info->invalid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HFlashPageInfo *cache = (HFlashPageInfo *)userData;
|
||||
return IsOverLap(info->addr, info->size, cache->addr, cache->size);
|
||||
}
|
||||
|
||||
static uint8_t ScanAvailablePage(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||
{
|
||||
uint32_t *result = (uint32_t *)userData;
|
||||
if (info->invalid == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = index;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t CreatePageInfo(HFlashAddr_t addr, uint32_t size)
|
||||
{
|
||||
HFlashPageInfo info;
|
||||
@ -550,13 +626,21 @@ static uint8_t CreatePageInfo(HFlashAddr_t addr, uint32_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t index = 0;
|
||||
if (ScanPage(ScanAvailablePage, &index)) {
|
||||
// 如果找到空闲页, 覆盖之前的页
|
||||
info.crc32 = GetFlashCrc32(info.addr, info.useSize);
|
||||
WritePage(index, &info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sPageInfo.useNum >= sPageInfo.pageNum) {
|
||||
FATAL_ERROR("page table is full");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 写入新页表
|
||||
const uint32_t index = sPageInfo.useNum++;
|
||||
index = sPageInfo.useNum++;
|
||||
info.crc32 = GetFlashCrc32(info.addr, info.useSize);
|
||||
WritePage(index, &info);
|
||||
|
||||
@ -565,6 +649,10 @@ static uint8_t CreatePageInfo(HFlashAddr_t addr, uint32_t size)
|
||||
|
||||
static uint8_t _FindCacheHelper(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||
{
|
||||
if (info->invalid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HFlashCacheInfo *cache = (HFlashCacheInfo *)userData;
|
||||
if (info->addr != cache->info.addr) {
|
||||
return 0;
|
||||
@ -689,12 +777,12 @@ 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);
|
||||
HSHELL_PRINTFL("page[%d], invalid[%d], addr[0x%08x][%u], useSize[0x%x][%d], size[0x%x][%d], modifyCount[%d], crc32[0x%x], version[%d]", index, info->invalid, info->addr, info->addr, info->useSize, info->useSize, info->size, 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);
|
||||
HSHELL_PRINTFL("page[%d], invalid[%d], addr[0x%08x][%u], useSize[0x%x][%d], size[0x%x][%d], modifyCount[%d], crc32[0x%x], version[%d]", index, info->invalid, info->addr, info->addr, info->useSize, info->useSize, info->size, info->size, info->modifyCount, info->crc32, info->version);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -704,13 +792,36 @@ static uint8_t _Print(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||
static void Shell(HSHELL_FUNC_ARGS)
|
||||
{
|
||||
uint32_t arg1 = 0;
|
||||
if (HSHellToUint32(tokens, tokensLen, 0, &arg1) == 0) {
|
||||
if (HSHellToUint32(tokens, tokensLen, 1, &arg1) == 0) {
|
||||
arg1 = -1;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case kShellPageInfo: {
|
||||
ScanPage(_Print, &arg1);
|
||||
for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
|
||||
HSHELL_PRINTFL("Cache index[%d], addr[0x%08x], useSize[0x%x][%d], size[0x%x][%d], modifyCount[%d], crc32[0x%x], version[%d]", i, sInfo.pageCache[i].info.addr, sInfo.pageCache[i].info.useSize, sInfo.pageCache[i].info.useSize, sInfo.pageCache[i].info.size, sInfo.pageCache[i].info.size, sInfo.pageCache[i].info.modifyCount, sInfo.pageCache[i].info.crc32, sInfo.pageCache[i].info.version);
|
||||
}
|
||||
} break;
|
||||
case kShellDelUseDataPage: {
|
||||
HFlashCacheInfo *cache = FindCache(arg1);
|
||||
if (cache == NULL) {
|
||||
HSHELL_PRINTFL("addr[0x%08x] not register", arg1);
|
||||
return ;
|
||||
}
|
||||
|
||||
cache->info.useSize = 0;
|
||||
WriteCachePage(cache);
|
||||
} break;
|
||||
case kShellDelPage: {
|
||||
HFlashCacheInfo *cache = FindCache(arg1);
|
||||
if (cache == NULL) {
|
||||
HSHELL_PRINTFL("addr[0x%08x] not register", arg1);
|
||||
return ;
|
||||
}
|
||||
|
||||
cache->info.invalid = 1;
|
||||
WriteCachePage(cache);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
@ -778,6 +889,10 @@ void HFlashInitCheck()
|
||||
///< 检查是否重叠, 重叠返回1
|
||||
static uint8_t _CheckOverLap(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||
{
|
||||
if (info->invalid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HFlashCacheInfo *cache = (HFlashCacheInfo *)userData;
|
||||
if (cache->pos == index) {
|
||||
return 0;
|
||||
@ -823,6 +938,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
||||
if (cache->info.useSize > size) {
|
||||
LogE("addr[0x%08x] useSize[%d] > size[%d]", addr, cache->info.useSize, size);
|
||||
cache->info.useSize = 0;
|
||||
cache->waitWrite = 1;
|
||||
}
|
||||
|
||||
// 检查是否在保护区域, 不是保护区域不需要检查crc校验
|
||||
@ -873,7 +989,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
||||
WriteCachePage(cache);
|
||||
}
|
||||
|
||||
uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
uint8_t HFlashWrite(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||
{
|
||||
// 检查是否存在致命性错误, 使用的地址不在注册页表中
|
||||
uint8_t result = 0;
|
||||
@ -910,7 +1026,7 @@ uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
||||
static uint8_t WriteOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size, uint8_t needSetZero)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
HFlashCacheInfo *cache = FindCache(addr);
|
||||
@ -928,7 +1044,7 @@ uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32
|
||||
|
||||
// 更新使用长度, 将跨越的部分填充0
|
||||
if (cache->info.useSize < useSize) {
|
||||
if (cache->info.useSize < offset) {
|
||||
if (needSetZero && cache->info.useSize < offset) {
|
||||
WriteFlashValue(addr + cache->info.useSize, offset - cache->info.useSize, 0);
|
||||
}
|
||||
|
||||
@ -936,8 +1052,13 @@ uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32
|
||||
}
|
||||
|
||||
result = WriteFlash(addr + offset, data, size);
|
||||
cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize);
|
||||
WriteCachePage(cache);
|
||||
if (needSetZero) {
|
||||
cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize);
|
||||
WriteCachePage(cache);
|
||||
} else {
|
||||
cache->waitWrite = 1;
|
||||
AddDelayCrc32(addr);
|
||||
}
|
||||
|
||||
// 检查是否在保护区域, 需要的话需要写入等待备份
|
||||
if (IsProtect(addr, size)) {
|
||||
@ -947,6 +1068,16 @@ uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size)
|
||||
{
|
||||
return WriteOffset(addr, offset, data, size, 1);
|
||||
}
|
||||
|
||||
uint8_t HFlashWriteRawOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size)
|
||||
{
|
||||
return WriteOffset(addr, offset, data, size, 0);
|
||||
}
|
||||
|
||||
void HFlashStreamBegin(HFlashAddr_t addr)
|
||||
{
|
||||
HFlashCacheInfo *cache = FindCache(addr);
|
||||
@ -960,7 +1091,7 @@ void HFlashStreamBegin(HFlashAddr_t addr)
|
||||
cache->info.useSize = 0;
|
||||
}
|
||||
|
||||
uint8_t HFlashStreamWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
uint8_t HFlashStreamWrite(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
HFlashCacheInfo *cache = FindCache(addr);
|
||||
@ -998,7 +1129,7 @@ void HFlashStreamEnd(HFlashAddr_t addr)
|
||||
WriteCachePage(cache);
|
||||
}
|
||||
|
||||
uint8_t HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
uint8_t HFlashRawWrite(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||
{
|
||||
return WriteFlash(addr, data, size);
|
||||
}
|
||||
@ -1038,12 +1169,13 @@ uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_
|
||||
|
||||
// 读取的数据超出使用长度, 将使用长度后面填充0
|
||||
const uint32_t useSize = offset + size;
|
||||
const uint32_t remain = useSize - cache->info.useSize;
|
||||
if (cache->info.useSize < useSize) {
|
||||
if (useSize > cache->info.useSize) {
|
||||
const uint32_t remain = useSize - cache->info.useSize;
|
||||
memset((uint8_t *)data + size - remain, 0, remain);
|
||||
size -= remain;
|
||||
}
|
||||
|
||||
return ReadFlash(addr + offset, data, size - remain);
|
||||
return ReadFlash(addr + offset, data, size);
|
||||
}
|
||||
|
||||
uint8_t HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user