1. 还需要优化一版, 先备份

This commit is contained in:
coffee 2025-12-06 09:53:23 +08:00
parent 150d642f22
commit 247e211168
2 changed files with 94 additions and 82 deletions

View File

@ -22,7 +22,7 @@
#define HFLASH_BLOCK_SIZE (4096)
#endif
///< 获取缓存内存, 需要能申请到大于等于(Flash一块大小 + 1024)
///< 获取缓存内存, 需要能申请到大于等于(Flash一块大小)
#ifndef HFLASH_MALLOC
#ifdef USE_STD_MEM
#define HFLASH_MALLOC(size) malloc(size)
@ -72,6 +72,7 @@ typedef struct HFlashCacheInfo {
uint32_t pos : 19; ///< 存储页表信息的位置
uint32_t heat : 4; ///< 热度优先级
uint32_t waitWrite : 1; ///< 延后写入, 一般适用于流式操作或者延后复写
uint32_t waitCrc : 1; ///< 延后CRC
} HFlashCacheInfo;

View File

@ -132,13 +132,12 @@ static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size)
return 1;
}
static inline uint32_t Aligned4K(uint32_t value)
static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size)
{
return (value + (HFLASH_BLOCK_SIZE - 1)) & ~(HFLASH_BLOCK_SIZE - 1);
if (size == 0) {
return 1;
}
static uint8_t ReadFlash(HFlashAddr_t addr, void *data, uint32_t size)
{
if (sInfo.read == NULL) {
FATAL_ERROR("read is null");
return 0;
@ -148,7 +147,7 @@ static uint8_t ReadFlash(HFlashAddr_t addr, void *data, uint32_t size)
return sInfo.read(addr, dataPtr, size);
}
static uint8_t EraseFlash(HFlashAddr_t addr)
static uint8_t EraseFlashCall(HFlashAddr_t addr)
{
if (sInfo.erase == NULL) {
FATAL_ERROR("erase is null");
@ -158,6 +157,21 @@ static uint8_t EraseFlash(HFlashAddr_t addr)
return sInfo.erase(addr);
}
static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size)
{
if (size == 0) {
return 1;
}
if (sInfo.write == NULL) {
FATAL_ERROR("write is null");
return 0;
}
uint8_t *dataPtr = (uint8_t *)data;
return sInfo.write(addr, dataPtr, size);
}
/**
* @brief Flash
* @param addr Flash地址
@ -168,11 +182,6 @@ static uint8_t EraseFlash(HFlashAddr_t addr)
*/
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");
return 0;
}
uint8_t *dataPtr = (uint8_t *)data;
uint32_t adjustAddr = addr & ~(HFLASH_BLOCK_SIZE - 1);
const uint16_t offset = addr - adjustAddr;
@ -185,18 +194,18 @@ static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, voi
}
// 先写入首个未对齐的块
if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
if (ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], read faild", adjustAddr);
goto _flashError;
}
if (EraseFlash(adjustAddr) == 0) {
if (EraseFlashCall(adjustAddr) == 0) {
LogE("addr[0x%08x], erase faild", adjustAddr);
goto _flashError;
}
call(buff + offset, dataPtr, remain, userData);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
}
@ -206,13 +215,13 @@ static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, voi
adjustAddr += HFLASH_BLOCK_SIZE;
dataPtr += remain;
for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE, dataPtr += HFLASH_BLOCK_SIZE) {
if (EraseFlash(adjustAddr) == 0) {
if (EraseFlashCall(adjustAddr) == 0) {
LogE("addr[0x%08x], erase faild", adjustAddr);
goto _flashError;
}
call(buff, dataPtr, HFLASH_BLOCK_SIZE, userData);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
}
@ -220,18 +229,18 @@ static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, voi
// 操作最后一个未对齐的块
if (size) {
if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
if (ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], read faild", adjustAddr);
goto _flashError;
}
if (EraseFlash(adjustAddr) == 0) {
if (EraseFlashCall(adjustAddr) == 0) {
LogE("addr[0x%08x], erase faild", adjustAddr);
goto _flashError;
}
call(buff, dataPtr, size, userData);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
}
@ -244,36 +253,6 @@ _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;
@ -337,9 +316,7 @@ static void SyncBackup()
HVectorClear(sNeedBackupOffset);
// 备份页表数据
uint32_t backSize = Aligned4K(AdjustPageAddr(sPageInfo.useNum + 1));
backSize = FLASH_MIN(uint32_t, backSize, sInfo.pageSize);
RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, backSize);
RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, AdjustPageByte(sPageInfo.useNum + 1));
sPageInfo.needBackupPage = 0;
}
@ -415,7 +392,7 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
for (uint32_t i = 0; i < size; i += HFLASH_BLOCK_SIZE) {
const uint32_t remain = FLASH_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE);
if (ReadFlash(addr + i, buff, remain) == 0) {
if (ReadFlashCall(addr + i, buff, remain) == 0) {
LogE("addr[0x%08x][0x%08x], size[%d] read faild", addr, addr + i, remain);
break;
}
@ -478,41 +455,75 @@ static void AddDelayCrc32(HFlashAddr_t addr)
StartDelayCrc32Timer();
}
static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t size)
static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_t copySize)
{
// 检查是不是页对齐数据, 是的话不用再回读写, 直接读写
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 (copySize == 0) {
LogD("addr[0x%08x], write size[%d] is 0", srcAddr, copySize);
return 1;
}
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE);
if (buff == NULL) {
LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, size);
LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, copySize);
return 0;
}
uint8_t result = 0;
uint32_t i = 0;
uint32_t remain = 0;
for (; i < size; i += mallocSize) {
remain = FLASH_MIN(uint32_t, size - i, mallocSize);
result = result || ReadFlash(srcAddr + i, buff, remain) == 0;
if (isAlignPage) {
// 是对齐大小直接回写
result = result || WriteAlignData(dstAddr + i, buff, remain) == 0;
} else {
result = result || WriteFlash(dstAddr + i, buff, remain) == 0;
}
uint32_t adjustAddr = dstAddr & ~(HFLASH_BLOCK_SIZE - 1);
uint32_t size = copySize;
uint32_t srcOffset = 0;
// 如果地址不是对齐页的, 先处理残余数据到对齐页
if (adjustAddr != dstAddr) {
const uint16_t offset = dstAddr - adjustAddr;
const uint32_t remain = offset + size > HFLASH_BLOCK_SIZE ? HFLASH_BLOCK_SIZE - offset : size;
// 先读取到对齐页, 然后将未对齐的数据重写
result = ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
result = result || ReadFlashCall(srcAddr + srcOffset, buff + offset, remain) == 0;
result = result || EraseFlashCall(adjustAddr) == 0;
result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
if (result) {
LogE("read addr[0x%08x], write addr[0x%08x], write size[%d] faild", srcAddr + i, dstAddr + i, remain);
result = 0;
LogE("addr[0x%08x], write size[%d] faild", srcAddr, size);
goto _FlashError;
}
size -= remain;
adjustAddr += HFLASH_BLOCK_SIZE;
srcOffset += remain;
}
// 中间对齐页直接读原地址页, 擦写目标页
for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE, srcOffset += HFLASH_BLOCK_SIZE) {
result = result || ReadFlashCall(srcAddr + srcOffset, buff, HFLASH_BLOCK_SIZE) == 0;
result = result || EraseFlashCall(adjustAddr) == 0;
result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
if (result) {
result = 0;
LogE("addr[0x%08x], write size[%d] faild", srcAddr, size);
goto _FlashError;
}
}
// 最后不对齐的数据
if (size) {
result = result || ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
result = result || ReadFlashCall(srcAddr + srcOffset, buff, size) == 0;
result = result || EraseFlashCall(adjustAddr) == 0;
result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
if (result) {
result = 0;
LogE("addr[0x%08x], write size[%d] faild", srcAddr, size);
goto _FlashError;
}
size = 0;
}
result = 1;
_FlashError:
HFLASH_FREE(buff);
LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d], result[%d], malloc[%d]", srcAddr, dstAddr, size, result, mallocSize);
LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d][%d], result[%d]", srcAddr, dstAddr, size, copySize, result);
return result;
}
@ -545,7 +556,7 @@ static void ReadPage(uint32_t index, HFlashPageInfo *info)
}
const HFlashAddr_t addr = AdjustPageAddrOffset(sInfo.pageAddr, index);
ReadFlash(addr, info, sizeof(HFlashPageInfo));
ReadFlashCall(addr, info, sizeof(HFlashPageInfo));
}
static void WritePage(uint32_t index, HFlashPageInfo *info)
@ -617,7 +628,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
uint8_t result = 0;
for (uint32_t i = 0; i < sPageInfo.useNum; i += pageNum) {
const uint32_t num = FLASH_MIN(uint32_t, sPageInfo.useNum - i, pageNum);
if (ReadFlash(AdjustPageAddrOffset(sInfo.pageAddr, i), buff, AdjustPageByte(num)) == 0) {
if (ReadFlashCall(AdjustPageAddrOffset(sInfo.pageAddr, i), buff, AdjustPageByte(num)) == 0) {
LogE("read page table[0x%08x] faild", AdjustPageAddrOffset(sInfo.pageAddr, i));
break;
}
@ -916,7 +927,7 @@ void HFlashInitCheck()
const uint32_t num = sInfo.pageSize / sizeof(HFlashPageInfo);
do {
if (ReadFlash(sInfo.pageAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
if (ReadFlashCall(sInfo.pageAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
LogE("Read page table[0x%08x] faild", sInfo.pageAddr);
break;
}
@ -934,7 +945,7 @@ void HFlashInitCheck()
LogD("page table is invalid, check backup table");
// 备份校验
if (ReadFlash(sInfo.pageBackupAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
if (ReadFlashCall(sInfo.pageBackupAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
LogE("Read backup page table[0x%08x] faild", sInfo.pageBackupAddr);
break;
}
@ -949,8 +960,8 @@ void HFlashInitCheck()
break;
}
// 备份校验通过, 恢复备份数据
RestoreBackup(sInfo.pageBackupAddr, sInfo.pageAddr, sPageInfo.useNum);
// 备份校验通过, 恢复备份数据
RestoreBackup(sInfo.pageBackupAddr, sInfo.pageAddr, sInfo.pageSize);
return ;
} while (0);
@ -1221,7 +1232,7 @@ uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size)
}
const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize);
return ReadFlash(addr, data, readSize);
return ReadFlashCall(addr, data, readSize);
}
uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
@ -1247,12 +1258,12 @@ uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_
size -= remain;
}
return ReadFlash(addr + offset, data, size);
return ReadFlashCall(addr + offset, data, size);
}
uint8_t HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size)
{
return ReadFlash(addr, data, size);
return ReadFlashCall(addr, data, size);
}
void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData)