007f6a0e2f
原「配置文件设计说明.md」是 2026-09 的规划文档(P1~P8 实施计划、D1~D15 决策表、差距调研、模块清单动作列、已终结的开放问题),与现在跑的系统 已有明显出入。改写成只描述当前状态的「配置文件设计.md」。 新文档 9 节:概览 / 文件格式(路径与容量、语法、出厂模板原文、值类型)/ 运行时机制(上电加载、外科手术式保存、2s 轮询与沉降、视图一致性守卫、 写者归属)/ 段与键表(8 段全满、注册顺序、接入新段模板、段回调)/ 接口(引擎 API、平台后端)/ 内存占用(编译期钉死的 9217B 暂存)/ 异常与恢复 / 双端差异 / 已知限制。 顺带修正一处事实错误:旧文档称 FTP STOR 是「写 .TMP 再 rename 原子更新」, 实际 lftpd receive_file 是原地覆写,已按代码现状改写。 旧二进制档(NCFG)的叙述按裁定从全仓移除:文档只描述当前状态,不再 交代旧版本兼容性。删掉网络配置说明 §3.2 整节(后续小节重排为 3.2~3.5), 并清理 README / 架构总览 / 产品需求 / 部署环境等 11 处同类叙述。 同步: - 8 段注册、FTP 原地覆写、2s FAT mtime 粒度等数据更新进配置分层架构图, 重跑后与生成器逐字节一致,check_generated_fresh 里这条存量基线下架 - 全仓 24 处引用改用新文档名,旧节号逐条映射到新节号 - 文档规范 §7.1 变更记录例外名单 4 篇减为 3 篇(该档实际无变更记录表) 验证:48 个提交期钩子全通过;Keil 构建 0 错误 0 警告; check_doc_links / check_mermaid / check_generated_fresh 均通过。
114 lines
4.1 KiB
C
114 lines
4.1 KiB
C
/*
|
||
* 模块名称:cfg_file_store
|
||
* 模块功能:cfg_file 平台存储后端接口——带路径的文件操作抽象;
|
||
* MCU 实现 = NAND 上 FatFS(cfg_file_store_mcu.c),
|
||
* 模拟器实现 = 宿主文件系统(cfg_file_store_sim.c)
|
||
* 适用平台:双端接口(实现分居两端)
|
||
* 作者:王建锋
|
||
* 创建日期:2026-09-14
|
||
* 修改记录:
|
||
* v1.0 2026-09-14 王建锋 创建初始版本
|
||
*/
|
||
|
||
#ifndef CFG_FILE_STORE_H
|
||
#define CFG_FILE_STORE_H
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
#include <stdint.h>
|
||
|
||
#include <stddef.h>
|
||
|
||
/*
|
||
* 文件变更基线:size + mtime 变更令牌
|
||
* mtime 仅作等值比较(不等 = 可能变更):
|
||
* MCU 端 = FAT 打包时间(fdate<<16 | fmtime,分钟级粒度)
|
||
* 模拟器 = 宿主文件 mtime(秒级)
|
||
*/
|
||
typedef struct {
|
||
uint32_t size;
|
||
uint32_t mtime;
|
||
} cfg_file_stat_t;
|
||
|
||
/*
|
||
* 函数功能:分配共享核心临时缓冲(由平台后端提供:MCU = FreeRTOS 堆 pvPortMalloc,
|
||
* 模拟器 = 宿主 CRT malloc)
|
||
* 入口参数:size - 字节数 size_t
|
||
* 返回值:缓冲指针(内容未清零);失败返回 NULL void *
|
||
* 限定条件:必须与 cfg_store_free 配对;共享核心(cfg_file.c / net_cfg.c)禁止直接
|
||
* 调用 C 库 malloc——MCU 端 MicroLIB C 堆仅 512 B(startup Heap_Size=0x200),
|
||
* KB 级分配必然失败,一律经本接口取 FreeRTOS 堆
|
||
*/
|
||
void *cfg_store_alloc(size_t size);
|
||
|
||
/*
|
||
* 函数功能:释放 cfg_store_alloc 分配的临时缓冲
|
||
* 入口参数:p_buf - 缓冲指针(NULL 安全) void *
|
||
* 返回值:无
|
||
* 限定条件:p_buf 必须来自 cfg_store_alloc(不得跨分配器释放、不得释放栈地址)
|
||
*/
|
||
void cfg_store_free(void *p_buf);
|
||
|
||
/*
|
||
* 函数功能:当前空闲堆字节数(分配失败诊断用,非精确预算)
|
||
* 入口参数:无
|
||
* 返回值:空闲字节数;模拟器不跟踪宿主堆,恒返回 0 uint32_t
|
||
* 限定条件:无
|
||
*/
|
||
uint32_t cfg_store_heap_free(void);
|
||
|
||
/*
|
||
* 函数功能:读文件(最多 cap 字节)
|
||
* 入口参数:p_path - 文件路径 const char *
|
||
* p_buf - 接收缓冲(不可为 NULL) uint8_t *
|
||
* cap - 缓冲容量 size_t
|
||
* p_nread- 实际读字节数输出(不可为 NULL) size_t *
|
||
* 返回值:0 - 成功;-1 - 文件缺失/读失败 int
|
||
* 限定条件:调用方保证 p_buf 容量 ≥ 所需长度(引擎读上限 CFG_FILE_MAX_LEN)
|
||
*/
|
||
int cfg_store_read(const char *p_path, uint8_t *p_buf, size_t cap, size_t *p_nread);
|
||
|
||
/*
|
||
* 函数功能:原子写文件(先写临时文件,成功后改名覆盖目标)
|
||
* 入口参数:p_path - 目标文件路径 const char *
|
||
* p_buf - 待写数据(不可为 NULL) const uint8_t *
|
||
* len - 数据长度 size_t
|
||
* 返回值:0 - 成功;-1 - 写/改名失败(目标文件保持不动,临时文件清理) int
|
||
* 限定条件:中途失败不得损坏目标文件(掉电安全)
|
||
*/
|
||
int cfg_store_write_atomic(const char *p_path, const uint8_t *p_buf, size_t len);
|
||
|
||
/*
|
||
* 函数功能:文件状态(size + mtime 变更令牌)
|
||
* 入口参数:p_path - 文件路径 const char *
|
||
* p_st - 输出(不可为 NULL) cfg_file_stat_t *
|
||
* 返回值:0 - 成功;-1 - 文件缺失/读失败 int
|
||
* 限定条件:无
|
||
*/
|
||
int cfg_store_stat(const char *p_path, cfg_file_stat_t *p_st);
|
||
|
||
/*
|
||
* 函数功能:删除文件
|
||
* 入口参数:p_path - 文件路径 const char *
|
||
* 返回值:0 - 成功;-1 - 文件缺失/删除失败 int
|
||
* 限定条件:无
|
||
*/
|
||
int cfg_store_remove(const char *p_path);
|
||
|
||
/* 函数功能:取配置文件路径(如 MCU "/config.ini"、模拟器 "sim_config.ini") */
|
||
const char *cfg_store_config_path(void);
|
||
|
||
/* 函数功能:取配置文件临时文件路径(write_atomic 内部用) */
|
||
const char *cfg_store_tmp_path(void);
|
||
|
||
/* 注:旧版遗留档 getter `cfg_store_legacy_path()` 已于 2026-10-10 随旧档迁移
|
||
* net_cfg_legacy 一并删除(旧二进制档不再读取) */
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* CFG_FILE_STORE_H */
|