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__
#define __H_FLASH_SERVER_H__
// #define USE_STD_MEM
#include <stdint.h>
#ifndef USE_STD_MEM
#include "HDSendBuffer.h"
#endif
///< Flash块大小, 按块操作, 2的幂关系
#ifndef HFLASH_BLOCK_SIZE
#define HFLASH_BLOCK_SIZE (4096)
@ -17,12 +24,20 @@
///< 获取缓存内存, 需要能申请到大于等于Flash一块大小
#ifndef HFLASH_MALLOC
#ifdef USE_STD_MEM
#define HFLASH_MALLOC(size) malloc(size)
#else
#define HFLASH_MALLOC(size) HDSendBufferGet(size)
#endif
#endif
///< 释放缓存
#ifndef HFLASH_FREE
#ifdef USE_STD_MEM
#define HFLASH_FREE(ptr) free(ptr)
#else
#define HFLASH_FREE(ptr) HDSendBufferFree(ptr)
#endif
#endif
///< 定时器ID
@ -133,7 +148,8 @@ void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size);
void HFlashInitCheck();
/**
* @brief HFlashRegister
* @brief HFlashRegister ,
* , 使
* @param addr
* @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);
/**
* @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值
* @param addr

View File

@ -5,8 +5,13 @@
#include "HVector.h"
#include "HTimer.h"
#ifndef USE_STD_MEM
#include "HDSendBuffer.h"
#include "HSCrc32.h"
#endif
#if 1
#ifdef USE_STD_MEM
#include <nmmintrin.h>
static uint32_t sCrcValue;
void HSCrc32Reset()
@ -29,8 +34,11 @@ uint32_t HSCrc32Get()
// 计算最小值
#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__);
#else
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1);
#endif
// 最大热度
#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 void StartBackupTimer();
///< 检查地址是否在双备份保护区内
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) {
const uint32_t addr = HVectorGetData(sNeedBackupOffset, i);
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);
@ -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)
{
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) {
LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, size);
return 0;
@ -347,8 +361,8 @@ static uint8_t RestoreBackup(HFlashAddr_t srcAddr, HFlashAddr_t dstAddr, uint32_
uint8_t result = 0;
uint32_t i = 0;
uint32_t remain = 0;
for (; i < size; i += HFLASH_BLOCK_SIZE) {
remain = FLASH_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE);
for (; i < size; i += mallocSize) {
remain = FLASH_MIN(uint32_t, size - i, mallocSize);
result = result || ReadFlash(srcAddr + 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;
}
///< 检查是否重叠, 重叠返回1
static uint8_t _CreatePageInfoHelper(uint32_t index, HFlashPageInfo *info, void *userData)
{
HFlashPageInfo *cache = (HFlashPageInfo *)userData;
@ -734,13 +749,33 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
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校验
if (IsProtect(addr, size) == 0) {
return ;
}
// 检查保护区域的crc是否相同
if (GetFlashCrc32(addr, size) == cache->info.crc32) {
if (GetFlashCrc32(addr, cache->info.useSize) == cache->info.crc32) {
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);
// 如果恢复后还校验失败, 那就恢复对应页表
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) {
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)
{
HFlashCacheInfo *cache = FindCache(addr);