1. 修改Flash使用内存映射

This commit is contained in:
coffee 2025-12-25 16:20:51 +08:00
parent d6fc4bfd9b
commit 06486210e1
4 changed files with 169 additions and 15 deletions

View File

@ -79,9 +79,31 @@ uint8_t HFlashMemWrite(uint32_t addr, const void *buf, uint32_t len);
*/ */
uint8_t HFlashMemSetValue(uint32_t addr, uint8_t value, uint32_t len); uint8_t HFlashMemSetValue(uint32_t addr, uint8_t value, uint32_t len);
/**
* @brief Flash数据拷贝
* @param srcAddr
* @param destAddr
* @param len
*/
uint8_t HFlashMemAddrCopy(uint32_t srcAddr, uint32_t destAddr, uint32_t len);
/**
* @brief Flash数据映射回调
* @param addr
* @param call , 0, ,
* @param arg
* @return call返回值
*/
uint8_t HFlashMemMMapCall(uint32_t addr, uint8_t(*call)(uint32_t addr, uint32_t offset, const uint8_t *data, uint16_t len, void *arg), void *arg);
/** /**
* @brief Flash * @brief Flash
*/ */
void HFlashMemSync(); void HFlashMemSync();
/**
* @brief
*/
void HFlashFreeCache();
#endif // __H_FLASH_MEM_H__ #endif // __H_FLASH_MEM_H__

View File

@ -17,7 +17,7 @@
#endif #endif
///< 使用Flash内存映射功能 ///< 使用Flash内存映射功能
// #define USE_FLASH_MEM #define USE_FLASH_MEM
///< Flash块大小, 按块操作, 2的幂关系 ///< Flash块大小, 按块操作, 2的幂关系
#ifndef HFLASH_BLOCK_SIZE #ifndef HFLASH_BLOCK_SIZE

View File

@ -386,7 +386,76 @@ uint8_t HFlashMemSetValue(uint32_t addr, uint8_t value, uint32_t len)
return WriteData(addr, NULL, len, _MemSetValueHelper, &value); return WriteData(addr, NULL, len, _MemSetValueHelper, &value);
} }
static void _MemAddrCopy(void *dest, const void *src, uint32_t len, void *userData)
{
uint32_t srcAddr = *(uint32_t *)userData;
HFlashMemRead(srcAddr + (long)src, dest, len);
}
uint8_t HFlashMemAddrCopy(uint32_t srcAddr, uint32_t destAddr, uint32_t len)
{
if (sOpts == NULL) {
return 0;
}
return WriteData(destAddr, NULL, len, _MemAddrCopy, &srcAddr);
}
uint8_t HFlashMemMMapCall(uint32_t addr, uint8_t(*call)(uint32_t addr, uint32_t offset, const uint8_t *data, uint16_t len, void *arg), void *arg)
{
if (sOpts == NULL || call == NULL) {
return 0;
}
uint32_t offset = 0;
HFlashMemCache *cache = NULL;
uint16_t len = 0;
uint8_t result = 0;
// 先处理未对齐的部分
if (addr != Align4K(addr)) {
cache = FindCache(addr + offset, 1);
if (cache == NULL) {
LogE("addr[0x%08x], find cache faild", addr);
return 0;
}
len = HFLASH_BLOCK_SIZE - (addr - cache->addr);
result = call(addr, offset, GetMMap(cache->offset) + (addr - cache->addr), len, arg);
offset += len;
}
if (result) {
return result;
}
// 剩余处理对齐部分
while (result == 0) {
cache = FindCache(addr + offset, 1);
if (cache == NULL) {
LogE("addr[0x%08x], find cache faild", addr + offset);
return 0;
}
result = call(addr + offset, offset, GetMMap(cache->offset), HFLASH_BLOCK_SIZE ,arg);
if (result) {
break;
}
offset += HFLASH_BLOCK_SIZE;
}
return result;
}
void HFlashMemSync() void HFlashMemSync()
{ {
SyncCache(); SyncCache();
} }
void HFlashFreeCache()
{
HFlashMemSync();
sInfo.useNum = 0;
}

View File

