1. 完成Flash服务

This commit is contained in:
coffee 2025-12-01 19:33:57 +08:00
parent ea96363aff
commit 54c9dc52a7
2 changed files with 204 additions and 86 deletions

View File

@ -24,6 +24,16 @@
#define HFLASH_FREE(ptr) free(ptr)
#endif
///< 定时器ID
#ifndef HFLASH_TIMER_ID
#define HFLASH_TIMER_ID 0
#endif
///< 同步时间ms
#ifndef HFLASH_SYNC_TIME
#define HFLASH_SYNC_TIME 2000
#endif
#include <stdint.h>
#include <stdlib.h>
@ -131,11 +141,62 @@ void HFlashInitCheck();
void HFlashRegister(HFlashAddr_t addr, uint32_t size);
/**
* @brief HFlashWrite Flash,
* @param addr
* @brief HFlashWrite Flash数据
* @param addr
* @param data
* @param size
*/
void HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
/**
* @brief HFlashWriteOffset , 使, 0
* @param addr
* @param offset
* @param data
* @param size
*/
void HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size);
/**
* @brief HFlashRawWrite Flash数据, 西, 使
* @param addr
* @param data
* @param size
*/
void HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size);
/**
* @brief HFlashRead Flash数据
* @param addr
* @param data
* @param size
* @return 1: 0:
*/
void HFlashRead(HFlashAddr_t addr, void *data, uint32_t size);
/**
* @brief HFlashReadOffset
* @param addr
* @param offset
* @param data
* @param size
* @return 1: 0:
*/
void HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size);
/**
* @brief HFlashRawRead Flash数据, 西, 使
* @param addr
* @param data
* @param size
*/
void HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size);
/**
* @brief HFlashGetCrc32 Flash数据的CRC32值
* @param addr
* @return CRC32
*/
uint32_t HFlashGetCrc32(HFlashAddr_t addr);
#endif // __H_FLASH_SERVER_H__

View File

