Files
STM32F4-Base/Drivers/BSP/NETCFG/net_cfg.h
T
wandering1 0f7b5a87fb chore(编号): 存量编号全量转语义短语,门禁识别面与语料同批重打
登记簿、文档与代码注释里的存量字母加数字编号(N-x / S-x / T-x / E-x / A-x / 卡号)
一律改写为语义短语,净删 2,028 处引用;删除基线与待确认、并行分道方案、排期详述、
采集保护收尾 4 篇(内容已并入 docs/任务规划/README 与登记簿)。

门禁机器与三张账同批重打:check_ids.py 新增变更记录行豁免与第二根护栏
undecidable_total_ceiling;check_test_traceability.py 只加 stdout/stderr UTF-8
reconfigure(TC_RE 未动);check_cubemx_survival.py 的 --write 固定 newline=LF;
id_registry / id_aliases(+19 条 retired-to-phrase)/ id_known_backlog 重打。

test/ 56 个文件同步 TC 标签语义化,其中 18 个 TU 改了 CHECK / printf 里的标签文字,
是本批唯一改变构建产物的文件集合。

为什么合成一笔、不拆四笔(实测撞闸,非偏好):pre-commit 跑钩子前会 stash 未 staged
部分,拆开后中间提交必然是「新规则 + 旧语料」——实跑可判定 85.15% < 基线 86.00%、
不可判定 1,453 > 上限 1,166,编号门禁直接拦下。编号识别面与它描述的语料只能同码移动。

实跑基线(工作区全量):754 文件 / 8,230 处编号字面量 / 可判定 7,079 = 86.01%
(基线 86.0%,容差 0.1pp)/ 不可判定绝对数 1,151(上限 1,166)/ 校验 1-6 错误级 0 /
告警 = 悬空 2(App/algo/freq.c 的 S2,属 §4.4 同号不同义)+ 孤儿 50。

基线从 84.0 抬到 86.0 的理由见 docs/门禁说明/id-check.md §7.6:本批真删了 2,028 处
引用,可判定面随真实内容上升,不是把分母做小。同批新增排除 docs/硬件平台/ 语料,使
识别面少 264 处——芯片手册位号与网表料号不属编号空间(registry 有 excluded_paths_note)。

⚠ 余量只剩 0.11pp(约 10 处)与绝对数 15 处:把「可判定的引用」改成散文会立刻撞第二
根护栏。另遗留一项:id_aliases 里 retired 的 N / S / T / A 别名没有 scope(U1~U5 有),
今后有人新写一个 A-4,校验 3 不会响,只能靠人,建议下批补 scope。

固件不变证据:115 个 .c/.h 剥注释并归一字符串后与 HEAD 逐字节全等,残留代码差异 0;
App / Src / Drivers 的字符串字面量零改动。@build 0 错误 0 警告;40/40 主机套件、2,889
断言全通过;覆盖率 line 89.2% / func 92.6%;pre-commit 48 钩子 --all-files 全绿;
check_doc_links --all 通过(176 文档,章节引用无法判定 0);逐字节卫生核过:14 个带
BOM 文件与 HEAD 一致、0 个 CR、0 个 U+FFFD,字符串字面量纯 ASCII。

.cubemx_survival_baseline.json 的 watchdog-module 哈希 56bf27 变 2bb051 属合法:
Src/freertos.c 的 USER CODE 区内只有注释文字随编号改写,代码未变。

同批带上体积同码凭证与 RAM 台账行(@build 之后盖戳):RW_IRAM1 79,008 B / 60.3%,
RW_CCM 57,376 B / 87.9%,阈值 92%。
2026-10-26 12:28:14 +08:00

