94b0d79026
本笔含两组收尾工作(同一工作区内交错在 6 个共享文档/门禁配置里, 拆开会产生"文档声称的页数与树里黄金数不一致"的中间提交,故合为一笔): 一、UI 补齐(清单清空) - 新建 6 个内容页模块:ui_page_accident / oper / alarm / start / yk 复用 ui_w_records 共享组件(分页、空态"无记录"、按实例读盘缓存), 记录层与五个写入点已由道F task-10 / 道G task-12 落地,本批只补页面; ui_page_runreport 为 13 行 2 页只读统计,四个数逐个挂范围标签 (自电池周期 / 本次开机),boot_ready=0 显 "--" 不显 0。 - 数据面:ui_data_info_t 尾部追加 9 字段,ui_data_feed 用 boot_stats_get() + iec104_serv_get_stats() 纯搬运;模拟器填确定值假数据 (差异登记 docs/测试说明/模拟器差距清单.md §2.3 两行)。 - 接线:菜单树 6 叶绑 #page=,绑定叶 22→28、UI_PAGE_MAP_COUNT=28; 字库 185→218 字 / 280→313 字形;双端注册 uvprojx +30、CMakeLists +6。 - 回归:内容页黄金 53→60(含 runreport_p2 真拍第 2 页),文本断言 425 正向 / 36 反向;存量 53 张逐字节零漂移;记录 5 页各用独立空目录 (模拟器把操作留痕写进 cwd 的 sim_oper.log,共用 tmp 会让空态拍不到)。 二、数据可信销项 + 「数据可信」任务卡号整族清退 - 删除已闭环的"已知电压注入验证"行与闭环结论块(证据在 docs/硬件平台/ADC通道映射说明.md §8.1 与 docs/测试说明/ADC前端注入验证流程.md §5~§7),§5 标识列改语义短语。 - 卡 0/0b/1~12 共 14 个号全仓 288 站点 / 56 文件清退成语义短语, 代码注释、测试、门禁配置与文档一并改;换算表入 docs/编号规范.md §9.3。 这一族是中文前缀,不进 check_ids 语料,刻意不入 id_aliases.json。 验证(实测) - @build 0 错 0 警:Code=236456 RO=28124 RW=1876 ZI=137084; RAM +464 B(RW +304 / ZI +160),RW_IRAM1 62.2% / RW_CCM 87.9%, 体积同码凭证与 RAM 台账已回填。 - check_menu_rows 8 状态 rc=0(池 5368/5448 常量未动); check_content_pages 60 页 rc=0;check_font_charset / registration / coding-standard / bom-drift / mojibake / doc-links --all / layer-deps / nested-comment 全 rc=0;check_ids --strict 无错误;主机单测 ui_data 295 / boot_stats 21 / sys_log_mcu 141 / soe 32 / soe_store 27。 未做(不是遗漏) - 六页真机判据(真记录翻页、掉电保持、清除后归零、boot_count 自增、 拔 RTC 电池落 RESTARTED、IWDG 复位落 rst_cause、主站连一次 conn_up+1) 已登记 docs/任务规划/登记簿.md §7;模拟器结构上照不到。 - docs/产品需求/产品需求设计文档.md 属另一条在飞改动,本笔不含; 其中我已同步 6 处现状数字(28 叶 / 60 页 / 218 字),随该笔入库。
200 lines
13 KiB
C
200 lines
13 KiB
C
/*
|
||
* 模块名称:运行参数段(L2/L3 整定层,「数据可信」这一项)
|
||
* 模块功能:遥测死区(9 点)与通道标定系数覆盖(k/b 各 8 路)的**单一真源**:
|
||
* - 死区 = 本模块 int32 毫单位 RAM 副本(注册进 cfg 引擎 [run_par] 段,
|
||
* 工厂默认 = 「数据可信」下游常数按工程量重定后的额定 0.5 % 档),104 消费侧
|
||
* (App/protocol/iec104/iec104_pts.c)每拍实时读取——无投递、无缓存
|
||
* 副本(104 改读快照曾在 pts 侧留运行时副本 s_yc_db,运行参数段落地后收编于此,
|
||
* 双源必打架);
|
||
* - 系数覆盖 = **直通 adc_cal_set()**([adc_cal]/[adc_cal_ofs] 是系数
|
||
* 唯一真源,标定落盘与整定入口已定;本模块只加 104 地址映射 + 落盘请求,不另存
|
||
* 一份系数——同 D1 裁"两处判断必打架"逻辑)。
|
||
* 104 地址映射(docs/算法/继电保护功能复现规划.md §5.1 运行参数类
|
||
* 0x8020H~0x8058H;逐项表原文"待补"(参考项目 CommPara_ConfigTable
|
||
* 不在仓),本表即运行参数段的落实,送检点表若另给权威地址只改常量段:
|
||
* 0x8030~0x8038 = 死区 UA/UB/UC/UN/IA/IB/IC/IN/FREQ(工程量 V/A/Hz);
|
||
* 0x8040~0x8047 = k 覆盖(µV/码);0x8048~0x804F = b 覆盖(码值,可负);
|
||
* 其余留白(未启用类别),**0x8027~0x802A 属 prot_set 告警段**,本表
|
||
* 永不让位(两表按精确地址分流,见 iec104_pts.c set 路由)。
|
||
* 持久化(B7 prot_set 先例同款):任一写成功 → 脏标志只置不清;
|
||
* iec104Task 主循环 peek → 置 SYS_EVT_RUN_PAR_SAVE → defaultTask
|
||
* (配置引擎属主)run_par_store_save() 调 cfg_file_save() 整档外科
|
||
* 保存(含 [run_par] 与刚被 adc_cal_set 改写的 [adc_cal]/[adc_cal_ofs]
|
||
* 副本)→ 成功清脏;失败留脏 = 下轮天然重试。本模块自身零文件 IO
|
||
* (属主纪律)。
|
||
* ⚠ 三份职责别混(道G task-43 第③项,此前只有意图式陈述):
|
||
* - **谁写 RAM**:系数/零点的唯一真源是 adc_cal 的引擎副本,而本模块那两支
|
||
* 语义 setter(run_par_cal_k_set / run_par_cal_b_set,task-7 落地)是**唯一
|
||
* "写值 + 置脏"成对发生**的入口;任何消费者绕过它们直调 adc_cal_set(),
|
||
* 值只进 RAM、脏标志不动 ⇒ 屏上"当前生效"是新的、盘上仍是旧的、重启即丢,
|
||
* 且该路径**没有错误返回**。这条形态现在可观测:adc_cal 侧
|
||
* set_ok 与落盘水位的差额 > 0,而 run_par_dirty_peek() 恒为 0。
|
||
* - **谁落盘 / 什么时机**:只有 defaultTask 的 run_par_store_save()(由
|
||
* iec104Task peek 后置的 SYS_EVT_RUN_PAR_SAVE 驱动);本模块零文件 IO。
|
||
* - **cfg_file_poll() 不是保存路径**:它的方向是**盘 → RAM 的重载**(外部
|
||
* 改档 → 沉降去抖 → 重载),拿它"兜住"未落盘的改值会把 FTP 侧的旧档倒灌
|
||
* 回 RAM,比不兜更坏。设计依据见 docs/算法/采集与算法层设计说明.md §10.1。
|
||
* 并发契约:引擎副本 int32 对齐字读写在 Cortex-M4 上原子;poll 重载 µs 级窗口
|
||
* 为「数据可信」§4.4 明载设计(adc_cal 同款)。写路径 = 104 执行段
|
||
* (iec104Task)与引擎读路径互不加锁,勿改成"读侧缓存"(缓存 = 新真源)。
|
||
* 纯算法:只用 stdint/stddef/math + cfg_file.h/adc_cal.h 头(注册/直通均为
|
||
* 接口级)→ 主机侧可单测(test/host/run_par,链真 cfg 引擎 + 真 adc_cal)。
|
||
* 适用平台:STM32F407ZGTx(Cortex-M4F,硬件 FPU)
|
||
* 作者:DTU 项目组
|
||
* 创建日期:2026-10-25(道D 运行参数段)
|
||
* 修改记录:
|
||
* v1.0 2026-10-25 DTU 项目组 创建:[run_par] 段 + 104 地址映射 + 直通
|
||
* adc_cal + B7 式脏标志落盘请求
|
||
* v1.1 2026-10-27 DTU 项目组 道F task-7(遥测整定两页)配套:新增语义
|
||
* setter run_par_cal_k_set / run_par_cal_b_set
|
||
* (写值 + 置脏成对;104 的 k/b 两支同批改调它,
|
||
* 消除两份置脏逻辑)+ 合法域唯一出口
|
||
* run_par_db_range() + 系数粗守上限
|
||
* RUN_PAR_K_MAX_UV;毫→工程换算收进模块内单点
|
||
* s_milli_to_eng()(顺带把 task-43 第①项所需的
|
||
* "写值必置脏"这一半满足掉)
|
||
* v1.2 2026-10-27 DTU 项目组 道G task-43 第②③项:run_par_store_save() 成功路径
|
||
* 给标定层盖一次落盘水位(纯观测回执,不参与判定);
|
||
* 本头把"谁写 RAM / 谁落盘 / 什么时机 / poll 不是保存
|
||
* 路径"从意图式陈述改成逐条契约
|
||
*/
|
||
|
||
#ifndef RUN_PAR_H
|
||
#define RUN_PAR_H
|
||
|
||
#include <stdint.h>
|
||
|
||
#include "adc_cal.h" /* adc_semantic_t:公开语义 setter 的形参类型(同层 algo→algo,方向不逆)*/
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/* 死区/覆盖点数(死区 = YC 表行数:电气 8 + 频率;覆盖 = 语义电气 8 路) */
|
||
#define RUN_PAR_DB_N 9u
|
||
#define RUN_PAR_CH_N 8u
|
||
|
||
/* 系数 k 的**粗守**上限(µV/码):只为挡误写(如把 mV 当 µV 填),不是工况域;
|
||
* 真合法带在 adc_cal 执行段裁(µV/码 ×[0.5,2.0]),两层各说各的、互不掩盖。
|
||
* 公开它是因为 UI 整定页要给编辑器设上限——上限在这里,就不许页面再抄一份。*/
|
||
#define RUN_PAR_K_MAX_UV 1.0e9f
|
||
|
||
/*
|
||
* 函数功能:运行参数初始化——副本置工厂默认 + 注册 [run_par] 段进 cfg 引擎
|
||
* 入口参数:无
|
||
* 返 回 值:无
|
||
* 限定条件:**内核启动前**调用(app_main_init,adc_cal_init 之后);注册必须先
|
||
* 于 defaultTask 的 cfg_file_load(FTP 鉴权确立的契约,同 adc_cal 先例);幂等
|
||
* 函数说明:注册失败(段名重复/段数超限)打 [ERR] 后继续——工厂默认照常生效,
|
||
* 仅文件整定失效(adc_cal_init 同款降级)。
|
||
*/
|
||
void run_par_init(void);
|
||
|
||
/*
|
||
* 函数功能:读第 idx 路遥测死区(工程量)
|
||
* 入口参数:idx - 0..7 = 语义通道序(UA..IN),8 = 频率 uint8_t
|
||
* 返 回 值:死区 V / A / Hz;idx 越界返 0.0(调用方按"无死区"保守处理) float
|
||
* 限定条件:任意上下文(int32 单字读原子;104 COV 每拍调用)
|
||
* 函数说明:毫单位 → 浮点的换算在本模块内也只有一处(run_par.c 的
|
||
* s_milli_to_eng(),run_par_deadband 与 run_par_db_range 共用);
|
||
* 消费侧一律取本模块给的工程量,不要再各自除 1000。
|
||
*/
|
||
float run_par_deadband(uint8_t idx);
|
||
|
||
/*
|
||
* 函数功能:写第 idx 路死区(工程量,含范围守卫 + 脏置位)
|
||
* 入口参数:idx - 同上 uint8_t;db - 死区工程量(V/A/Hz,≥0) float
|
||
* 返 回 值:0 成功;-1 越界/越程/NaN(副本不动) int
|
||
* 限定条件:写者两门——**iec104Task**(104 C_SE 执行段)与 **uiTask**(遥测死区页
|
||
* 经 ui_data 通道五注入转达,道F task-7 起;ui_data.h 通道五表注:合法域
|
||
* 与"写值+置脏"必须原子发生在执行侧)。两门都只写 RAM 副本 + 置脏,
|
||
* 落盘统一收敛在 defaultTask(勿在 adcTask 调用;此句为 2026-10-27 措辞
|
||
* 收口——原写"UI 若整定需另行走属主路径"是 task-2 期遗留,task-7 已接线)
|
||
* 函数说明:合法域按点型分档——电压 0~50 V、电流 0~1 A、频率 0~5 Hz(上限 =
|
||
* 额定 × 二档裕量,守卫目的是挡误写不是限工况;见 .c 常量段)。
|
||
* 成功即置脏(落盘请求,见文件头持久化契约)。
|
||
*/
|
||
int run_par_deadband_set(uint8_t idx, float db);
|
||
|
||
/*
|
||
* 函数功能:104 运行参数地址读(C_RD 路由,先于 prot_set 扫描)
|
||
* 入口参数:addr - 通讯地址(0x8020~0x8058 段内) uint32_t;out - 工程量浮点
|
||
* (死区 V/A/Hz;k 覆盖 µV/码;b 覆盖 码值) float *
|
||
* 返 回 值:0 命中并写出;-1 地址不归本段(调用方继续走 prot_set) int
|
||
* 限定条件:iec104Task 上下文
|
||
* 函数说明:命中集 = 0x8030~0x8038 / 0x8040~0x8047 / 0x8048~0x804F 精确匹配;
|
||
* k/b 读回 = adc_cal **当前生效值**(与折算同视图:文件坏值被合法带
|
||
* 哨兵回退 ROM 时,回显的就是 ROM——主站看到的即下游实际吃到的)。
|
||
*/
|
||
int run_par_104_read(uint32_t addr, float *out);
|
||
|
||
/*
|
||
* 函数功能:104 运行参数地址写(C_SE 两段式路由,先于 prot_set 扫描)
|
||
* 入口参数:addr - 通讯地址 uint32_t;v - 工程量浮点 float;
|
||
* select - 1 = 选择段(只校验不落副本)/ 0 = 执行段 uint8_t
|
||
* 返 回 值:0 接受;-1 拒绝(越程/NaN/合法带外/非本段可写地址命中守卫);
|
||
* -2 地址不归本段(调用方继续走 prot_set) int
|
||
* 限定条件:iec104Task 上下文;执行段成功即置脏
|
||
* 函数说明:k/b 覆盖经 adc_cal_set() 合法带哨兵(µV/码 ×[0.5,2.0]、|b|≤8192,
|
||
* 越带 -1 → 104 侧 PN 否定确认,adc_cal 不留痕由**其自身**越带 [ERR]
|
||
* 机制负责——本模块直通不重复留痕);两段式与 prot_set 定值写同构。
|
||
*/
|
||
int run_par_104_write(uint32_t addr, float v, uint8_t select);
|
||
|
||
/*
|
||
* 函数功能:写某路系数 k(µV/码)**并在同一函数内置脏**——整定的语义写入口
|
||
* 入口参数:sem - 电气语义通道(adc_semantic_t 枚举序) adc_semantic_t;
|
||
* k_uv - 系数(µV/码,须 >0 且 <= RUN_PAR_K_MAX_UV) float
|
||
* 返回值:0 - RAM 副本已写且已置脏;-1 - 粗守或执行段拒(副本未动、不置脏) int
|
||
* 限定条件:整定路径上下文(iec104Task 的 C_SE 执行段;UI 侧由装配层
|
||
* App/app/ui_data_feed.c 经 ui_data_yt_ops_t 转进来)。勿在 adcTask 调用
|
||
* 函数说明:**写值与置脏成对,不许拆开**(lead 裁②):拆开就等于"屏上已改、
|
||
* 盘上永不落、且没有任何错误返回"。因此本模块**不提供**公开的
|
||
* mark_dirty——单独调它等于空承诺;零点 b 由本函数 RMW 取当前生效值。
|
||
*/
|
||
int run_par_cal_k_set(adc_semantic_t sem, float k_uv);
|
||
|
||
/*
|
||
* 函数功能:写某路零点偏移 b(码值)并置脏(与 k 同款语义,粗守 ±1e6 码)
|
||
* 入口参数:sem - 电气语义通道 adc_semantic_t;b_codes - 零点(码值) int32_t
|
||
* 返回值:0 - 已写并置脏;-1 - 粗守或执行段拒(副本未动、不置脏) int
|
||
* 限定条件:同 run_par_cal_k_set()
|
||
* 函数说明:k 侧 RMW 取当前生效值;±8192 真带由 adc_cal 执行段裁。消费者 =
|
||
* 104 的 0x8048~ 分支(改造后走这里),不是为将来预留的口
|
||
*/
|
||
int run_par_cal_b_set(adc_semantic_t sem, int32_t b_codes);
|
||
|
||
/*
|
||
* 函数功能:取第 idx 路死区的合法域(工程量)——**合法域的唯一出口**
|
||
* 入口参数:idx - 0..8 uint8_t;lo/hi - 输出下限/上限(V/A/Hz) float *
|
||
* 返回值:0 - 已写出;-1 - idx 越界或指针空(调用方不得回退成自造默认域) int
|
||
* 限定条件:任意上下文(纯常量读)
|
||
* 函数说明:存在的唯一理由:UI 整定页要给编辑器设 min/max,而这些上限的真源是
|
||
* 本模块的 RUN_PAR_DB_MAX_*;页面抄一份就是第二真源。给的是**粗守域**,
|
||
* 真提交仍由与 104 选择段同源的守卫裁,两条路不会漂移到两套数字。
|
||
*/
|
||
int run_par_db_range(uint8_t idx, float *lo, float *hi);
|
||
|
||
/*
|
||
* 函数功能:落盘脏标志探查(非消费)
|
||
* 入口参数:无
|
||
* 返 回 值:1 = 有已整定未落盘的改动;0 = 干净 uint8_t
|
||
* 限定条件:任意上下文(单字节);iec104_serv 主循环 peek 后投递事件(B7 同款)
|
||
*/
|
||
uint8_t run_par_dirty_peek(void);
|
||
|
||
/*
|
||
* 函数功能:执行落盘请求(cfg_file_save 整档外科保存 + 成功清脏)
|
||
* 入口参数:无
|
||
* 返 回 值:0 成功(或无脏可存);-1 写盘失败(脏保持,下轮重试) int
|
||
* 限定条件:**defaultTask(配置引擎属主)上下文**,由 SYS_EVT_RUN_PAR_SAVE 驱动
|
||
* 函数说明:save 走引擎唯一写闸(超长拒写/原子改名);本函数不清
|
||
* 引擎以外模块的脏语义([adc_cal] 副本值已由写路径就位)。
|
||
*/
|
||
int run_par_store_save(void);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* RUN_PAR_H */
|