@ -38,12 +38,18 @@ uint32_t HSCrc32Get()
#endif #endif
// 计算最小值 // 计算最小值
#define FLASH_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b))))) #define FAST_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b)))))
#ifdef USE_STD_MEM #ifdef USE_FATAL_NOT_LOOP
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__);
#else #else
#define FATAL_ERROR(format, ...) while (1) { LogE(format, ##__VA_ARGS__); HShellRun(); }; __attribute__((weak))
void HDMainLoopCallOverride(uint8_t event)
{
(void)(event);
HShellRun();
}
#define FATAL_ERROR(format, ...) while (1) { LogE(format, ##__VA_ARGS__); HDMainLoopCallOverride(0); };
#endif #endif
// 最大热度 // 最大热度
@ -80,9 +86,11 @@ union PageInfo {
}; };
struct Info { struct Info {
#ifndef USE_FLASH_MEM
HFlashReadCallback read; ///< 读取回调 HFlashReadCallback read; ///< 读取回调
HFlashWriteCallback write; ///< 写入回调 HFlashWriteCallback write; ///< 写入回调
HFlashEraseCallback erase; ///< 擦除回调 HFlashEraseCallback erase; ///< 擦除回调
#endif
HFlashAddr_t pageAddr; ///< 页表地址 HFlashAddr_t pageAddr; ///< 页表地址
HFlashAddr_t pageBackupAddr; ///< 页表备份地址 HFlashAddr_t pageBackupAddr; ///< 页表备份地址
uint32_t pageSize; ///< 页大小 uint32_t pageSize; ///< 页大小
@ -141,7 +149,9 @@ static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size)
if (size == 0) { if (size == 0) {
return 1; return 1;
} }
#ifdef USE_FLASH_MEM
return HFlashMemRead(addr, data, size);
#else
if (sInfo.read == NULL) { if (sInfo.read == NULL) {
FATAL_ERROR("read is null"); FATAL_ERROR("read is null");
return 0; return 0;
@ -149,8 +159,10 @@ static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size)
uint8_t *dataPtr = (uint8_t *)data; uint8_t *dataPtr = (uint8_t *)data;
return sInfo.read(addr, dataPtr, size); return sInfo.read(addr, dataPtr, size);
#endif
} }
#ifndef USE_FLASH_MEM
static uint8_t EraseFlashCall(HFlashAddr_t addr) static uint8_t EraseFlashCall(HFlashAddr_t addr)
{ {
if (sInfo.erase == NULL) { if (sInfo.erase == NULL) {
@ -160,7 +172,6 @@ static uint8_t EraseFlashCall(HFlashAddr_t addr)
return sInfo.erase(addr); return sInfo.erase(addr);
} }
static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size) static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size)
{ {
if (size == 0) { if (size == 0) {
@ -175,7 +186,9 @@ static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size
uint8_t *dataPtr = (uint8_t *)data; uint8_t *dataPtr = (uint8_t *)data;
return sInfo.write(addr, dataPtr, size); return sInfo.write(addr, dataPtr, size);
} }
#endif
#ifndef USE_FLASH_MEM
/** /**
* @brief Flash * @brief Flash
* @param addr Flash地址 * @param addr Flash地址
@ -256,31 +269,40 @@ _flashError:
HFLASH_FREE(buff); HFLASH_FREE(buff);
return result; return result;
} }
#endif
#ifndef USE_FLASH_MEM
static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, void *userData) static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, void *userData)
{ {
(void)userData; (void)userData;
memcpy(dest, src, buffSize); memcpy(dest, src, buffSize);
} }
#endif
static uint8_t WriteFlash(HFlashAddr_t addr, const void *data, uint32_t size) static uint8_t WriteFlash(HFlashAddr_t addr, const void *data, uint32_t size)
{ {
#ifdef USE_FLASH_MEM #ifdef USE_FLASH_MEM
HFlashMemWrite(addr, data, size); return HFlashMemWrite(addr, data, size);
#else #else
return WriteData(addr, data, size, _WriteFlashHelper, NULL); return WriteData(addr, data, size, _WriteFlashHelper, NULL);
#endif #endif
} }
#ifndef USE_FLASH_MEM
static void _WriteFalshValueHelper(void *dest, const void *src, uint16_t size, void *userData) static void _WriteFalshValueHelper(void *dest, const void *src, uint16_t size, void *userData)
{ {
uint8_t *value = (uint8_t *)userData; uint8_t *value = (uint8_t *)userData;
memset(dest, *value, size); memset(dest, *value, size);
} }
#endif
static uint8_t WriteFlashValue(uint32_t addr, uint32_t size, uint8_t value) static uint8_t WriteFlashValue(uint32_t addr, uint32_t size, uint8_t value)
{ {
#ifdef USE_FLASH_MEM
return HFlashMemSetValue(addr, value, size);
#else
return WriteData(addr, NULL, size, _WriteFalshValueHelper, &value); return WriteData(addr, NULL, size, _WriteFalshValueHelper, &value);
#endif
} }
static inline uint32_t AdjustPageAddr(uint32_t addr) static inline uint32_t AdjustPageAddr(uint32_t addr)
@ -383,6 +405,14 @@ static void AddBackupAddr(uint32_t addr, uint32_t size)
} }
} }
static uint8_t _CalcCrc32(uint32_t addr, uint32_t offset, const uint8_t *data, uint16_t len, void *args)
{
uint32_t needLen = *(uint32_t *)args;
uint32_t calcLen = FAST_MIN(uint32_t, (needLen - offset), len);
HSCrc32Update(data, calcLen);
return needLen <= offset + len;
}
static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size) static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
{ {
if (size == 0) { if (size == 0) {
@ -390,6 +420,12 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
} }
HSCrc32Reset(); HSCrc32Reset();
#ifdef USE_FLASH_MEM
if (HFlashMemMMapCall(addr, _CalcCrc32, &size) == 0) {
LogE("addr[0x%08x], size[%d] mmap faild", addr, size);
return 0xFFFFFFFF;
}
#else
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE); uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE);
if (buff == NULL) { if (buff == NULL) {
LogE("addr[0x%08x], write size[%d] malloc faild", addr, size); LogE("addr[0x%08x], write size[%d] malloc faild", addr, size);
@ -397,7 +433,7 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
} }
for (uint32_t i = 0; i < size; i += HFLASH_BLOCK_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); const uint32_t remain = FAST_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE);
if (ReadFlashCall(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); LogE("addr[0x%08x][0x%08x], size[%d] read faild", addr, addr + i, remain);
break; break;
@ -407,6 +443,7 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
} }
HFLASH_FREE(buff); HFLASH_FREE(buff);
#endif
return HSCrc32Get(); return HSCrc32Get();
} }
@ -416,7 +453,9 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_
LogD("addr[0x%08x], write size[%d] is 0", srcAddr, copySize); LogD("addr[0x%08x], write size[%d] is 0", srcAddr, copySize);
return 1; return 1;
} }
#ifdef USE_FLASH_MEM
return HFlashMemAddrCopy(srcAddr, dstAddr, copySize);
#else
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE); uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE);
if (buff == NULL) { if (buff == NULL) {
LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, copySize); LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, copySize);
@ -480,6 +519,7 @@ _FlashError:
HFLASH_FREE(buff); HFLASH_FREE(buff);
LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d][%d], result[%d]", srcAddr, dstAddr, size, copySize, result); LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d][%d], result[%d]", srcAddr, dstAddr, size, copySize, result);
return result; return result;
#endif
} }
///< 恢复指定页表 ///< 恢复指定页表
@ -628,7 +668,24 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
return 0; return 0;
} }
const uint32_t pageNum = FLASH_MIN(uint32_t, sPageInfo.useNum, (HFLASH_BLOCK_SIZE / sizeof(HFlashPageInfo))); #ifdef USE_FLASH_MEM
HFlashPageInfo page;
uint8_t result = 0;
for (uint32_t i = 0; i < sPageInfo.useNum; ++i) {
if (HFlashMemRead(AdjustPageAddrOffset(sInfo.pageAddr, i), &page, sizeof(HFlashPageInfo)) == 0) {
LogE("read page table[0x%08x] faild", AdjustPageAddrOffset(sInfo.pageAddr, i));
return 0;
}
result = call(i, &page, userData);
if (result) {
break;
}
}
return result;
#else
const uint32_t pageNum = FAST_MIN(uint32_t, sPageInfo.useNum, (HFLASH_BLOCK_SIZE / sizeof(HFlashPageInfo)));
HFlashPageInfo *buff = (HFlashPageInfo *)HFLASH_MALLOC(pageNum * sizeof(HFlashPageInfo)); HFlashPageInfo *buff = (HFlashPageInfo *)HFLASH_MALLOC(pageNum * sizeof(HFlashPageInfo));
if (buff == NULL) { if (buff == NULL) {
LogE("malloc faild"); LogE("malloc faild");
@ -637,7 +694,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
uint8_t result = 0; uint8_t result = 0;
for (uint32_t i = 0; i < sPageInfo.useNum; i += pageNum) { for (uint32_t i = 0; i < sPageInfo.useNum; i += pageNum) {
const uint32_t num = FLASH_MIN(uint32_t, sPageInfo.useNum - i, pageNum); const uint32_t num = FAST_MIN(uint32_t, sPageInfo.useNum - i, pageNum);
if (ReadFlashCall(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)); LogE("read page table[0x%08x] faild", AdjustPageAddrOffset(sInfo.pageAddr, i));
break; break;
@ -658,6 +715,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
HFLASH_FREE(buff); HFLASH_FREE(buff);
return result; return result;
#endif
} }
///< 检查是否重叠, 重叠返回1 ///< 检查是否重叠, 重叠返回1
@ -740,13 +798,13 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
uint8_t fastCoolDown = 0; 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 = FAST_MIN(uint8_t, currMin, sInfo.pageCache[i].heat);
fastCoolDown = fastCoolDown || sInfo.pageCache[i].heat >= MAX_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, MAX_HEAT); sInfo.pageCache[i].heat = FAST_MIN(uint8_t, sInfo.pageCache[i].heat + 1, MAX_HEAT);
if (i == 0) { if (i == 0) {
return &sInfo.pageCache[i]; return &sInfo.pageCache[i];
} }
@ -775,7 +833,7 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
memset(&cache, 0, sizeof(HFlashCacheInfo)); memset(&cache, 0, sizeof(HFlashCacheInfo));
cache.info.addr = addr; cache.info.addr = addr;
if (ScanPage(_FindCacheHelper, &cache)) { if (ScanPage(_FindCacheHelper, &cache)) {
const uint16_t index = FLASH_MIN(uint16_t, sInfo.pageCacheUseNum, sInfo.pageCacheSize - 1); const uint16_t index = FAST_MIN(uint16_t, sInfo.pageCacheUseNum, sInfo.pageCacheSize - 1);
if (sInfo.pageCacheUseNum < sInfo.pageCacheSize) { if (sInfo.pageCacheUseNum < sInfo.pageCacheSize) {
++sInfo.pageCacheUseNum; ++sInfo.pageCacheUseNum;
} }
@ -802,9 +860,11 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
void HFlashInitCallback(HFlashReadCallback read, HFlashWriteCallback write, HFlashEraseCallback erase) void HFlashInitCallback(HFlashReadCallback read, HFlashWriteCallback write, HFlashEraseCallback erase)
{ {
#ifndef USE_FLASH_MEM
sInfo.read = read; sInfo.read = read;
sInfo.write = write; sInfo.write = write;
sInfo.erase = erase; sInfo.erase = erase;
#endif
} }
void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size) void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size)
@ -1244,7 +1304,7 @@ uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size)
memset((uint8_t *)data + cache->info.useSize, 0, size - cache->info.useSize); memset((uint8_t *)data + cache->info.useSize, 0, size - cache->info.useSize);
} }
const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize); const uint32_t readSize = FAST_MIN(uint32_t, size, cache->info.useSize);
return ReadFlashCall(addr, data, readSize); return ReadFlashCall(addr, data, readSize);
} }
@ -1361,4 +1421,7 @@ void HFlashSync()
SyncCachePage(); SyncCachePage();
SyncPageInfo(); SyncPageInfo();
SyncBackup(); SyncBackup();
#ifdef USE_FLASH_MEM
HFlashMemSync();
#endif
} }