219 lines
9.3 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.
/*
* 模块名称:Network Configuration (NET CFG)
* 模块功能:网络参数配置(IP/掩码/网关/MAC)——双端共享核心:RAM 配置副本 +
* 工厂默认 + 加载/保存编排 + 实际 MAC 影子 + 跨任务保存请求交接;
* 存储经 cfg_file 通用配置文件引擎(INI [network] 段:ip/mask/gw/mac;
* MCU = NAND 上 /config.ini,模拟器 = sim_config.ini);MAC 全零哨兵
* = 不覆盖芯片内置 MAC。cfg_file 引擎为静态单任务设计,调用收敛于
* 单一属主任务(MCU = defaultTask:就绪屏障前加载 / 保存执行 / 2s
* poll;模拟器 = 主循环);UI 保存只投递请求,netTask 只读 RAM 副本
* 函数说明:旧版 NCFG 二进制格式(magic+ver+CRC-16+18B 字段)的迁移路径
* (net_cfg_legacy)**已于 2026-10-10 删除** → 旧档 /cfg/netcfg.bin
* 不再读取/迁移,携带旧档的设备升级后回落工厂默认(理由见 net_cfg.c v1.3)
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:王建锋
* 创建日期:2026-09-10
* 修改记录:
* v1.0 2026-09-10 王建锋 创建初始版本
* v1.1 2026-09-14 王建锋 存储迁移至 cfg_file 引擎(INI [network] 段)
* v1.2 2026-09-15 王建锋 保存改跨任务交接(request/state/run + 通知回调);
* 引擎属主明确为 defaultTask(竞态修复)
*/
#ifndef NET_CFG_H
#define NET_CFG_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* 网络参数配置(RAM 副本)
* mac 全零哨兵:不设置芯片 MAC(用芯片内置值,存于芯片 EEPROM)
*/
typedef struct {
uint8_t ip[4]; /* IP 地址(工厂默认 192.168.1.100) */
uint8_t mask[4]; /* 子网掩码(工厂默认 255.255.255.0) */
uint8_t gw[4]; /* 默认网关(工厂默认 192.168.1.1) */
uint8_t mac[6]; /* MAC 地址(全零 = 芯片内置 MAC) */
} net_cfg_t;
/*
* 函数功能:从存储加载网络配置到 RAM 副本
* 入口参数:无
* 返回值:恒 0(RAM 恒有效:文件缺失/损坏回退工厂默认) int
* 限定条件:由配置引擎属主任务调用(MCU = defaultTask,置位
* SYS_EVT_STORAGE_READY 前;模拟器 = 主循环启动期);文件读失败
* 自动回退工厂默认(不阻塞网络启动)
* 函数说明: 1. 注册 [network] 段(幂等)
* 2. 文件缺失 → 先迁旧档 NCFG(有效 → 旧值物化进新文件),否则
* 生成出厂模板
* 3. 解析文件:有效键 → RAM 副本;无效/缺失键 → 工厂默认并留痕
* 4. 严重错误 → RAM 副本 = 工厂默认(不让坏配置带崩网络)
*/
int net_cfg_load(void);
/*
* 函数功能:保存当前 RAM 配置到存储(Flash 持久化)
* 入口参数:无
* 返回值:0 - 成功;-1 - 写失败 int
* 限定条件:仅配置引擎属主任务上下文调用(MCU = defaultTask;模拟器 = 主循环);
* 跨任务保存请用 net_cfg_save_request 投递
* 函数说明:经 cfg_file 引擎写盘(外科手术式保存:保留注释/未知内容,
* 临时文件 + 原子改名);属主任务执行,成功后触发"立即应用"
*/
int net_cfg_save(void);
/*
* "立即应用"回调类型:平台挂钩(可选)
* 入口参数:无
* 返回值:无
* 函数说明:MCU 端由 netTask 注册——置 SYS_EVT_NET_RECONFIG 事件,由 netTask
* 重建网络;模拟器无网络栈,不注册(空操作)。经回调而非直接调用,
* 避免 NETCFG(驱动层)反向依赖 App 层。
*/
typedef void (*net_cfg_apply_cb_t)(void);
/*
* 函数功能:注册"立即应用"回调
* 入口参数:cb - 回调函数(NULL = 注销) net_cfg_apply_cb_t
* 返回值:无
* 限定条件:应用启动早期注册一次即可
* 函数说明:见 net_cfg_apply_cb_t
*/
void net_cfg_set_apply_cb(net_cfg_apply_cb_t cb);
/*
* 函数功能:请求立即应用当前 RAM 配置
* 入口参数:无
* 返回值:无
* 限定条件:无(未注册回调时空操作)
* 函数说明:保存写盘成功后由属主任务调用(MCU:defaultTask);真正生效
* 由平台回调完成(MCU:netTask 重建网络,无需重启)
*/
void net_cfg_request_apply(void);
/*
* 保存请求交接状态(UI 保存行显示)
* IDLE - 尚无保存(显示 ENTER)
* WAIT - 保存进行中:请求已投递未执行 / 属主任务写盘中(显示 WAIT)
* OK - 最近一次保存成功(显示 OK)
* FAIL - 最近一次保存失败(显示 ERR)
*/
#define NET_CFG_SAVE_ST_IDLE 0u
#define NET_CFG_SAVE_ST_WAIT 1u
#define NET_CFG_SAVE_ST_OK 2u
#define NET_CFG_SAVE_ST_FAIL 3u
/*
* 函数功能:投递"保存网络配置"请求(跨任务交接的投递端)
* 入口参数:无
* 返回值:恒 0 int
* 限定条件:任意任务上下文(UI 保存行);新值须已落 RAM 副本(net_cfg_set)
* 函数说明:只置"待保存"标志 + 经平台回调唤醒属主任务(MCU:置
* SYS_EVT_CFG_SAVE 事件);写盘与"立即应用"由属主任务执行
* (net_cfg_save_run),UI 不直接触碰配置文件引擎
*/
int net_cfg_save_request(void);
/*
* 函数功能:取保存请求交接状态(供 UI 保存行显示)
* 入口参数:无
* 返回值:NET_CFG_SAVE_ST_IDLE / _WAIT / _OK / _FAIL int
* 限定条件:任意任务上下文(单字节读取,无撕裂)
*/
int net_cfg_save_state(void);
/*
* 函数功能:执行待处理的保存请求(配置文件引擎属主任务)
* 入口参数:无
* 返回值:0 - 无待处理请求或保存成功;-1 - 写盘失败 int
* 限定条件:仅配置引擎属主任务上下文(MCU = defaultTask;模拟器 = 主循环)
* 函数说明:有待处理请求 → 先清标志(写盘期间的新请求重位置位,下轮再
* 执行,不丢失)→ net_cfg_save() 写盘 → 成功置 OK 并触发"立即
* 应用"(netTask 重建网络);失败置 FAIL(不触发应用,网络保持
* 原配置)
*/
int net_cfg_save_run(void);
/*
* "保存请求"通知回调类型:平台挂钩(可选)
* 入口参数:无
* 返回值:无
* 函数说明:MCU 端由 defaultTask 注册——置 SYS_EVT_CFG_SAVE 事件立即唤醒
* 属主任务执行写盘;模拟器单线程无需唤醒,不注册(空操作)。
* 经回调而非直接调用,避免 NETCFG(驱动层)反向依赖 App 层。
*/
typedef void (*net_cfg_save_req_cb_t)(void);
/*
* 函数功能:注册"保存请求"通知回调
* 入口参数:cb - 回调函数(NULL = 注销) net_cfg_save_req_cb_t
* 返回值:无
* 限定条件:应用启动早期注册一次即可
* 函数说明:见 net_cfg_save_req_cb_t
*/
void net_cfg_set_save_req_cb(net_cfg_save_req_cb_t cb);
/*
* 函数功能:取 RAM 配置副本(只读指针)
* 入口参数:无
* 返回值:RAM 配置副本指针(恒非空) const net_cfg_t *
* 限定条件:无
* 函数说明:netTask(启动期读取组网)与 UI 页(显示/编辑)共用
*/
const net_cfg_t *net_cfg_get(void);
/*
* 函数功能:更新 RAM 配置副本(不写盘)
* 入口参数:p_cfg - 新配置指针(不可为 NULL) const net_cfg_t *
* 返回值:无
* 限定条件:p_cfg 非空;写盘须另行调 net_cfg_save
* 函数说明:UI 编辑页调整字段后经此落 RAM 副本
*/
void net_cfg_set(const net_cfg_t *p_cfg);
/*
* 函数功能:回写芯片实际 MAC(影子区,供 UI 显示)
* 入口参数:p_mac - 芯片读回的实际 MAC(不可为 NULL) const uint8_t *
* 返回值:无
* 限定条件:net_init 成功后由 netTask 上下文调用
* 函数说明:CH395F SPI 归 netTask 独占(中断/轮询集中处理);UI 页不可直接
* 调 SPI 读命令,故 netTask 初始化后读回实际 MAC 存于此供
* "网口设置"页显示(存储 MAC 全零时显示芯片内置 MAC)
*/
void net_cfg_set_active_mac(const uint8_t *p_mac);
/*
* 函数功能:取显示用 MAC
* 入口参数:p_out - 6 字节输出缓冲(不可为 NULL) uint8_t *
* 返回值:无
* 限定条件:p_out 非空
* 函数说明:存储 MAC 非全零 → 存储值;否则芯片实际(已回写时);
* 否则全零(网络未初始化/芯片内置未知)
*/
void net_cfg_get_mac(uint8_t *p_out);
/*
* 函数功能:4 字节 IPv4 格式化为点分十进制字符串(每段 3 位补零)
* 入口参数:p_ip - 4 字节 IP(不可为 NULL) const uint8_t *
* p_buf - 输出缓冲(不可为 NULL) char *
* len - 缓冲长度 size_t
* 返回值:无
* 限定条件:p_ip/p_buf 非空;len ≥ 16(输出 15 字符 + '\0')
* 函数说明:"192.168.001.100"——每段 3 位补零使字符串定长,UI 编辑光标
* 可按固定偏移(4i/3i 起始)定位字节;net_init 的 parse_ip_string
* 对前导零兼容(十进制逐段解析)
*/
void net_cfg_fmt_ipv4(const uint8_t *p_ip, char *p_buf, size_t len);
#ifdef __cplusplus
}
#endif
#endif /* NET_CFG_H */