Files
STM32F4-Base/App/cfg/cfg_file.h
T

139 lines
6.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称:cfg_file
* 模块功能:通用配置文件引擎(双端共享核心)公共接口——INI 段/键表解析校验、
* 外科手术式保存(保留注释/未知内容,缺失段/键写回)、出厂模板生成、
* 沉降去抖轮询与分段变更回调;平台文件操作经 cfg_file_store 后端
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:王建锋
* 创建日期:2026-09-14
* 修改记录:
* v1.0 2026-09-14 王建锋 创建初始版本(P3:段键表引擎 + net_cfg 集成)
* v1.1 2026-09-15 王建锋 属主任务由 netTask 改为 defaultTask(配置引擎单一属主,P1-3)
* v1.2 2026-09-21 王建锋 E-01(错误码传播审计 P0):超长守卫契约同步——poll 沉降
* 后先按真实 st.size 判超长(旧实现查截断后读长恒假)、
* save 输出上限收紧至 CFG_FILE_MAX_LEN、写盘唯一闸口拒写
* 超长;超长处置补自检留痕
*/
#ifndef CFG_FILE_H
#define CFG_FILE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
/* 配置文件长度上限(字节);超过 = 文件损坏,按出厂模板重建
* (load 与 poll 同判,E-01:poll 在读取前基于真实 st.size 判定) */
#define CFG_FILE_MAX_LEN 4096u
/* 引擎可注册段数上限 */
#define CFG_FILE_MAX_SECTIONS 8u
/* 单段键数上限 */
#define CFG_FILE_MAX_KEYS 16u
/* 沉降去抖:变更基线连续 N 次轮询不变才重载(轮询周期 2s → 4s 沉降) */
#define CFG_FILE_SETTLE_CNT 2u
/*
* 键值类型
* UINT:无符号十进制;len = 目标字段字节数(1/2/4,小端)
* IP4 :点分 IPv4 "a.b.c.d";字段 uint8_t[4]
* MAC :十六进制 MAC "xx:xx:xx:xx:xx:xx"(分隔符兼容 - 与 .);字段 uint8_t[6]
* STR :ASCII 字符串;字段 char[len](len = 缓冲长度,自动补 NUL)
*/
typedef enum {
CFG_VAL_UINT = 0,
CFG_VAL_IP4,
CFG_VAL_MAC,
CFG_VAL_STR
} cfg_val_type_t;
/* 键定义(offset/len 均相对段 RAM 副本起始) */
typedef struct {
const char *name; /* 键名(小写) */
cfg_val_type_t type; /* 值类型 */
size_t offset; /* 字段偏移 */
size_t len; /* 字段长度 */
} cfg_key_def_t;
/* 段注册描述符 */
typedef struct {
const char *name; /* 段名(≤ 15 字符) */
void *p_data; /* 段 RAM 副本(模块自有静态区,引擎原地更新) */
const void *p_defaults; /* 工厂默认值(与 p_data 同布局;load 先复位再解析) */
size_t data_size; /* RAM 副本字节数 */
const cfg_key_def_t *p_keys; /* 键表 */
uint8_t key_count; /* 键数(1 ~ CFG_FILE_MAX_KEYS) */
void (*p_cb)(void); /* 变更回调(可空;poll 重载后该段有差异时调用;
注册段 data_size 须 ≤ 64 字节方可挂回调) */
} cfg_section_reg_t;
/*
* 函数功能:注册配置段(引擎建立"段 → RAM 副本 + 键表"映射)
* 入口参数:p_reg - 段注册描述符(不可为 NULL) const cfg_section_reg_t *
* 返回值:0 - 成功;-1 - 参数非法/段名重复/段数超限 int
* 限定条件:启动早期调用一次(重复注册同段名拒绝);
* 注册后 p_data/p_defaults/p_keys 生命周期须覆盖引擎使用期
*/
int cfg_file_register(const cfg_section_reg_t *p_reg);
/*
* 函数功能:从配置文件加载全部段(文件 = 配置唯一来源)
* 入口参数:无
* 返回值:0 - 正常(含回退工厂默认);-1 - 严重错误(RAM 已置工厂默认,仍安全) int
* 限定条件:至少注册一个段
* 函数说明: 1. 各段先复位工厂默认(文件缺失/损坏的键 = 工厂默认)
* 2. 文件缺失 → 按当前 RAM 副本生成出厂模板写盘(首启建文件)
* 3. 文件存在 → 解析:有效键写入 RAM 副本;无效键留工厂默认并留痕
* 4. 文件超长(> CFG_FILE_MAX_LEN)= 损坏 → 工厂默认 + 重建模板
* + 自检留痕(poll 检出运行期超长文件执行同一契约,E-01)
*/
int cfg_file_load(void);
/*
* 函数功能:保存全部段到配置文件(外科手术式)
* 入口参数:无
* 返回值:0 - 成功;-1 - 写失败(原文件保持不动) int
* 限定条件:至少注册一个段
* 函数说明:文件存在 → 逐行保留注释/未知段/未知键,受管段/键按 RAM 副本
* 值原位改写,缺失段/键补写;文件缺失/损坏 → 按 RAM 副本重建
* 完整文档(含文件头注释);写盘 = 临时文件 + 原子改名;输出超
* CFG_FILE_MAX_LEN → 拒绝保存返回 -1(原文件不动 + 自检上报,
* 引擎写盘闸口同拒,E-01)
*/
int cfg_file_save(void);
/*
* 函数功能:配置文件变更轮询(沉降去抖 + 重载 + 分段变更回调)
* 入口参数:无
* 返回值:无
* 限定条件:由配置引擎属主任务周期调用(建议 2s;MCU = defaultTask,
* 模拟器 = 主循环);引擎静态状态无跨任务保护,属主唯一即无竞态
* 函数说明:(size, mtime 变更令牌) 相对基线变化且连续 CFG_FILE_SETTLE_CNT
* 次轮询稳定 → 先查 st.size 超 CFG_FILE_MAX_LEN = 损坏 → 工厂默认
* + 重建模板 + 自检留痕(不触发段回调:保留在线修复通道,重启
* 收敛,E-01);否则重载全部段(各段复位工厂默认后解析);挂回调
* 段有差异 → 调用其回调(如触发网络重建);重载后刷新基线
* (回调触发的写盘不引发二次重载)
*/
void cfg_file_poll(void);
/*
* 函数功能:取段 RAM 副本指针
* 入口参数:p_name - 段名 const char *
* 返回值:段 RAM 副本指针;未注册返回 NULL void *
* 限定条件:无
*/
void *cfg_file_section_data(const char *p_name);
#ifdef __cplusplus
}
#endif
#endif /* CFG_FILE_H */