@ -3,6 +3,7 @@
#include "HFlashServer.h"
#include "HDLog.h"
#include "HVector.h"
#include "HTimer.h"
#if 1
@ -60,6 +61,9 @@ struct Info {
static struct Info sInfo;
static union PageInfo sPageInfo;
// 备份定时器
static HTimer_t sBackupTimer = HTIMER_INVALID;
// 需要备份的保护区地址页偏移
static HVECTOR_DEFINE32(sNeedBackupOffset, 10);
@ -108,6 +112,14 @@ static uint8_t EraseFlash(HFlashAddr_t addr)
return sInfo.erase(addr);
}
/**
* @brief Flash
* @param addr Flash地址
* @param data
* @param size
* @param call , dest缓存, src已经调整好位置的指针, buffSize需要拷贝的数据大小, userData用户数据
* @return
*/
static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*call)(void *dest, const void *src, uint16_t buffSize, void *userData), void *userData)
{
if (sInfo.write == NULL) {
@ -138,7 +150,6 @@ static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*cal
}
call(buff + offset, dataPtr, remain, userData);
// memcpy(buff + offset, dataPtr, remain);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
@ -155,7 +166,6 @@ static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*cal
}
call(buff, dataPtr, HFLASH_BLOCK_SIZE, userData);
// memcpy(buff, dataPtr, HFLASH_BLOCK_SIZE);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
@ -175,7 +185,6 @@ static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*cal
}
call(buff, dataPtr, size, userData);
// memcpy(buff, dataPtr, size);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
@ -198,82 +207,6 @@ static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, vo
static uint8_t WriteFlash(HFlashAddr_t addr, void *data, uint32_t size)
{
return WriteData(addr, data, size, _WriteFlashHelper, NULL);
#if 0
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;
uint32_t remain = offset + size > HFLASH_BLOCK_SIZE ? HFLASH_BLOCK_SIZE - offset : size;
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(HFLASH_BLOCK_SIZE);
uint8_t result = 0;
if (buff == NULL) {
LogE("addr[0x%08x], write size[%d] malloc faild", addr, size);
return 0;
}
// 先写入首个未对齐的块
if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], read faild", adjustAddr);
goto _flashError;
}
if (EraseFlash(adjustAddr) == 0) {
LogE("addr[0x%08x], erase faild", adjustAddr);
goto _flashError;
}
memcpy(buff + offset, dataPtr, remain);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
}
// 操作块读写
size -= remain;
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) {
LogE("addr[0x%08x], erase faild", adjustAddr);
goto _flashError;
}
memcpy(buff, dataPtr, HFLASH_BLOCK_SIZE);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
}
}
// 操作最后一个未对齐的块
if (size) {
if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], read faild", adjustAddr);
goto _flashError;
}
if (EraseFlash(adjustAddr) == 0) {
LogE("addr[0x%08x], erase faild", adjustAddr);
goto _flashError;
}
memcpy(buff, dataPtr, size);
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
LogE("addr[0x%08x], write faild", adjustAddr);
goto _flashError;
}
}
result = 1;
_flashError:
HFLASH_FREE(buff);
return result;
#endif
}
static void _WriteFalshValueHelper(void *dest, const void *src, uint16_t size, void *userData)
@ -289,6 +222,11 @@ static uint8_t WriteFlashValue(uint32_t addr, uint32_t size, uint8_t value)
static void SyncBackup()
{
if (sBackupTimer != HTIMER_INVALID) {
HTimerRemove(sBackupTimer);
sBackupTimer = HTIMER_INVALID;
}
// 需要备份的数据为空, 说明是二次调用, 上次已经同步了
if (HVectorEmpty(sNeedBackupOffset) && sPageInfo.needBackupPage == 0) {
return ;
@ -309,6 +247,12 @@ static void SyncBackup()
static void _AddBackupAddr(uint32_t addr)
{
if (sBackupTimer != HTIMER_INVALID) {
HTimerRemove(sBackupTimer);
sBackupTimer = HTIMER_INVALID;
}
sBackupTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_TIME, SyncBackup, kHTimerOnce);
const HVectorLenType index = HVectorFindData(sNeedBackupOffset, addr);
if (index == HVECTOR_ERROR) {
return ;
@ -586,6 +530,7 @@ static uint8_t _FindCacheHelper(uint32_t index, HFlashPageInfo *info, void *user
static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
{
uint8_t currMin = 0xFF;
HFlashCacheInfo cache;
for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
currMin = FLASH_MIN(uint8_t, currMin, sInfo.pageCache[i].heat);
if (sInfo.pageCache[i].info.addr != addr) {
@ -593,6 +538,19 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
}
sInfo.pageCache[i].heat = FLASH_MIN(uint8_t, sInfo.pageCache[i].heat + 1, ((1 << 5) - 1));
if (i == 0) {
return &sInfo.pageCache[i];
}
// 这里需要根据热度交换缓存位置
if (sInfo.pageCache[i].heat > sInfo.pageCache[i - 1].heat) {
cache = sInfo.pageCache[i];
sInfo.pageCache[i] = sInfo.pageCache[i - 1];
sInfo.pageCache[i - 1] = cache;
--i;
}
return &sInfo.pageCache[i];
}
@ -604,7 +562,6 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
}
// 查找到了就直接替换最后面的就行
HFlashCacheInfo cache;
memset(&cache, 0, sizeof(HFlashCacheInfo));
cache.info.addr = addr;
if (ScanPage(_FindCacheHelper, &cache)) {
@ -795,6 +752,8 @@ void HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
return ;
}
++cache->info.modifyCount;
// 更新使用长度
if (cache->info.useSize < size) {
cache->info.useSize = size;
@ -804,14 +763,112 @@ void HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
HSCrc32Reset();
HSCrc32Update((uint8_t *)data, size);
cache->info.crc32 = HSCrc32Get();
++cache->info.modifyCount;
WriteFlash(addr, data, size);
WritePage(cache->pos, &cache->info);
// 检查是否在保护区域, 需要的话需要写入等待备份
if (IsProtect(addr, size)) {
AddBackupAddr(addr, size);
}
WriteFlash(addr, data, size);
WritePage(cache->pos, &cache->info);
}
void HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
{
HFlashCacheInfo *cache = FindCache(addr);
if (cache == NULL) {
FATAL_ERROR("addr[0x%08x] not register", addr);
return ;
}
const uint32_t useSize = offset + size;
// 检查写入数据大小是否超出注册提供的大小范围
if (cache->info.size < useSize) {
FATAL_ERROR("addr[0x%08x] size[%d] overflow", addr, useSize);
return ;
}
++cache->info.modifyCount;
// 更新使用长度, 将跨越的部分填充0
if (cache->info.useSize < useSize) {
if (cache->info.useSize < offset) {
WriteFlashValue(addr + cache->info.useSize, offset - cache->info.useSize, 0);
}
cache->info.useSize = useSize;
}
cache->info.crc32 = GetFlashCrc32(addr, useSize);
WriteFlash(addr + offset, data, size);
WritePage(cache->pos, &cache->info);
// 检查是否在保护区域, 需要的话需要写入等待备份
if (IsProtect(addr, size)) {
AddBackupAddr(addr, useSize);
}
}
void HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size)
{
WriteFlash(addr, data, size);
}
void HFlashRead(HFlashAddr_t addr, void *data, uint32_t size)
{
HFlashCacheInfo *cache = FindCache(addr);
if (cache == NULL) {
FATAL_ERROR("addr[0x%08x] not register", addr);
memset(data, 0, size);
return ;
}
// 超出部分填充0
if (cache->info.useSize < 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);
ReadFlash(addr, data, readSize);
}
void HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
{
HFlashCacheInfo *cache = FindCache(addr);
if (cache == NULL) {
FATAL_ERROR("addr[0x%08x] not register", addr);
memset(data, 0, size);
return ;
}
// 读取的偏移量超出使用长度
if (cache->info.useSize < offset) {
memset(data, 0, size);
return ;
}
// 读取的数据超出使用长度, 将使用长度后面填充0
const uint32_t useSize = offset + size;
const uint32_t remain = useSize - cache->info.useSize;
if (cache->info.useSize < useSize) {
memset((uint8_t *)data + size - remain, 0, remain);
}
ReadFlash(addr, data, size - remain);
}
void HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size)
{
ReadFlash(addr, data, size);
}
uint32_t HFlashGetCrc32(HFlashAddr_t addr)
{
HFlashCacheInfo *cache = FindCache(addr);
if (cache == NULL) {
FATAL_ERROR("addr[0x%08x] not register", addr);
return 0xFFFFFFFF;
}
return cache->info.crc32;
}