1. 还需要优化一版, 先备份
This commit is contained in:
parent
150d642f22
commit
247e211168
@ -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;
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user