1. 完善Flash模块

This commit is contained in:
coffee 2025-12-02 20:35:42 +08:00
parent 92bfa80e77
commit 1616de90d7
2 changed files with 114 additions and 9 deletions

View File

@ -8,8 +8,15 @@
#ifndef __H_FLASH_SERVER_H__ #ifndef __H_FLASH_SERVER_H__
#define __H_FLASH_SERVER_H__ #define __H_FLASH_SERVER_H__
// #define USE_STD_MEM
#include <stdint.h> #include <stdint.h>
#ifndef USE_STD_MEM
#include "HDSendBuffer.h"
#endif
///< Flash块大小, 按块操作, 2的幂关系 ///< Flash块大小, 按块操作, 2的幂关系
#ifndef HFLASH_BLOCK_SIZE #ifndef HFLASH_BLOCK_SIZE
#define HFLASH_BLOCK_SIZE (4096) #define HFLASH_BLOCK_SIZE (4096)
@ -17,12 +24,20 @@
///< 获取缓存内存, 需要能申请到大于等于Flash一块大小 ///< 获取缓存内存, 需要能申请到大于等于Flash一块大小
#ifndef HFLASH_MALLOC #ifndef HFLASH_MALLOC
#ifdef USE_STD_MEM
#define HFLASH_MALLOC(size) malloc(size) #define HFLASH_MALLOC(size) malloc(size)
#else
#define HFLASH_MALLOC(size) HDSendBufferGet(size)
#endif
#endif #endif
///< 释放缓存 ///< 释放缓存
#ifndef HFLASH_FREE #ifndef HFLASH_FREE
#ifdef USE_STD_MEM
#define HFLASH_FREE(ptr) free(ptr) #define HFLASH_FREE(ptr) free(ptr)
#else
#define HFLASH_FREE(ptr) HDSendBufferFree(ptr)
#endif
#endif #endif
///< 定时器ID ///< 定时器ID
@ -133,7 +148,8 @@ void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size);
void HFlashInitCheck(); void HFlashInitCheck();
/** /**
* @brief HFlashRegister * @brief HFlashRegister ,
* , 使
* @param addr * @param addr
* @param size * @param size
*/ */
@ -235,6 +251,26 @@ typedef void (*HFlashUpdateVersionCallback)(HFlashAddr_t addr, uint16_t oldVersi
*/ */
void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData); void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData);
/**
* @brief HFlashDeleteFile
* @param addr
*/
void HFlashDeleteData(HFlashAddr_t addr);
/**
* @brief HFlashGetUseSize Flash数据的使用大小
* @param addr
* @return 使
*/
uint32_t HFlashGetUseSize(HFlashAddr_t addr);
/**
* @brief HFlashGetSize Flash数据的大小
* @param addr
* @return
*/
uint32_t HFlashGetSize(HFlashAddr_t addr);
/** /**
* @brief HFlashGetCrc32 Flash数据的CRC32值 * @brief HFlashGetCrc32 Flash数据的CRC32值
* @param addr * @param addr

View File

@ -5,8 +5,13 @@
#include "HVector.h" #include "HVector.h"
#include "HTimer.h" #include "HTimer.h"
#ifndef USE_STD_MEM
#include "HDSendBuffer.h"
#include "HSCrc32.h"
#endif
#if 1
#ifdef USE_STD_MEM
#include <nmmintrin.h> #include <nmmintrin.h>
static uint32_t sCrcValue; static uint32_t sCrcValue;
void HSCrc32Reset() void HSCrc32Reset()
@ -29,8 +34,11 @@ uint32_t HSCrc32Get()
// 计算最小值 // 计算最小值
#define FLASH_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b))))) #define FLASH_MIN(type, a, b) ((b) ^ (((a) ^ (b)) & (-(type)((a) < (b)))))
// #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1); #ifdef USE_STD_MEM
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); #define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__);
#else
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1);
#endif
// 最大热度 // 最大热度
#define MAX_HEAT ((1 << 4) - 1) #define MAX_HEAT ((1 << 4) - 1)
@ -74,6 +82,7 @@ static HVECTOR_DEFINE32(sNeedBackupOffset, 10);
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 size);
static void StartBackupTimer();
///< 检查地址是否在双备份保护区内 ///< 检查地址是否在双备份保护区内
static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size) static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size)
@ -241,7 +250,11 @@ static void SyncBackup()
for (uint16_t i = 0; i < HVectorGetUseLen(sNeedBackupOffset); ++i) { for (uint16_t i = 0; i < HVectorGetUseLen(sNeedBackupOffset); ++i) {
const uint32_t addr = HVectorGetData(sNeedBackupOffset, i); const uint32_t addr = HVectorGetData(sNeedBackupOffset, i);
const uint32_t destAddr = sInfo.protectBackupAddr + (addr - sInfo.protectAddr); const uint32_t destAddr = sInfo.protectBackupAddr + (addr - sInfo.protectAddr);
RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE); if (RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE) == 0) {
LogE("RestorePage faild, addr[0x%08x]", addr);
StartBackupTimer();
return ;
}
} }
HVectorClear(sNeedBackupOffset); HVectorClear(sNeedBackupOffset);
@ -338,7 +351,8 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
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 size)
{ {
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE); const uint16_t mallocSize = 1024;
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(mallocSize);
if (buff == NULL) { if (buff == NULL) {
LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, size); LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, size);
return 0; return 0;
@ -347,8 +361,8 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_
uint8_t result = 0; uint8_t result = 0;
uint32_t i = 0; uint32_t i = 0;
uint32_t remain = 0; uint32_t remain = 0;
for (; i < size; i += HFLASH_BLOCK_SIZE) { for (; i < size; i += mallocSize) {
remain = FLASH_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE); remain = FLASH_MIN(uint32_t, size - i, mallocSize);
result = result || ReadFlash(srcAddr + i, buff, remain) == 0; result = result || ReadFlash(srcAddr + i, buff, remain) == 0;
result = result || WriteFlash(dstAddr + i, buff, remain) == 0; result = result || WriteFlash(dstAddr + i, buff, remain) == 0;
@ -504,6 +518,7 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
return result; return result;
} }
///< 检查是否重叠, 重叠返回1
static uint8_t _CreatePageInfoHelper(uint32_t index, HFlashPageInfo *info, void *userData) static uint8_t _CreatePageInfoHelper(uint32_t index, HFlashPageInfo *info, void *userData)
{ {
HFlashPageInfo *cache = (HFlashPageInfo *)userData; HFlashPageInfo *cache = (HFlashPageInfo *)userData;
@ -734,13 +749,33 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
return ; return ;
} }
// 检查是否需要更新页表存储的大小
if (size != cache->info.size) {
LogD("Update addr[0x%08x] size[%d], useSize[%d], oldSize[%d]", addr, size, cache->info.useSize, cache->info.size);
cache->info.size = size;
// 检查页表地址是否和当前页表地址范围内存在重叠
if (ScanPage(_CreatePageInfoHelper, &cache->info)) {
FATAL_ERROR("addr[0x%08x] size[%d] exist range Error", addr, size);
return ;
}
cache->waitWrite = 1;
}
// 已使用空间大于容量, 页表数据异常或者容量被缩小, 丢弃数据, 如果是保护区域下面会恢复
if (cache->info.useSize > size) {
LogE("addr[0x%08x] useSize[%d] > size[%d]", addr, cache->info.useSize, size);
cache->info.useSize = 0;
}
// 检查是否在保护区域, 不是保护区域不需要检查crc校验 // 检查是否在保护区域, 不是保护区域不需要检查crc校验
if (IsProtect(addr, size) == 0) { if (IsProtect(addr, size) == 0) {
return ; return ;
} }
// 检查保护区域的crc是否相同 // 检查保护区域的crc是否相同
if (GetFlashCrc32(addr, size) == cache->info.crc32) { if (GetFlashCrc32(addr, cache->info.useSize) == cache->info.crc32) {
return ; return ;
} }
@ -749,7 +784,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
RestoreBackup(sInfo.protectBackupAddr + (cache->info.addr - sInfo.protectAddr), cache->info.addr, cache->info.size); RestoreBackup(sInfo.protectBackupAddr + (cache->info.addr - sInfo.protectAddr), cache->info.addr, cache->info.size);
// 如果恢复后还校验失败, 那就恢复对应页表 // 如果恢复后还校验失败, 那就恢复对应页表
const uint32_t contentCrc = GetFlashCrc32(cache->info.addr, cache->info.size); const uint32_t contentCrc = GetFlashCrc32(cache->info.addr, cache->info.useSize);
if (contentCrc == cache->info.crc32) { if (contentCrc == cache->info.crc32) {
return ; return ;
} }
@ -975,6 +1010,40 @@ void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVer
} }
} }
void HFlashDeleteData(HFlashAddr_t addr)
{
HFlashCacheInfo *cache = FindCache(addr);
if (cache == NULL) {
FATAL_ERROR("addr[0x%08x] not register", addr);
return ;
}
cache->info.useSize = 0;
WriteCachePage(cache);
}
uint32_t HFlashGetUseSize(HFlashAddr_t addr)
{
HFlashCacheInfo *cache = FindCache(addr);
if (cache == NULL) {
FATAL_ERROR("addr[0x%08x] not register", addr);
return 0;
}
return cache->info.useSize;
}
uint32_t HFlashGetSize(HFlashAddr_t addr)
{
HFlashCacheInfo *cache = FindCache(addr);
if (cache == NULL) {
FATAL_ERROR("addr[0x%08x] not register", addr);
return 0;
}
return cache->info.size;
}
uint32_t HFlashGetCrc32(HFlashAddr_t addr) uint32_t HFlashGetCrc32(HFlashAddr_t addr)
{ {
HFlashCacheInfo *cache = FindCache(addr); HFlashCacheInfo *cache = FindCache(addr);