1. 修改Flash使用内存映射
This commit is contained in:
parent
d6fc4bfd9b
commit
06486210e1
@ -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);
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
void HFlashMemSync();
|
||||
|
||||
/**
|
||||
* @brief 释放缓存页
|
||||
*/
|
||||
void HFlashFreeCache();
|
||||
|
||||
#endif // __H_FLASH_MEM_H__
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
#endif
|
||||
|
||||
///< 使用Flash内存映射功能
|
||||
// #define USE_FLASH_MEM
|
||||
#define USE_FLASH_MEM
|
||||
|
||||
///< Flash块大小, 按块操作, 2的幂关系
|
||||
#ifndef HFLASH_BLOCK_SIZE
|
||||
|
||||
@ -386,7 +386,76 @@ uint8_t HFlashMemSetValue(uint32_t addr, uint8_t value, uint32_t len)
|
||||
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()
|
||||
{
|
||||
SyncCache();
|
||||
}
|
||||
|
||||
void HFlashFreeCache()
|
||||
{
|
||||
HFlashMemSync();
|
||||
sInfo.useNum = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -38,12 +38,18 @@ uint32_t HSCrc32Get()
|
||||
#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__);
|
||||
#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
|
||||
|
||||
// 最大热度
|
||||
@ -80,9 +86,11 @@ union PageInfo {
|
||||
};
|
||||
|
||||
struct Info {
|
||||
#ifndef USE_FLASH_MEM
|
||||
HFlashReadCallback read; ///< 读取回调
|
||||
HFlashWriteCallback write; ///< 写入回调
|
||||
HFlashEraseCallback erase; ///< 擦除回调
|
||||
#endif
|
||||
HFlashAddr_t pageAddr; ///< 页表地址
|
||||
HFlashAddr_t pageBackupAddr; ///< 页表备份地址
|
||||
uint32_t pageSize; ///< 页大小
|
||||
@ -141,7 +149,9 @@ static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
if (size == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef USE_FLASH_MEM
|
||||
return HFlashMemRead(addr, data, size);
|
||||
#else
|
||||
if (sInfo.read == NULL) {
|
||||
FATAL_ERROR("read is null");
|
||||
return 0;
|
||||
@ -149,8 +159,10 @@ static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size)
|
||||
|
||||
uint8_t *dataPtr = (uint8_t *)data;
|
||||
return sInfo.read(addr, dataPtr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef USE_FLASH_MEM
|
||||
static uint8_t EraseFlashCall(HFlashAddr_t addr)
|
||||
{
|
||||
if (sInfo.erase == NULL) {
|
||||
@ -160,7 +172,6 @@ static uint8_t EraseFlashCall(HFlashAddr_t addr)
|
||||
|
||||
return sInfo.erase(addr);
|
||||
}
|
||||
|
||||
static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||
{
|
||||
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;
|
||||
return sInfo.write(addr, dataPtr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_FLASH_MEM
|
||||
/**
|
||||
* @brief 写入数据到Flash
|
||||
* @param addr 写入的Flash地址
|
||||
@ -256,31 +269,40 @@ _flashError:
|
||||
HFLASH_FREE(buff);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_FLASH_MEM
|
||||
static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, void *userData)
|
||||
{
|
||||
(void)userData;
|
||||
memcpy(dest, src, buffSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t WriteFlash(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||
{
|
||||
#ifdef USE_FLASH_MEM
|
||||
HFlashMemWrite(addr, data, size);
|
||||
return HFlashMemWrite(addr, data, size);
|
||||
#else
|
||||
return WriteData(addr, data, size, _WriteFlashHelper, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef USE_FLASH_MEM
|
||||
static void _WriteFalshValueHelper(void *dest, const void *src, uint16_t size, void *userData)
|
||||
{
|
||||
uint8_t *value = (uint8_t *)userData;
|
||||
memset(dest, *value, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (size == 0) {
|
||||
@ -390,6 +420,12 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
|
||||
}
|
||||
|
||||
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);
|
||||
if (buff == NULL) {
|
||||
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) {
|
||||
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) {
|
||||
LogE("addr[0x%08x][0x%08x], size[%d] read faild", addr, addr + i, remain);
|
||||
break;
|
||||
@ -407,6 +443,7 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
|
||||
}
|
||||
|
||||
HFLASH_FREE(buff);
|
||||
#endif
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef USE_FLASH_MEM
|
||||
return HFlashMemAddrCopy(srcAddr, dstAddr, copySize);
|
||||
#else
|
||||
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE);
|
||||
if (buff == NULL) {
|
||||
LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, copySize);
|
||||
@ -480,6 +519,7 @@ _FlashError:
|
||||
HFLASH_FREE(buff);
|
||||
LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d][%d], result[%d]", srcAddr, dstAddr, size, copySize, result);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
///< 恢复指定页表
|
||||
@ -628,7 +668,24 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
|
||||
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));
|
||||
if (buff == NULL) {
|
||||
LogE("malloc faild");
|
||||
@ -637,7 +694,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);
|
||||
const uint32_t num = FAST_MIN(uint32_t, sPageInfo.useNum - i, pageNum);
|
||||
if (ReadFlashCall(AdjustPageAddrOffset(sInfo.pageAddr, i), buff, AdjustPageByte(num)) == 0) {
|
||||
LogE("read page table[0x%08x] faild", AdjustPageAddrOffset(sInfo.pageAddr, i));
|
||||
break;
|
||||
@ -658,6 +715,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
|
||||
|
||||
HFLASH_FREE(buff);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
///< 检查是否重叠, 重叠返回1
|
||||
@ -740,13 +798,13 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
||||
uint8_t fastCoolDown = 0;
|
||||
HFlashCacheInfo cache;
|
||||
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;
|
||||
if (sInfo.pageCache[i].info.addr != addr) {
|
||||
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) {
|
||||
return &sInfo.pageCache[i];
|
||||
}
|
||||
@ -775,7 +833,7 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
||||
memset(&cache, 0, sizeof(HFlashCacheInfo));
|
||||
cache.info.addr = addr;
|
||||
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) {
|
||||
++sInfo.pageCacheUseNum;
|
||||
}
|
||||
@ -802,9 +860,11 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
||||
|
||||
void HFlashInitCallback(HFlashReadCallback read, HFlashWriteCallback write, HFlashEraseCallback erase)
|
||||
{
|
||||
#ifndef USE_FLASH_MEM
|
||||
sInfo.read = read;
|
||||
sInfo.write = write;
|
||||
sInfo.erase = erase;
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1361,4 +1421,7 @@ void HFlashSync()
|
||||
SyncCachePage();
|
||||
SyncPageInfo();
|
||||
SyncBackup();
|
||||
#ifdef USE_FLASH_MEM
|
||||
HFlashMemSync();
|
||||
#endif
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user