Compare commits
5 Commits
dda4f91b42
...
176709e37d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
176709e37d | ||
|
|
247e211168 | ||
|
|
150d642f22 | ||
|
|
a902eb38c8 | ||
|
|
276218d3e0 |
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
// 使用宏开关管理日志
|
// 使用宏开关管理日志
|
||||||
#ifndef LOG_CLOSE_OUT
|
#ifndef LOG_CLOSE_OUT
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#define USE_HD_LOG_DATA (1)
|
#define USE_HD_LOG_DATA (1)
|
||||||
#define USE_HD_TRACE (1)
|
#define USE_HD_TRACE (1)
|
||||||
#define USE_HD_FPGA_CHECK (1)
|
#define USE_HD_FPGA_CHECK (1)
|
||||||
|
#define USE_HD_OPT_LOG (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 当前检查栈数量的线程总数
|
// 当前检查栈数量的线程总数
|
||||||
@ -89,6 +91,13 @@
|
|||||||
#endif
|
#endif
|
||||||
#define InitLogData() HDLogInit(NULL)
|
#define InitLogData() HDLogInit(NULL)
|
||||||
|
|
||||||
|
// 操作日志
|
||||||
|
#if USE_HD_OPT_LOG
|
||||||
|
#define LogOpt(format, ...) HDLogOptOut(format, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LogOpt(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum eLogLevel {
|
typedef enum eLogLevel {
|
||||||
kLogLevelSwitch = 0, ///< 日志开关
|
kLogLevelSwitch = 0, ///< 日志开关
|
||||||
kLogLevelColor, ///< 彩色日志
|
kLogLevelColor, ///< 彩色日志
|
||||||
@ -120,17 +129,27 @@ void HDLogOptFlashInit();
|
|||||||
void HDLogInit(uint32_t (*getTime)());
|
void HDLogInit(uint32_t (*getTime)());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取当前时间
|
* @brief 设置操作日志输出回调
|
||||||
* @return 当前时间
|
* @param call 日志输出调用
|
||||||
|
*/
|
||||||
|
void HDLogSetOptCall(void (*call)(const char *format, va_list args));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取运行时间
|
||||||
|
* @return 运行时间
|
||||||
*/
|
*/
|
||||||
uint32_t HDLogGetTime();
|
uint32_t HDLogGetTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 格式打印
|
* @brief 格式打印
|
||||||
**/
|
**/
|
||||||
__attribute__ ((format(printf, 6, 7)))
|
|
||||||
void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *funcName, int line, const char *format, ...);
|
void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *funcName, int line, const char *format, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 操作日志格式打印
|
||||||
|
*/
|
||||||
|
void HDLogOptOut(const char *format, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 打印FPGA
|
* @brief 打印FPGA
|
||||||
* @param data FPGA数据
|
* @param data FPGA数据
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* 日期: 2025-11-27
|
* 日期: 2025-11-27
|
||||||
* 作者: coffee
|
* 作者: coffee
|
||||||
* 描述: Flash通用服务模块, 用于保证Flash操作的完备性, 支持任意长度数据读写
|
* 描述: Flash通用服务模块, 用于保证Flash操作的完备性, 支持任意长度数据读写, 因内部使用延后处理, 需要重启时必须调用同步
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
#define HFLASH_BLOCK_SIZE (4096)
|
#define HFLASH_BLOCK_SIZE (4096)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///< 获取缓存内存, 需要能申请到大于等于Flash一块大小
|
///< 获取缓存内存, 需要能申请到大于等于(Flash一块大小)
|
||||||
#ifndef HFLASH_MALLOC
|
#ifndef HFLASH_MALLOC
|
||||||
#ifdef USE_STD_MEM
|
#ifdef USE_STD_MEM
|
||||||
#define HFLASH_MALLOC(size) malloc(size)
|
#define HFLASH_MALLOC(size) malloc(size)
|
||||||
@ -45,9 +45,19 @@
|
|||||||
#define HFLASH_TIMER_ID 0
|
#define HFLASH_TIMER_ID 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///< 同步时间ms
|
///< 同步缓存页时间ms
|
||||||
#ifndef HFLASH_SYNC_TIME
|
#ifndef HFLASH_SYNC_CACHE_PAGE_TIME
|
||||||
#define HFLASH_SYNC_TIME 2000
|
#define HFLASH_SYNC_CACHE_PAGE_TIME 600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///< 同步页表信息时间ms
|
||||||
|
#ifndef HFLASH_SYNC_PAGE_INFO_TIME
|
||||||
|
#define HFLASH_SYNC_PAGE_INFO_TIME 800
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///< 同步备份页表信息时间ms
|
||||||
|
#ifndef HFLASH_SYNC_BACKUP_TIME
|
||||||
|
#define HFLASH_SYNC_BACKUP_TIME 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///< Flash地址类型
|
///< Flash地址类型
|
||||||
@ -63,6 +73,7 @@ typedef union HFlashPageInfo {
|
|||||||
uint32_t useSize : 24; ///< 使用大小
|
uint32_t useSize : 24; ///< 使用大小
|
||||||
uint16_t version; ///< 当前页数据的版本
|
uint16_t version; ///< 当前页数据的版本
|
||||||
uint32_t modifyCount; ///< 修改次数
|
uint32_t modifyCount; ///< 修改次数
|
||||||
|
uint8_t invalid : 1; ///< 无效标志
|
||||||
};
|
};
|
||||||
} HFlashPageInfo;
|
} HFlashPageInfo;
|
||||||
|
|
||||||
@ -71,6 +82,7 @@ typedef struct HFlashCacheInfo {
|
|||||||
uint32_t pos : 19; ///< 存储页表信息的位置
|
uint32_t pos : 19; ///< 存储页表信息的位置
|
||||||
uint32_t heat : 4; ///< 热度优先级
|
uint32_t heat : 4; ///< 热度优先级
|
||||||
uint32_t waitWrite : 1; ///< 延后写入, 一般适用于流式操作或者延后复写
|
uint32_t waitWrite : 1; ///< 延后写入, 一般适用于流式操作或者延后复写
|
||||||
|
uint32_t waitCrc : 1; ///< 延后CRC
|
||||||
} HFlashCacheInfo;
|
} HFlashCacheInfo;
|
||||||
|
|
||||||
|
|
||||||
@ -162,7 +174,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size);
|
|||||||
* @param size 写入数据大小
|
* @param size 写入数据大小
|
||||||
* @return 1: 写入成功 0: 写入失败
|
* @return 1: 写入成功 0: 写入失败
|
||||||
*/
|
*/
|
||||||
uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
uint8_t HFlashWrite(HFlashAddr_t addr, const void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashWriteOffset 写入从原始地址偏移后的地方写入数据, 如果偏移后的写入大小超过原未使用, 超出部分会自动写入0填充
|
* @brief HFlashWriteOffset 写入从原始地址偏移后的地方写入数据, 如果偏移后的写入大小超过原未使用, 超出部分会自动写入0填充
|
||||||
@ -172,7 +184,17 @@ uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
|||||||
* @param size 写入数据大小
|
* @param size 写入数据大小
|
||||||
* @return 1: 写入成功 0: 写入失败
|
* @return 1: 写入成功 0: 写入失败
|
||||||
*/
|
*/
|
||||||
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size);
|
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HFlashWriteRawOffset 写入原始地址偏移后的位置写入Flash数据, 超出部分不自动填充, 仅提供给一些库使用, 正常情况请勿使用
|
||||||
|
* @param addr 需要注册的地址
|
||||||
|
* @param offset 地址偏移
|
||||||
|
* @param data 写入数据
|
||||||
|
* @param size 写入数据大小
|
||||||
|
* @return 1: 写入成功 0: 写入失败
|
||||||
|
*/
|
||||||
|
uint8_t HFlashWriteRawOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashStreamBegin 开始流式写入, 重置使用长度
|
* @brief HFlashStreamBegin 开始流式写入, 重置使用长度
|
||||||
@ -187,7 +209,7 @@ void HFlashStreamBegin(HFlashAddr_t addr);
|
|||||||
* @param size 写入数据大小
|
* @param size 写入数据大小
|
||||||
* @return 1: 写入成功 0: 写入失败
|
* @return 1: 写入成功 0: 写入失败
|
||||||
*/
|
*/
|
||||||
uint8_t HFlashStreamWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
uint8_t HFlashStreamWrite(HFlashAddr_t addr, const void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashStreamEnd 结束流式写入, 计算CRC
|
* @brief HFlashStreamEnd 结束流式写入, 计算CRC
|
||||||
@ -202,7 +224,7 @@ void HFlashStreamEnd(HFlashAddr_t addr);
|
|||||||
* @param size 写入数据大小
|
* @param size 写入数据大小
|
||||||
* @return 1: 写入成功 0: 写入失败
|
* @return 1: 写入成功 0: 写入失败
|
||||||
*/
|
*/
|
||||||
uint8_t HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size);
|
uint8_t HFlashRawWrite(HFlashAddr_t addr, const void *data, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashRead 读取Flash数据
|
* @brief HFlashRead 读取Flash数据
|
||||||
@ -272,10 +294,22 @@ uint32_t HFlashGetUseSize(HFlashAddr_t addr);
|
|||||||
uint32_t HFlashGetSize(HFlashAddr_t addr);
|
uint32_t HFlashGetSize(HFlashAddr_t addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief HFlashGetCrc32 获取Flash数据的CRC32值
|
* @brief HFlashGetCrc32 获取页表记录的CRC32值
|
||||||
* @param addr 需要注册的地址
|
* @param addr 需要注册的地址
|
||||||
* @return CRC32
|
* @return CRC32
|
||||||
*/
|
*/
|
||||||
uint32_t HFlashGetCrc32(HFlashAddr_t addr);
|
uint32_t HFlashGetCrc32(HFlashAddr_t addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HFlashCalcCrc32 计算Flash数据的CRC32值
|
||||||
|
* @param addr 需要注册的地址
|
||||||
|
* @return CRC32
|
||||||
|
*/
|
||||||
|
uint32_t HFlashCalcCrc32(HFlashAddr_t addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HFlashSync 执行同步写入Flash数据, 在重启前需要执行
|
||||||
|
*/
|
||||||
|
void HFlashSync();
|
||||||
|
|
||||||
#endif // __H_FLASH_SERVER_H__
|
#endif // __H_FLASH_SERVER_H__
|
||||||
|
|||||||
30
src/HDLog.c
30
src/HDLog.c
@ -55,11 +55,24 @@ static HShellMatch sLogMatch[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///< 日志级别
|
||||||
static HBIT_DEFINE(sLogItem, kLogLevelMax);
|
static HBIT_DEFINE(sLogItem, kLogLevelMax);
|
||||||
|
|
||||||
|
///< 获取运行时间回调
|
||||||
static uint32_t (*sGetTime)() = NULL;
|
static uint32_t (*sGetTime)() = NULL;
|
||||||
|
|
||||||
|
///< 日志操作回调
|
||||||
|
static void (*sOperateCall)(const char *format, va_list args) = NULL;
|
||||||
|
|
||||||
|
///< 获取当前任务回调
|
||||||
static HDLogGetTaskType_t sGetCurrTask = NULL;
|
static HDLogGetTaskType_t sGetCurrTask = NULL;
|
||||||
|
|
||||||
|
///< 获取当前任务栈回调
|
||||||
static HDLogGetStackSizeType_t sGetCurrStackSize = NULL;
|
static HDLogGetStackSizeType_t sGetCurrStackSize = NULL;
|
||||||
|
|
||||||
|
///< 获取Flash配置回调
|
||||||
static HDLogFlashOpt_t sFlashCall = NULL;
|
static HDLogFlashOpt_t sFlashCall = NULL;
|
||||||
|
|
||||||
#if USE_SYS_CHECK_HEAP
|
#if USE_SYS_CHECK_HEAP
|
||||||
static HDLogGetStackSizeType_t sGetCurrHeapSize = NULL;
|
static HDLogGetStackSizeType_t sGetCurrHeapSize = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -252,6 +265,11 @@ void HDLogInit(uint32_t (*getTime)())
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HDLogSetOptCall(void (*call)(const char *format, va_list args))
|
||||||
|
{
|
||||||
|
sOperateCall = call;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t HDLogGetTime()
|
uint32_t HDLogGetTime()
|
||||||
{
|
{
|
||||||
if (sGetTime)
|
if (sGetTime)
|
||||||
@ -351,6 +369,18 @@ void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *func
|
|||||||
LOG_UNLOCK();
|
LOG_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HDLogOptOut(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
if (sOperateCall)
|
||||||
|
{
|
||||||
|
sOperateCall(format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
static void HDLogFpgaError(const uint8_t *data, int len, uint8_t isWrite, uint8_t checkFpga)
|
static void HDLogFpgaError(const uint8_t *data, int len, uint8_t isWrite, uint8_t checkFpga)
|
||||||
{
|
{
|
||||||
if (checkFpga == 0)
|
if (checkFpga == 0)
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
#include "HDLog.h"
|
#include "HDLog.h"
|
||||||
#include "HVector.h"
|
#include "HVector.h"
|
||||||
#include "HTimer.h"
|
#include "HTimer.h"
|
||||||
|
#include "HShellLex.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef USE_STD_MEM
|
#ifndef USE_STD_MEM
|
||||||
#include "HDSendBuffer.h"
|
#include "HDSendBuffer.h"
|
||||||
@ -37,7 +39,7 @@ uint32_t HSCrc32Get()
|
|||||||
#ifdef USE_STD_MEM
|
#ifdef USE_STD_MEM
|
||||||
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__);
|
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__);
|
||||||
#else
|
#else
|
||||||
#define FATAL_ERROR(format, ...) LogE(format, ##__VA_ARGS__); while(1);
|
#define FATAL_ERROR(format, ...) while (1) { LogE(format, ##__VA_ARGS__); HShellRun(); };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 最大热度
|
// 最大热度
|
||||||
@ -45,6 +47,24 @@ uint32_t HSCrc32Get()
|
|||||||
|
|
||||||
// 检查是不是4对齐
|
// 检查是不是4对齐
|
||||||
#define IS_NOT_4(size) ((size & (4 - 1)) != 0)
|
#define IS_NOT_4(size) ((size & (4 - 1)) != 0)
|
||||||
|
#define IS_NOT_4K(size) ((size & (HFLASH_BLOCK_SIZE - 1)) != 0)
|
||||||
|
|
||||||
|
enum eShell
|
||||||
|
{
|
||||||
|
kShellPageInfo, ///< 查看页表信息
|
||||||
|
kShellDelUseDataPage, ///< 删除页表使用数据
|
||||||
|
kShellDelPage, ///< 删除页
|
||||||
|
kShellResetPage, ///< 重置页
|
||||||
|
kShellMax,
|
||||||
|
};
|
||||||
|
|
||||||
|
static HShellMatch sShellMatch[] = {
|
||||||
|
HSHELL_MATCH_ITEM(kShellPageInfo, "pageInfo"),
|
||||||
|
HSHELL_MATCH_ITEM(kShellDelUseDataPage, "pageDelUseData"),
|
||||||
|
HSHELL_MATCH_ITEM(kShellDelPage, "pageDel"),
|
||||||
|
HSHELL_MATCH_ITEM(kShellResetPage, "pageReset"),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
union PageInfo {
|
union PageInfo {
|
||||||
uint8_t reverse[32]; ///< 每页的信息占用32字节
|
uint8_t reverse[32]; ///< 每页的信息占用32字节
|
||||||
@ -52,7 +72,6 @@ union PageInfo {
|
|||||||
uint32_t crc32; ///< 页表内容的CRC32校验值
|
uint32_t crc32; ///< 页表内容的CRC32校验值
|
||||||
uint32_t pageNum : 19; ///< 可用页数量
|
uint32_t pageNum : 19; ///< 可用页数量
|
||||||
uint32_t useNum : 19; ///< 已使用页数量
|
uint32_t useNum : 19; ///< 已使用页数量
|
||||||
uint32_t needBackupPage : 1; ///< 是否需要备份页表
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,12 +96,20 @@ static union PageInfo sPageInfo;
|
|||||||
// 备份定时器
|
// 备份定时器
|
||||||
static HTimer_t sBackupTimer = HTIMER_INVALID;
|
static HTimer_t sBackupTimer = HTIMER_INVALID;
|
||||||
|
|
||||||
// 需要备份的保护区地址页偏移
|
// 同步页定时器
|
||||||
|
static HTimer_t sSyncPageTimer = HTIMER_INVALID;
|
||||||
|
|
||||||
|
// 同步定时器
|
||||||
|
static HTimer_t sSyncCacheTimer = HTIMER_INVALID;
|
||||||
|
|
||||||
|
// 存储需要备份的保护区地址页偏移
|
||||||
static HVECTOR_DEFINE32(sNeedBackupOffset, 10);
|
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 void StartSyncBackupTimer();
|
||||||
|
static HFlashCacheInfo *FindCache(HFlashAddr_t addr);
|
||||||
|
static void WriteCachePage(HFlashCacheInfo *info);
|
||||||
|
static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size);
|
||||||
|
|
||||||
///< 检查地址是否在双备份保护区内
|
///< 检查地址是否在双备份保护区内
|
||||||
static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size)
|
static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size)
|
||||||
@ -105,8 +132,12 @@ static uint8_t IsProtect(HFlashAddr_t addr, uint32_t size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t ReadFlash(HFlashAddr_t addr, void *data, uint32_t size)
|
static uint8_t ReadFlashCall(HFlashAddr_t addr, void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
|
if (size == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (sInfo.read == NULL) {
|
if (sInfo.read == NULL) {
|
||||||
FATAL_ERROR("read is null");
|
FATAL_ERROR("read is null");
|
||||||
return 0;
|
return 0;
|
||||||
@ -116,7 +147,7 @@ static uint8_t ReadFlash(HFlashAddr_t addr, void *data, uint32_t size)
|
|||||||
return sInfo.read(addr, dataPtr, size);
|
return sInfo.read(addr, dataPtr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t EraseFlash(HFlashAddr_t addr)
|
static uint8_t EraseFlashCall(HFlashAddr_t addr)
|
||||||
{
|
{
|
||||||
if (sInfo.erase == NULL) {
|
if (sInfo.erase == NULL) {
|
||||||
FATAL_ERROR("erase is null");
|
FATAL_ERROR("erase is null");
|
||||||
@ -126,6 +157,21 @@ static uint8_t EraseFlash(HFlashAddr_t addr)
|
|||||||
return sInfo.erase(addr);
|
return sInfo.erase(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t WriteFlashCall(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||||
|
{
|
||||||
|
if (size == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sInfo.write == NULL) {
|
||||||
|
FATAL_ERROR("write is null");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *dataPtr = (uint8_t *)data;
|
||||||
|
return sInfo.write(addr, dataPtr, size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 写入数据到Flash
|
* @brief 写入数据到Flash
|
||||||
* @param addr 写入的Flash地址
|
* @param addr 写入的Flash地址
|
||||||
@ -134,13 +180,8 @@ static uint8_t EraseFlash(HFlashAddr_t addr)
|
|||||||
* @param call 拷贝回调, dest缓存, src已经调整好位置的指针, buffSize需要拷贝的数据大小, userData用户数据
|
* @param call 拷贝回调, dest缓存, src已经调整好位置的指针, buffSize需要拷贝的数据大小, userData用户数据
|
||||||
* @return 写入是否成功
|
* @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)
|
static uint8_t WriteData(HFlashAddr_t addr, const void *data, uint32_t size, void(*call)(void *dest, const void *src, uint16_t buffSize, void *userData), void *userData)
|
||||||
{
|
{
|
||||||
if (sInfo.write == NULL) {
|
|
||||||
FATAL_ERROR("write is null");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *dataPtr = (uint8_t *)data;
|
uint8_t *dataPtr = (uint8_t *)data;
|
||||||
uint32_t adjustAddr = addr & ~(HFLASH_BLOCK_SIZE - 1);
|
uint32_t adjustAddr = addr & ~(HFLASH_BLOCK_SIZE - 1);
|
||||||
const uint16_t offset = addr - adjustAddr;
|
const uint16_t offset = addr - adjustAddr;
|
||||||
@ -153,18 +194,18 @@ static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*cal
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 先写入首个未对齐的块
|
// 先写入首个未对齐的块
|
||||||
if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
if (ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
||||||
LogE("addr[0x%08x], read faild", adjustAddr);
|
LogE("addr[0x%08x], read faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EraseFlash(adjustAddr) == 0) {
|
if (EraseFlashCall(adjustAddr) == 0) {
|
||||||
LogE("addr[0x%08x], erase faild", adjustAddr);
|
LogE("addr[0x%08x], erase faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
|
|
||||||
call(buff + offset, dataPtr, remain, userData);
|
call(buff + offset, dataPtr, remain, userData);
|
||||||
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
||||||
LogE("addr[0x%08x], write faild", adjustAddr);
|
LogE("addr[0x%08x], write faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
@ -174,13 +215,13 @@ static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*cal
|
|||||||
adjustAddr += HFLASH_BLOCK_SIZE;
|
adjustAddr += HFLASH_BLOCK_SIZE;
|
||||||
dataPtr += remain;
|
dataPtr += remain;
|
||||||
for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE, dataPtr += HFLASH_BLOCK_SIZE) {
|
for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE, dataPtr += HFLASH_BLOCK_SIZE) {
|
||||||
if (EraseFlash(adjustAddr) == 0) {
|
if (EraseFlashCall(adjustAddr) == 0) {
|
||||||
LogE("addr[0x%08x], erase faild", adjustAddr);
|
LogE("addr[0x%08x], erase faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
|
|
||||||
call(buff, dataPtr, HFLASH_BLOCK_SIZE, userData);
|
call(buff, dataPtr, HFLASH_BLOCK_SIZE, userData);
|
||||||
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
||||||
LogE("addr[0x%08x], write faild", adjustAddr);
|
LogE("addr[0x%08x], write faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
@ -188,18 +229,18 @@ static uint8_t WriteData(HFlashAddr_t addr, void *data, uint32_t size, void(*cal
|
|||||||
|
|
||||||
// 操作最后一个未对齐的块
|
// 操作最后一个未对齐的块
|
||||||
if (size) {
|
if (size) {
|
||||||
if (ReadFlash(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
if (ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
||||||
LogE("addr[0x%08x], read faild", adjustAddr);
|
LogE("addr[0x%08x], read faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EraseFlash(adjustAddr) == 0) {
|
if (EraseFlashCall(adjustAddr) == 0) {
|
||||||
LogE("addr[0x%08x], erase faild", adjustAddr);
|
LogE("addr[0x%08x], erase faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
|
|
||||||
call(buff, dataPtr, size, userData);
|
call(buff, dataPtr, size, userData);
|
||||||
if (sInfo.write(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
if (WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0) {
|
||||||
LogE("addr[0x%08x], write faild", adjustAddr);
|
LogE("addr[0x%08x], write faild", adjustAddr);
|
||||||
goto _flashError;
|
goto _flashError;
|
||||||
}
|
}
|
||||||
@ -218,7 +259,7 @@ static void _WriteFlashHelper(void *dest, const void *src, uint16_t buffSize, vo
|
|||||||
memcpy(dest, src, buffSize);
|
memcpy(dest, src, buffSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t WriteFlash(HFlashAddr_t addr, void *data, uint32_t size)
|
static uint8_t WriteFlash(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
return WriteData(addr, data, size, _WriteFlashHelper, NULL);
|
return WriteData(addr, data, size, _WriteFlashHelper, NULL);
|
||||||
}
|
}
|
||||||
@ -234,6 +275,21 @@ static uint8_t WriteFlashValue(uint32_t addr, uint32_t size, uint8_t value)
|
|||||||
return WriteData(addr, NULL, size, _WriteFalshValueHelper, &value);
|
return WriteData(addr, NULL, size, _WriteFalshValueHelper, &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t AdjustPageAddr(uint32_t addr)
|
||||||
|
{
|
||||||
|
return addr + sizeof(sPageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t AdjustPageAddrOffset(uint32_t addr, uint32_t offset)
|
||||||
|
{
|
||||||
|
return addr + sizeof(sPageInfo) + offset * sizeof(HFlashPageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t AdjustPageByte(uint32_t index)
|
||||||
|
{
|
||||||
|
return index * sizeof(HFlashPageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
static void SyncBackup()
|
static void SyncBackup()
|
||||||
{
|
{
|
||||||
LogD("Start sync Backup");
|
LogD("Start sync Backup");
|
||||||
@ -242,17 +298,12 @@ static void SyncBackup()
|
|||||||
sBackupTimer = HTIMER_INVALID;
|
sBackupTimer = HTIMER_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 需要备份的数据为空, 说明是二次调用, 上次已经同步了
|
|
||||||
if (HVectorEmpty(sNeedBackupOffset) && sPageInfo.needBackupPage == 0) {
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
if (RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE) == 0) {
|
if (RestoreBackup(addr, destAddr, HFLASH_BLOCK_SIZE) == 0) {
|
||||||
LogE("RestorePage faild, addr[0x%08x]", addr);
|
LogE("RestorePage faild, addr[0x%08x]", addr);
|
||||||
StartBackupTimer();
|
StartSyncBackupTimer();
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,18 +311,21 @@ static void SyncBackup()
|
|||||||
HVectorClear(sNeedBackupOffset);
|
HVectorClear(sNeedBackupOffset);
|
||||||
|
|
||||||
// 备份页表数据
|
// 备份页表数据
|
||||||
RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, sInfo.pageSize);
|
const uint32_t crcValue = GetFlashCrc32(AdjustPageAddr(sInfo.pageBackupAddr), AdjustPageByte(sPageInfo.useNum));
|
||||||
sPageInfo.needBackupPage = 0;
|
if (crcValue != sPageInfo.crc32) {
|
||||||
|
RestoreBackup(sInfo.pageAddr, sInfo.pageBackupAddr, AdjustPageByte(sPageInfo.useNum + 1));
|
||||||
|
}
|
||||||
|
LogD("Sync Backup End");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartBackupTimer()
|
static void StartSyncBackupTimer()
|
||||||
{
|
{
|
||||||
if (sBackupTimer != HTIMER_INVALID) {
|
if (sBackupTimer != HTIMER_INVALID) {
|
||||||
HTimerRemove(sBackupTimer);
|
HTimerRemove(sBackupTimer);
|
||||||
sBackupTimer = HTIMER_INVALID;
|
sBackupTimer = HTIMER_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
sBackupTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_TIME, SyncBackup, kHTimerOnce);
|
sBackupTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_BACKUP_TIME, SyncBackup, kHTimerOnce);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _AddBackupAddr(uint32_t addr)
|
static void _AddBackupAddr(uint32_t addr)
|
||||||
@ -295,7 +349,7 @@ static void _AddBackupAddr(uint32_t addr)
|
|||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
LogD("Add wait sync addr[0x%08x], size[%d]", addr, HVectorGetUseLen(sNeedBackupOffset));
|
LogD("Add wait sync addr[0x%08x], size[%d]", addr, HVectorGetUseLen(sNeedBackupOffset));
|
||||||
StartBackupTimer();
|
StartSyncBackupTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddBackupAddr(uint32_t addr, uint32_t size)
|
static void AddBackupAddr(uint32_t addr, uint32_t size)
|
||||||
@ -321,7 +375,6 @@ static void AddBackupAddr(uint32_t addr, uint32_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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) {
|
||||||
@ -337,7 +390,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 = FLASH_MIN(uint32_t, size - i, HFLASH_BLOCK_SIZE);
|
||||||
if (ReadFlash(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;
|
||||||
}
|
}
|
||||||
@ -349,52 +402,78 @@ static uint32_t GetFlashCrc32(HFlashAddr_t addr, uint32_t size)
|
|||||||
return HSCrc32Get();
|
return HSCrc32Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 copySize)
|
||||||
{
|
{
|
||||||
const uint16_t mallocSize = 1024;
|
if (copySize == 0) {
|
||||||
uint8_t *buff = (uint8_t *)HFLASH_MALLOC(mallocSize);
|
LogD("addr[0x%08x], write size[%d] is 0", srcAddr, copySize);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, size);
|
LogE("addr[0x%08x], write size[%d] malloc faild", srcAddr, copySize);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t result = 0;
|
uint8_t result = 0;
|
||||||
uint32_t i = 0;
|
uint32_t adjustAddr = dstAddr & ~(HFLASH_BLOCK_SIZE - 1);
|
||||||
uint32_t remain = 0;
|
uint32_t size = copySize;
|
||||||
for (; i < size; i += mallocSize) {
|
uint32_t srcOffset = 0;
|
||||||
remain = FLASH_MIN(uint32_t, size - i, mallocSize);
|
// 如果地址不是对齐页的, 先处理残余数据到对齐页
|
||||||
result = result || ReadFlash(srcAddr + i, buff, remain) == 0;
|
if (adjustAddr != dstAddr) {
|
||||||
result = result || WriteFlash(dstAddr + i, buff, remain) == 0;
|
const uint16_t offset = dstAddr - adjustAddr;
|
||||||
|
const uint32_t remain = offset + size > HFLASH_BLOCK_SIZE ? HFLASH_BLOCK_SIZE - offset : size;
|
||||||
|
|
||||||
|
// 先读取到对齐页, 然后将未对齐的数据重写
|
||||||
|
result = ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
|
||||||
|
result = result || ReadFlashCall(srcAddr + srcOffset, buff + offset, remain) == 0;
|
||||||
|
result = result || EraseFlashCall(adjustAddr) == 0;
|
||||||
|
result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
|
||||||
if (result) {
|
if (result) {
|
||||||
LogE("read addr[0x%08x], write addr[0x%08x], write size[%d] faild", srcAddr + i, dstAddr + i, remain);
|
|
||||||
result = 0;
|
result = 0;
|
||||||
|
LogE("addr[0x%08x], write size[%d] faild", srcAddr, size);
|
||||||
goto _FlashError;
|
goto _FlashError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size -= remain;
|
||||||
|
adjustAddr += HFLASH_BLOCK_SIZE;
|
||||||
|
srcOffset += remain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 中间对齐页直接读原地址页, 擦写目标页
|
||||||
|
for (; size >= HFLASH_BLOCK_SIZE; adjustAddr += HFLASH_BLOCK_SIZE, size -= HFLASH_BLOCK_SIZE, srcOffset += HFLASH_BLOCK_SIZE) {
|
||||||
|
result = result || ReadFlashCall(srcAddr + srcOffset, buff, HFLASH_BLOCK_SIZE) == 0;
|
||||||
|
result = result || EraseFlashCall(adjustAddr) == 0;
|
||||||
|
result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
|
||||||
|
if (result) {
|
||||||
|
result = 0;
|
||||||
|
LogE("addr[0x%08x], write size[%d] faild", srcAddr, size);
|
||||||
|
goto _FlashError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最后不对齐的数据
|
||||||
|
if (size) {
|
||||||
|
result = result || ReadFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
|
||||||
|
result = result || ReadFlashCall(srcAddr + srcOffset, buff, size) == 0;
|
||||||
|
result = result || EraseFlashCall(adjustAddr) == 0;
|
||||||
|
result = result || WriteFlashCall(adjustAddr, buff, HFLASH_BLOCK_SIZE) == 0;
|
||||||
|
if (result) {
|
||||||
|
result = 0;
|
||||||
|
LogE("addr[0x%08x], write size[%d] faild", srcAddr, size);
|
||||||
|
goto _FlashError;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 1;
|
result = 1;
|
||||||
_FlashError:
|
_FlashError:
|
||||||
HFLASH_FREE(buff);
|
HFLASH_FREE(buff);
|
||||||
LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d], result[%d]", srcAddr, dstAddr, size, result);
|
LogD("Restore srcAddr[0x%08x], dstAddr[0x%08x], size[%d][%d], result[%d]", srcAddr, dstAddr, size, copySize, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t AdjustPageAddr(uint32_t addr)
|
|
||||||
{
|
|
||||||
return addr + sizeof(sPageInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t AdjustPageAddrOffset(uint32_t addr, uint32_t offset)
|
|
||||||
{
|
|
||||||
return addr + sizeof(sPageInfo) + offset * sizeof(HFlashPageInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t AdjustPageByte(uint32_t index)
|
|
||||||
{
|
|
||||||
return index * sizeof(HFlashPageInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
///< 恢复指定页表
|
///< 恢复指定页表
|
||||||
static uint8_t RestorePage(uint32_t index)
|
static uint8_t RestorePage(uint32_t index)
|
||||||
{
|
{
|
||||||
@ -408,12 +487,32 @@ static uint8_t RestorePage(uint32_t index)
|
|||||||
return RestoreBackup(srcAddr, dstAddr, sizeof(HFlashPageInfo));
|
return RestoreBackup(srcAddr, dstAddr, sizeof(HFlashPageInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdatePageInfo()
|
static void SyncPageInfo()
|
||||||
{
|
{
|
||||||
sPageInfo.crc32 = GetFlashCrc32(AdjustPageAddr(sInfo.pageAddr), AdjustPageByte(sPageInfo.useNum));
|
if (sSyncPageTimer != HTIMER_INVALID) {
|
||||||
WriteFlash(sInfo.pageAddr, &sPageInfo, sizeof(sPageInfo));
|
HTimerRemove(sSyncPageTimer);
|
||||||
|
sSyncPageTimer = HTIMER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
sPageInfo.needBackupPage = 1;
|
const uint32_t crcValue = GetFlashCrc32(AdjustPageAddr(sInfo.pageAddr), AdjustPageByte(sPageInfo.useNum));
|
||||||
|
if (crcValue == sPageInfo.crc32) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sPageInfo.crc32 = crcValue;;
|
||||||
|
WriteFlash(sInfo.pageAddr, &sPageInfo, sizeof(sPageInfo));
|
||||||
|
StartSyncBackupTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StartSyncPageInfo()
|
||||||
|
{
|
||||||
|
if (sSyncPageTimer != HTIMER_INVALID) {
|
||||||
|
HTimerRemove(sSyncPageTimer);
|
||||||
|
sSyncPageTimer = HTIMER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
sSyncPageTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_PAGE_INFO_TIME, SyncPageInfo, kHTimerOnce);
|
||||||
|
StartSyncBackupTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReadPage(uint32_t index, HFlashPageInfo *info)
|
static void ReadPage(uint32_t index, HFlashPageInfo *info)
|
||||||
@ -424,7 +523,7 @@ static void ReadPage(uint32_t index, HFlashPageInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const HFlashAddr_t addr = AdjustPageAddrOffset(sInfo.pageAddr, index);
|
const HFlashAddr_t addr = AdjustPageAddrOffset(sInfo.pageAddr, index);
|
||||||
ReadFlash(addr, info, sizeof(HFlashPageInfo));
|
ReadFlashCall(addr, info, sizeof(HFlashPageInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WritePage(uint32_t index, HFlashPageInfo *info)
|
static void WritePage(uint32_t index, HFlashPageInfo *info)
|
||||||
@ -436,15 +535,50 @@ static void WritePage(uint32_t index, HFlashPageInfo *info)
|
|||||||
|
|
||||||
const HFlashAddr_t addr = AdjustPageAddrOffset(sInfo.pageAddr, index);
|
const HFlashAddr_t addr = AdjustPageAddrOffset(sInfo.pageAddr, index);
|
||||||
WriteFlash(addr, info, sizeof(HFlashPageInfo));
|
WriteFlash(addr, info, sizeof(HFlashPageInfo));
|
||||||
|
StartSyncPageInfo();
|
||||||
|
}
|
||||||
|
|
||||||
UpdatePageInfo();
|
|
||||||
|
static void SyncCachePage()
|
||||||
|
{
|
||||||
|
if (sSyncCacheTimer != HTIMER_INVALID) {
|
||||||
|
HTimerRemove(sSyncCacheTimer);
|
||||||
|
sSyncCacheTimer = HTIMER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
|
||||||
|
// 更新Crc32
|
||||||
|
if (sInfo.pageCache[i].waitCrc) {
|
||||||
|
sInfo.pageCache[i].waitCrc = 0;
|
||||||
|
sInfo.pageCache[i].info.crc32 = GetFlashCrc32(sInfo.pageCache[i].info.addr, sInfo.pageCache[i].info.useSize);
|
||||||
|
sInfo.pageCache[i].waitWrite = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入页表
|
||||||
|
if (sInfo.pageCache[i].waitWrite) {
|
||||||
|
WritePage(sInfo.pageCache[i].pos, &sInfo.pageCache[i].info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StartSyncPageInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StartSyncCachePage()
|
||||||
|
{
|
||||||
|
if (sSyncCacheTimer != HTIMER_INVALID) {
|
||||||
|
HTimerRemove(sSyncCacheTimer);
|
||||||
|
sSyncCacheTimer = HTIMER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
sSyncCacheTimer = HTimerAdd(HFLASH_TIMER_ID, HFLASH_SYNC_CACHE_PAGE_TIME, SyncCachePage, kHTimerOnce);
|
||||||
|
StartSyncPageInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteCachePage(HFlashCacheInfo *info)
|
static void WriteCachePage(HFlashCacheInfo *info)
|
||||||
{
|
{
|
||||||
++info->info.modifyCount;
|
++info->info.modifyCount;
|
||||||
info->waitWrite = 0;
|
info->waitWrite = 1;
|
||||||
WritePage(info->pos, &info->info);
|
StartSyncCachePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 检查是否重叠, 重叠返回1, 非重叠返回0
|
/// 检查是否重叠, 重叠返回1, 非重叠返回0
|
||||||
@ -496,7 +630,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 = FLASH_MIN(uint32_t, sPageInfo.useNum - i, pageNum);
|
||||||
if (ReadFlash(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;
|
||||||
}
|
}
|
||||||
@ -521,10 +655,25 @@ static uint8_t ScanPage(uint8_t (*call)(uint32_t index, HFlashPageInfo *info, vo
|
|||||||
///< 检查是否重叠, 重叠返回1
|
///< 检查是否重叠, 重叠返回1
|
||||||
static uint8_t _CreatePageInfoHelper(uint32_t index, HFlashPageInfo *info, void *userData)
|
static uint8_t _CreatePageInfoHelper(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||||
{
|
{
|
||||||
|
if (info->invalid) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
HFlashPageInfo *cache = (HFlashPageInfo *)userData;
|
HFlashPageInfo *cache = (HFlashPageInfo *)userData;
|
||||||
return IsOverLap(info->addr, info->size, cache->addr, cache->size);
|
return IsOverLap(info->addr, info->size, cache->addr, cache->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t ScanAvailablePage(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||||
|
{
|
||||||
|
uint32_t *result = (uint32_t *)userData;
|
||||||
|
if (info->invalid == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = index;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t CreatePageInfo(HFlashAddr_t addr, uint32_t size)
|
static uint8_t CreatePageInfo(HFlashAddr_t addr, uint32_t size)
|
||||||
{
|
{
|
||||||
HFlashPageInfo info;
|
HFlashPageInfo info;
|
||||||
@ -537,13 +686,21 @@ static uint8_t CreatePageInfo(HFlashAddr_t addr, uint32_t size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t index = 0;
|
||||||
|
if (ScanPage(ScanAvailablePage, &index)) {
|
||||||
|
// 如果找到空闲页, 覆盖之前的页
|
||||||
|
info.crc32 = GetFlashCrc32(info.addr, info.useSize);
|
||||||
|
WritePage(index, &info);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (sPageInfo.useNum >= sPageInfo.pageNum) {
|
if (sPageInfo.useNum >= sPageInfo.pageNum) {
|
||||||
FATAL_ERROR("page table is full");
|
FATAL_ERROR("page table is full");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 写入新页表
|
// 写入新页表
|
||||||
const uint32_t index = sPageInfo.useNum++;
|
index = sPageInfo.useNum++;
|
||||||
info.crc32 = GetFlashCrc32(info.addr, info.useSize);
|
info.crc32 = GetFlashCrc32(info.addr, info.useSize);
|
||||||
WritePage(index, &info);
|
WritePage(index, &info);
|
||||||
|
|
||||||
@ -552,6 +709,10 @@ static uint8_t CreatePageInfo(HFlashAddr_t addr, uint32_t size)
|
|||||||
|
|
||||||
static uint8_t _FindCacheHelper(uint32_t index, HFlashPageInfo *info, void *userData)
|
static uint8_t _FindCacheHelper(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||||
{
|
{
|
||||||
|
if (info->invalid) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
HFlashCacheInfo *cache = (HFlashCacheInfo *)userData;
|
HFlashCacheInfo *cache = (HFlashCacheInfo *)userData;
|
||||||
if (info->addr != cache->info.addr) {
|
if (info->addr != cache->info.addr) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -611,9 +772,16 @@ static HFlashCacheInfo *FindCache(HFlashAddr_t addr)
|
|||||||
++sInfo.pageCacheUseNum;
|
++sInfo.pageCacheUseNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新Crc32
|
||||||
|
if (sInfo.pageCache[index].waitCrc) {
|
||||||
|
sInfo.pageCache[index].info.crc32 = GetFlashCrc32(sInfo.pageCache[index].info.addr, sInfo.pageCache[index].info.useSize);
|
||||||
|
sInfo.pageCache[index].waitWrite = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// 如果是延迟写入的, 需要先写入再替换
|
// 如果是延迟写入的, 需要先写入再替换
|
||||||
if (sInfo.pageCache[index].waitWrite) {
|
if (sInfo.pageCache[index].waitWrite) {
|
||||||
WriteCachePage(&sInfo.pageCache[index]);
|
WritePage(sInfo.pageCache[index].pos, &sInfo.pageCache[index].info);
|
||||||
|
sInfo.pageCache[index].waitWrite = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&sInfo.pageCache[index], &cache, sizeof(HFlashCacheInfo));
|
memcpy(&sInfo.pageCache[index], &cache, sizeof(HFlashCacheInfo));
|
||||||
@ -640,12 +808,20 @@ void HFlashSetPageCache(HFlashCacheInfo *pageInfo, uint16_t size)
|
|||||||
|
|
||||||
void HFlashSetPageAddr(HFlashAddr_t addr, uint32_t size)
|
void HFlashSetPageAddr(HFlashAddr_t addr, uint32_t size)
|
||||||
{
|
{
|
||||||
|
if (IS_NOT_4K(addr) || IS_NOT_4K(size)) {
|
||||||
|
FATAL_ERROR("not align page size[0x%08x], size[%x]", addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
sInfo.pageAddr = addr;
|
sInfo.pageAddr = addr;
|
||||||
sInfo.pageSize = size;
|
sInfo.pageSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size)
|
void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size)
|
||||||
{
|
{
|
||||||
|
if (IS_NOT_4K(addr) || IS_NOT_4K(size)) {
|
||||||
|
FATAL_ERROR("not align page size[0x%08x], size[%x]", addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
if (sInfo.pageSize != size) {
|
if (sInfo.pageSize != size) {
|
||||||
FATAL_ERROR("page size not match[%d][%d]", sInfo.pageSize, size);
|
FATAL_ERROR("page size not match[%d][%d]", sInfo.pageSize, size);
|
||||||
return ;
|
return ;
|
||||||
@ -657,12 +833,20 @@ void HFlashSetPageBackupAddr(HFlashAddr_t addr, uint32_t size)
|
|||||||
|
|
||||||
void HFlashSetProtectAddr(HFlashAddr_t addr, uint32_t size)
|
void HFlashSetProtectAddr(HFlashAddr_t addr, uint32_t size)
|
||||||
{
|
{
|
||||||
|
if (IS_NOT_4K(addr) || IS_NOT_4K(size)) {
|
||||||
|
FATAL_ERROR("not align page size[0x%08x], size[%x]", addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
sInfo.protectAddr = addr;
|
sInfo.protectAddr = addr;
|
||||||
sInfo.protectSize = size;
|
sInfo.protectSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size)
|
void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size)
|
||||||
{
|
{
|
||||||
|
if (IS_NOT_4K(addr) || IS_NOT_4K(size)) {
|
||||||
|
FATAL_ERROR("not align page size[0x%08x], size[%x]", addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
if (sInfo.protectSize != size) {
|
if (sInfo.protectSize != size) {
|
||||||
FATAL_ERROR("protect size not match[%d][%d]", sInfo.protectSize, size);
|
FATAL_ERROR("protect size not match[%d][%d]", sInfo.protectSize, size);
|
||||||
return ;
|
return ;
|
||||||
@ -672,8 +856,73 @@ void HFlashSetProtectBackupAddr(HFlashAddr_t addr, uint32_t size)
|
|||||||
sInfo.protectSize = size;
|
sInfo.protectSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t _Print(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||||
|
{
|
||||||
|
uint32_t *arg1 = (uint32_t *)userData;
|
||||||
|
if (*arg1 == -1) {
|
||||||
|
HSHELL_PRINTFL("page[%d], invalid[%d], addr[0x%08x][%u], useSize[0x%x][%d], size[0x%x][%d], modifyCount[%d], crc32[0x%x], version[%d]", index, info->invalid, info->addr, info->addr, info->useSize, info->useSize, info->size, info->size, info->modifyCount, info->crc32, info->version);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == *arg1) {
|
||||||
|
HSHELL_PRINTFL("page[%d], invalid[%d], addr[0x%08x][%u], useSize[0x%x][%d], size[0x%x][%d], modifyCount[%d], crc32[0x%x], version[%d]", index, info->invalid, info->addr, info->addr, info->useSize, info->useSize, info->size, info->size, info->modifyCount, info->crc32, info->version);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Shell(HSHELL_FUNC_ARGS)
|
||||||
|
{
|
||||||
|
uint32_t arg1 = 0;
|
||||||
|
if (HSHellToUint32(tokens, tokensLen, 1, &arg1) == 0) {
|
||||||
|
arg1 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case kShellPageInfo: {
|
||||||
|
ScanPage(_Print, &arg1);
|
||||||
|
for (uint16_t i = 0; i < sInfo.pageCacheUseNum; ++i) {
|
||||||
|
HSHELL_PRINTFL("Cache index[%d], addr[0x%08x], useSize[0x%x][%d], size[0x%x][%d], modifyCount[%d], crc32[0x%x], version[%d]", i, sInfo.pageCache[i].info.addr, sInfo.pageCache[i].info.useSize, sInfo.pageCache[i].info.useSize, sInfo.pageCache[i].info.size, sInfo.pageCache[i].info.size, sInfo.pageCache[i].info.modifyCount, sInfo.pageCache[i].info.crc32, sInfo.pageCache[i].info.version);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case kShellDelUseDataPage: {
|
||||||
|
HFlashCacheInfo *cache = FindCache(arg1);
|
||||||
|
if (cache == NULL) {
|
||||||
|
HSHELL_PRINTFL("addr[0x%08x] not register", arg1);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->info.useSize = 0;
|
||||||
|
WriteCachePage(cache);
|
||||||
|
} break;
|
||||||
|
case kShellDelPage: {
|
||||||
|
HFlashCacheInfo *cache = FindCache(arg1);
|
||||||
|
if (cache == NULL) {
|
||||||
|
HSHELL_PRINTFL("addr[0x%08x] not register", arg1);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->info.invalid = 1;
|
||||||
|
WriteCachePage(cache);
|
||||||
|
} break;
|
||||||
|
case kShellResetPage: {
|
||||||
|
if (arg1 >= sPageInfo.pageNum) {
|
||||||
|
HSHELL_PRINTFL("index[%d] over max[%d]", arg1, sPageInfo.pageNum);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
sPageInfo.useNum = arg1;
|
||||||
|
SyncPageInfo();
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HFlashInitCheck()
|
void HFlashInitCheck()
|
||||||
{
|
{
|
||||||
|
HSHellRegister(sShellMatch, sizeof(sShellMatch) / sizeof(HShellMatch), Shell, 0);
|
||||||
if (sInfo.pageCache == NULL || sInfo.pageCacheSize == 0) {
|
if (sInfo.pageCache == NULL || sInfo.pageCacheSize == 0) {
|
||||||
FATAL_ERROR("pageCache is null");
|
FATAL_ERROR("pageCache is null");
|
||||||
return ;
|
return ;
|
||||||
@ -687,7 +936,7 @@ void HFlashInitCheck()
|
|||||||
|
|
||||||
const uint32_t num = sInfo.pageSize / sizeof(HFlashPageInfo);
|
const uint32_t num = sInfo.pageSize / sizeof(HFlashPageInfo);
|
||||||
do {
|
do {
|
||||||
if (ReadFlash(sInfo.pageAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
|
if (ReadFlashCall(sInfo.pageAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
|
||||||
LogE("Read page table[0x%08x] faild", sInfo.pageAddr);
|
LogE("Read page table[0x%08x] faild", sInfo.pageAddr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -705,7 +954,7 @@ void HFlashInitCheck()
|
|||||||
|
|
||||||
LogD("page table is invalid, check backup table");
|
LogD("page table is invalid, check backup table");
|
||||||
// 备份校验
|
// 备份校验
|
||||||
if (ReadFlash(sInfo.pageBackupAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
|
if (ReadFlashCall(sInfo.pageBackupAddr, sPageInfo.reverse, sizeof(sPageInfo)) == 0) {
|
||||||
LogE("Read backup page table[0x%08x] faild", sInfo.pageBackupAddr);
|
LogE("Read backup page table[0x%08x] faild", sInfo.pageBackupAddr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -720,8 +969,8 @@ void HFlashInitCheck()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 备份校验通过, 恢复备份数据
|
// 备份校验通过, 恢复全备份数据
|
||||||
RestoreBackup(sInfo.pageBackupAddr, sInfo.pageAddr, sPageInfo.useNum);
|
RestoreBackup(sInfo.pageBackupAddr, sInfo.pageAddr, sInfo.pageSize);
|
||||||
return ;
|
return ;
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
@ -732,6 +981,10 @@ void HFlashInitCheck()
|
|||||||
///< 检查是否重叠, 重叠返回1
|
///< 检查是否重叠, 重叠返回1
|
||||||
static uint8_t _CheckOverLap(uint32_t index, HFlashPageInfo *info, void *userData)
|
static uint8_t _CheckOverLap(uint32_t index, HFlashPageInfo *info, void *userData)
|
||||||
{
|
{
|
||||||
|
if (info->invalid) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
HFlashCacheInfo *cache = (HFlashCacheInfo *)userData;
|
HFlashCacheInfo *cache = (HFlashCacheInfo *)userData;
|
||||||
if (cache->pos == index) {
|
if (cache->pos == index) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -754,8 +1007,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
|||||||
LogE("Create addr[0x%08x] size[%d] faild", addr, size);
|
LogE("Create addr[0x%08x] size[%d] faild", addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
sPageInfo.needBackupPage = 1;
|
StartSyncBackupTimer();
|
||||||
StartBackupTimer();
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,6 +1029,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
|||||||
if (cache->info.useSize > size) {
|
if (cache->info.useSize > size) {
|
||||||
LogE("addr[0x%08x] useSize[%d] > size[%d]", addr, cache->info.useSize, size);
|
LogE("addr[0x%08x] useSize[%d] > size[%d]", addr, cache->info.useSize, size);
|
||||||
cache->info.useSize = 0;
|
cache->info.useSize = 0;
|
||||||
|
cache->waitWrite = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否在保护区域, 不是保护区域不需要检查crc校验
|
// 检查是否在保护区域, 不是保护区域不需要检查crc校验
|
||||||
@ -803,12 +1056,22 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
|||||||
LogE("addr[0x%08x] size[%d] crc32 not match, restore faild", cache->info.addr, cache->info.size);
|
LogE("addr[0x%08x] size[%d] crc32 not match, restore faild", cache->info.addr, cache->info.size);
|
||||||
RestorePage(cache->pos);
|
RestorePage(cache->pos);
|
||||||
ReadPage(cache->pos, &cache->info);
|
ReadPage(cache->pos, &cache->info);
|
||||||
if (contentCrc == cache->info.crc32) {
|
do {
|
||||||
|
// 如果恢复页表数据后, 大小不一致, 说明用户在调整大小, 放弃数据, 不恢复
|
||||||
|
if (cache->info.size != size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复后数据校验不一致, 需要重置
|
||||||
|
if (contentCrc != cache->info.crc32) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
}
|
} while (0);
|
||||||
|
|
||||||
// 恢复后数据还是错误的, 需要将该页表数据重新初始化
|
// 恢复后数据还是错误的, 需要将该页表数据重新初始化
|
||||||
LogE("addr[0x%08x] size[%d] crc32 not match", cache->info.addr, cache->info.size);
|
LogE("addr[0x%08x] size[%d] newSize[%d] crc32 not match", cache->info.addr, cache->info.size, size);
|
||||||
memset(cache->info.reverse, 0, sizeof(cache->info));
|
memset(cache->info.reverse, 0, sizeof(cache->info));
|
||||||
cache->info.addr = addr;
|
cache->info.addr = addr;
|
||||||
cache->info.useSize = 0;
|
cache->info.useSize = 0;
|
||||||
@ -817,7 +1080,7 @@ void HFlashRegister(HFlashAddr_t addr, uint32_t size)
|
|||||||
WriteCachePage(cache);
|
WriteCachePage(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
uint8_t HFlashWrite(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
// 检查是否存在致命性错误, 使用的地址不在注册页表中
|
// 检查是否存在致命性错误, 使用的地址不在注册页表中
|
||||||
uint8_t result = 0;
|
uint8_t result = 0;
|
||||||
@ -833,14 +1096,14 @@ uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新使用长度
|
// 更新使用长度, 直接重写比较短的数据不要影响使用长度
|
||||||
if (cache->info.useSize < size) {
|
if (cache->info.useSize < size) {
|
||||||
cache->info.useSize = size;
|
cache->info.useSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新crc, 写入数据后再更新页表
|
// 更新crc, 写入数据后再更新页表
|
||||||
HSCrc32Reset();
|
HSCrc32Reset();
|
||||||
HSCrc32Update((uint8_t *)data, size);
|
HSCrc32Update((uint8_t *)data, cache->info.useSize);
|
||||||
cache->info.crc32 = HSCrc32Get();
|
cache->info.crc32 = HSCrc32Get();
|
||||||
|
|
||||||
result = WriteFlash(addr, data, size);
|
result = WriteFlash(addr, data, size);
|
||||||
@ -854,7 +1117,7 @@ uint8_t HFlashWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
static uint8_t WriteOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size, uint8_t needSetZero)
|
||||||
{
|
{
|
||||||
uint8_t result = 0;
|
uint8_t result = 0;
|
||||||
HFlashCacheInfo *cache = FindCache(addr);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
@ -872,15 +1135,15 @@ uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32
|
|||||||
|
|
||||||
// 更新使用长度, 将跨越的部分填充0
|
// 更新使用长度, 将跨越的部分填充0
|
||||||
if (cache->info.useSize < useSize) {
|
if (cache->info.useSize < useSize) {
|
||||||
if (cache->info.useSize < offset) {
|
if (needSetZero && cache->info.useSize < offset) {
|
||||||
WriteFlashValue(addr + cache->info.useSize, offset - cache->info.useSize, 0);
|
WriteFlashValue(addr + cache->info.useSize, offset - cache->info.useSize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->info.useSize = useSize;
|
cache->info.useSize = useSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->info.crc32 = GetFlashCrc32(addr, useSize);
|
|
||||||
result = WriteFlash(addr + offset, data, size);
|
result = WriteFlash(addr + offset, data, size);
|
||||||
|
cache->waitCrc = 1;
|
||||||
WriteCachePage(cache);
|
WriteCachePage(cache);
|
||||||
|
|
||||||
// 检查是否在保护区域, 需要的话需要写入等待备份
|
// 检查是否在保护区域, 需要的话需要写入等待备份
|
||||||
@ -891,6 +1154,16 @@ uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t HFlashWriteOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size)
|
||||||
|
{
|
||||||
|
return WriteOffset(addr, offset, data, size, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t HFlashWriteRawOffset(HFlashAddr_t addr, uint32_t offset, const void *data, uint32_t size)
|
||||||
|
{
|
||||||
|
return WriteOffset(addr, offset, data, size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void HFlashStreamBegin(HFlashAddr_t addr)
|
void HFlashStreamBegin(HFlashAddr_t addr)
|
||||||
{
|
{
|
||||||
HFlashCacheInfo *cache = FindCache(addr);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
@ -900,11 +1173,12 @@ void HFlashStreamBegin(HFlashAddr_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cache->waitWrite = 1;
|
cache->waitWrite = 1;
|
||||||
|
cache->waitCrc = 1;
|
||||||
cache->info.crc32 = 0xFFFFFFFF;
|
cache->info.crc32 = 0xFFFFFFFF;
|
||||||
cache->info.useSize = 0;
|
cache->info.useSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HFlashStreamWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
uint8_t HFlashStreamWrite(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
uint8_t result = 0;
|
uint8_t result = 0;
|
||||||
HFlashCacheInfo *cache = FindCache(addr);
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
@ -920,6 +1194,7 @@ uint8_t HFlashStreamWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
|||||||
|
|
||||||
result = WriteFlash(addr + cache->info.useSize, data, size);
|
result = WriteFlash(addr + cache->info.useSize, data, size);
|
||||||
cache->waitWrite = 1;
|
cache->waitWrite = 1;
|
||||||
|
cache->waitCrc = 1;
|
||||||
cache->info.useSize += size;
|
cache->info.useSize += size;
|
||||||
++cache->info.modifyCount;
|
++cache->info.modifyCount;
|
||||||
return result;
|
return result;
|
||||||
@ -933,8 +1208,8 @@ void HFlashStreamEnd(HFlashAddr_t addr)
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->waitWrite = 0;
|
|
||||||
cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize);
|
cache->info.crc32 = GetFlashCrc32(addr, cache->info.useSize);
|
||||||
|
cache->waitCrc = 0;
|
||||||
if (IsProtect(addr, cache->info.useSize)) {
|
if (IsProtect(addr, cache->info.useSize)) {
|
||||||
AddBackupAddr(addr, cache->info.useSize);
|
AddBackupAddr(addr, cache->info.useSize);
|
||||||
}
|
}
|
||||||
@ -942,7 +1217,7 @@ void HFlashStreamEnd(HFlashAddr_t addr)
|
|||||||
WriteCachePage(cache);
|
WriteCachePage(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HFlashRawWrite(HFlashAddr_t addr, void *data, uint32_t size)
|
uint8_t HFlashRawWrite(HFlashAddr_t addr, const void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
return WriteFlash(addr, data, size);
|
return WriteFlash(addr, data, size);
|
||||||
}
|
}
|
||||||
@ -962,7 +1237,7 @@ uint8_t HFlashRead(HFlashAddr_t addr, void *data, uint32_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize);
|
const uint32_t readSize = FLASH_MIN(uint32_t, size, cache->info.useSize);
|
||||||
return ReadFlash(addr, data, readSize);
|
return ReadFlashCall(addr, data, readSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_t size)
|
||||||
@ -982,17 +1257,18 @@ uint8_t HFlashReadOffset(HFlashAddr_t addr, uint32_t offset, void *data, uint32_
|
|||||||
|
|
||||||
// 读取的数据超出使用长度, 将使用长度后面填充0
|
// 读取的数据超出使用长度, 将使用长度后面填充0
|
||||||
const uint32_t useSize = offset + size;
|
const uint32_t useSize = offset + size;
|
||||||
const uint32_t remain = useSize - cache->info.useSize;
|
if (useSize > cache->info.useSize) {
|
||||||
if (cache->info.useSize < useSize) {
|
const uint32_t remain = useSize - cache->info.useSize;
|
||||||
memset((uint8_t *)data + size - remain, 0, remain);
|
memset((uint8_t *)data + size - remain, 0, remain);
|
||||||
|
size -= remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReadFlash(addr + offset, data, size - remain);
|
return ReadFlashCall(addr + offset, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size)
|
uint8_t HFlashRawRead(HFlashAddr_t addr, void *data, uint32_t size)
|
||||||
{
|
{
|
||||||
return ReadFlash(addr, data, size);
|
return ReadFlashCall(addr, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData)
|
void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVersionCallback callback, void *userData)
|
||||||
@ -1008,16 +1284,12 @@ void HFlashUpdateVersion(HFlashAddr_t addr, uint16_t newVersion, HFlashUpdateVer
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint16_t oldVersion = cache->info.version;
|
const uint16_t oldVersion = cache->info.version;
|
||||||
cache->waitWrite = 1;
|
|
||||||
cache->info.version = newVersion;
|
cache->info.version = newVersion;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(addr, oldVersion, newVersion, userData);
|
callback(addr, oldVersion, newVersion, userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果回调没有进行页写入, 需要进行页写入
|
WriteCachePage(cache);
|
||||||
if (cache->waitWrite) {
|
|
||||||
WriteCachePage(cache);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HFlashDeleteData(HFlashAddr_t addr)
|
void HFlashDeleteData(HFlashAddr_t addr)
|
||||||
@ -1065,3 +1337,20 @@ uint32_t HFlashGetCrc32(HFlashAddr_t addr)
|
|||||||
return cache->info.crc32;
|
return cache->info.crc32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t HFlashCalcCrc32(HFlashAddr_t addr)
|
||||||
|
{
|
||||||
|
HFlashCacheInfo *cache = FindCache(addr);
|
||||||
|
if (cache == NULL) {
|
||||||
|
FATAL_ERROR("addr[0x%08x] not register", addr);
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetFlashCrc32(addr, cache->info.useSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HFlashSync()
|
||||||
|
{
|
||||||
|
SyncCachePage();
|
||||||
|
SyncPageInfo();
|
||||||
|
SyncBackup();
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user