593c5d0c84
用户裁定(2026-10-28):L1/L1.5/L2/L2.5/L3 这套层号「谁能看懂」,改用语义名。 映射(同一批定稿,含 L4/L5): L1 → 语义取数与有效性 L1.5 → 标定折算 L2 → 全周傅氏相量 L2.5 → 测频与遥测快照 L3 → 保护判据 L4 → 出口与记录 L5 → 动作留痕 实测规模:384 站点 / 62 文件(App/algo、App/task、test/host 六个套件、docs/算法、 产品需求、架构总览、启动顺序、ADC 采样节拍、IEC104 上行、采集短板评测、内存管理、 AGENTS.md、README.md、docs/README.md、.pre-commit-config.yaml 与 scripts 里的注释)。 改法(不是全局替换,逐模式有上下文规则): - 先吃同位语再落裸词:L1 有效性校验 → 语义取数与有效性校验、L2 相量层 → 全周傅氏 相量层、L3 保护 → 保护判据、L2.5 遥测快照 → 测频与遥测快照,避免「保护判据保护判据」 这类重复(第一版就是这么坏掉的,已整体回滚重做)。 - .c/.h 只改注释:先把字符串字面量切出去(引号数为奇数的跨行注释按整行处理), C 字符串里的 L2-in ring 之类原样保留——AGENTS 铁律「字符串字面量必须纯 ASCII」。 - 层内条目号(L1-3 / L2-3 这类)**本批不动**,属批次 2;另外三族(UI 菜单层级 L0~L3、链路延迟分段 L1~L8、CubeMX 防丢失三层)也不动,属批次 3。 - 顺手修的措辞:范围写法 L1~L3 → 「分层(语义取数与有效性 → 保护判据)」、 CI 段「不含 L1/L2/L3」→「不含采集链分层」、目录地图里同一处并列表述。 验证:@build 0 错 0 警(Code=236456,与改前逐字节同尺寸——纯注释改动); 内存布局配图已按新脚本重生成(自检通过);doc-links --all --sections-strict 通过 (195 文档);mojibake / bom-guard / coding-standard / 新编号门禁自查 全 rc=0; git diff --check 干净。
200 lines
13 KiB
C
200 lines
13 KiB
C
/*
|
||
* 模块名称:运行参数段(全周傅氏相量/保护判据整定层,「数据可信」这一项)
|
||
* 模块功能:遥测死区(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 */
|