样例工程目录结构
WQiang authored at 2021-12-01 10:47:56
3.15 KiB
microCLib
#pragma once

#include "Type.h"

// 需要在自己项目内补充。 ConfigBase_t 只提供读写保存。
#include "Config.h"

// Config 有效性 取决于 魔数和 Crc32
typedef struct
{
	// 魔数  内部使用。 外部不要碰
	// 默认为 : 'M' 'a' 'g' '&'   0x4D616726
	uint MagicNum;
	// 实际配置长度。 
	// 为了做配置向后兼容。 必须有。
	uint Length;

	// 配置实际内容。
	Config_t Config;

	// 校验  内部使用。 外部不要碰
	uint Crc32;
}ConfigBase_t;


// 获取配置
bool GetConfig(Config_t* cfg, uint addr);

// 保存配置
bool SetConfig(Config_t* cfg, uint addr);

// 删除配置内容
bool CleanConfig(uint addr);

/***************************************************************/
/*
写很多份配置的驱动。
NOR FLASH 作为存储载体。
多擦除块设计。
处理写入时断电问题。
*/

// 块:擦除块
typedef struct
{
	// FLASH 写
	bool (*FlashWrite)(uint address, byte* buf, int len);
	// 可以直接通过指针访问的 addr ,此函数为 NULL。
	bool (*FlashRead)(uint address, byte* buf, int len);
	// FLASH 擦块
	bool (*FlashErase)(uint address);
}NorFlash_t;

// 对象
typedef struct
{
	// 内当前最新配置,用于对比是否需要写入。
	Config_t CurrCfg;
	// NOR FLASH 接口
	NorFlash_t FApi;
	// FLASH Section 地址数组,数组长度是 FlashSecCnt
    uint* FSecAddrs;
	// FLASH Section 块个数。 个数 FlashSecCnt = (1 << FSecBit)
	byte FSecBit;
	// FLASH Section 存 Config_t 的份数 = (1 << FSecCfgBit)
	byte FSecCfgBit;

	// 当前使用的 IDEX 。也是存放位置。
	ushort CurrIndex;    
}FCfgCtrl_t;

/*
// FLASH 擦除块地址
const uint secAddr[] = 
{ 
	0    + 0x8000000 + (48 * 1024),
	1024 + 0x8000000 + (48 * 1024),
	2048 + 0x8000000 + (48 * 1024),
	4096 + 0x8000000 + (48 * 1024)
};

// 单片机内部 NOR FLASH
NorFlash_t nfunc = 
{
	.FlashWrite = XXX
	.FlashRead = NULL,
	.FlashErase = XXX,
};

// 直接定义
FCfgCtrl_t FCtl =
{
	.FlashWrite = xxx,
	.FlashErase = xxx,
	.BaseAddrs = secAddr,
	.FSecCnt = 2, 			// (1<<2) 有4块
	.FSecCfgCnt = 3,		// (1<<3) 存8份
	.CfgIndex = 0,
};

使用 FCfgInit 函数配置
FCfgInit(&FCtl, &nfunc, secAddr, ArrayLength(secAddr), 8);

*/

/**
 * @brief 初始化
 * @param ctl
 * @param api NOR FLASH 接口
 * @param sad FLASH 块地址数组
 * @param sadlen 块数组长度
 * @param ccnt 块内 存放配置的份数
 * @return 0 æ— é”™
 */
int FCfgInit(FCfgCtrl_t* ctl, NorFlash_t* api, uint* sad, byte sadlen, byte ccnt);

/**
 * @brief 扫描整个 FLASH 存储区,找到最新且有效的配置取出来
 * @param ctl
 * @param cfg
 */
bool FCfgLoad(FCfgCtrl_t* ctl, Config_t* cfg);

/**
 * @brief 保存配置
 * @param ctl
 * @param cfg
 */
bool FCfgSave(FCfgCtrl_t* ctl, Config_t* cfg);

/**
 * @brief 删除一个配置,应该用不到
 * @param ctl
 * @param idx
 */
bool FCfgClean(FCfgCtrl_t* ctl, int idx);

/**
 * @brief 擦除所有 FLASH 区域,一个不留
 * @param ctl
 */
bool FCfgCleanAll(FCfgCtrl_t* ctl);