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 字),随该笔入库。
145 lines
8.0 KiB
C
145 lines
8.0 KiB
C
/*
|
||
* 模块名称:保护元件框架(L3,P1 子集)
|
||
* 模块功能:通用"越限 + 返回系数滞回 + 定时限"元件核 + 实例表(数据驱动,
|
||
* 同 phasor 实例表模式)。判据为**纯逻辑**(吃测量值 + 定值),
|
||
* 主机侧可离线单测;出口/SOE(L4)与任务编排为后续。
|
||
*
|
||
* V0.1 有效实例(双转换器无共同采样触发 → 仅 TPAFE 三路):
|
||
* OC1/OC2/OC3 三段式相间过流(A 相 IA)
|
||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||
* OL 过负荷(A 相 IA)
|
||
* OV/UV 过压/欠压(UA,过压 / 欠压)
|
||
* 3U0 零序过压(UN 外部零序电压通道)
|
||
* OF/UF 过频/低频(测量量 = freq 层测得频率,过频 / 低频,B8 落地)
|
||
*
|
||
* 测量数组口径:相量类实例 = 基波有效值(A/V);OF/UF = 测得频率(Hz)。
|
||
* run() 按实例表 src 字段取数(0=phasor rms,1=freq)。freq 无有效读数
|
||
* (未启动收敛或幅值门失效)→ 该行按方向填"必不启动"值(过量填 0、
|
||
* 欠量填极大值 → 滞回核比较恒假 → 元件复位不误动),**不整拍跳过**
|
||
* (否则浮空台架会把 OC/UV 等全部饿死,B5 行为回归)。
|
||
*
|
||
* 与参考系统的口径差异(有意简化,均已在规划文档登记):
|
||
* - 返回门槛 = 定值 × 返回系数(参考经 CN_SET_RET 独立定值,等价);
|
||
* - 返回**即时**(参考 GRly_TimeRelay 带 10 ms 返回延时——V0.1 无出口硬件,
|
||
* 抖动只影响日志,P4 接出口时再补返回延时);
|
||
* - 复压/方向/无压无流闭锁(dwSetFyCtrl 类)随 P2/P3 元件扩展;
|
||
* - 测量输入 = adc_task 经 adc_cal_apply() 折算后的工程量(L1.5,标定折算已落地):
|
||
* 未标定(VALID=0)时单位只是 ADC 引脚电压——该域下判据必然错配,由
|
||
* protectTask 的「数据可信」未标定即闭锁停走整条判据链,元件核本身不掺和
|
||
* 标定语义(保持纯逻辑);标定后单位 = 二次值,定值口径才名副其实。
|
||
*
|
||
* 线程约定:init 内核启动前或保护消费者任务上下文;eval/run 仅保护消费者任务
|
||
* 上下文(B5 起 = protectTask);request_reset 任意上下文(跨上下文复归请求,
|
||
* 如 104 遥控 YK11 在 iec104Task 落请求、下一拍 eval 头部消费)。板端接线
|
||
* 走栈预算 + IWDG 心跳门禁。
|
||
*
|
||
* 创建日期:2026-10-11
|
||
*/
|
||
#ifndef PROT_ELM_H
|
||
#define PROT_ELM_H
|
||
|
||
#include <stdint.h>
|
||
|
||
/* 元件实例编号(枚举序 = 实例表序 = 测量数组序;尾追加,编号不回收) */
|
||
typedef enum {
|
||
PE_OC1 = 0, /* 过流 Ⅰ 段(IA) */
|
||
PE_OC2, /* 过流 Ⅱ 段(IA) */
|
||
PE_OC3, /* 过流 Ⅲ 段(IA) */
|
||
PE_OL, /* 过负荷(IA) */
|
||
PE_OV, /* 过压(UA) */
|
||
PE_UV, /* 欠压(UA,欠量方向) */
|
||
PE_3U0, /* 零序过压(UN) */
|
||
PE_OF, /* 过频(测量量 = freq 层测得频率,B8,过频 / 低频) */
|
||
PE_UF, /* 低频(测量量 = freq 层测得频率,欠量方向,B8,过频 / 低频) */
|
||
PE_COUNT
|
||
} prot_elm_id_t;
|
||
|
||
/* 单元件状态快照(读侧拷贝语义,见 prot_elm_state) */
|
||
typedef struct {
|
||
uint8_t enabled; /* 本拍投入(定值投退 && 未闭锁) */
|
||
uint8_t picked; /* 越限启动(滞回后电平) */
|
||
uint8_t asserted; /* 定时限到点(动作) */
|
||
uint32_t pick_ms; /* 本次启动起始时基(0 = 未启动过;asserted 延时观测用) */
|
||
} prot_elm_state_t;
|
||
|
||
/*
|
||
* 函数功能:复位全部元件状态(定值不动;幂等,内核启动前可调)
|
||
* 限定条件:内核启动前,或保护消费者任务上下文(跨上下文请用 request_reset)
|
||
*/
|
||
void prot_elm_init(void);
|
||
|
||
/*
|
||
* 函数功能:登记"复归元件状态"请求(任意上下文安全,单字标志)
|
||
* 函数说明:下一拍 prot_elm_eval() 头部消费并执行 prot_elm_init()。
|
||
* 104 遥控 YK11(iec104Task 上下文)必须走本接口,不得直接调
|
||
* prot_elm_init()(会与 protectTask 的 eval 竞态)。
|
||
*/
|
||
void prot_elm_request_reset(void);
|
||
|
||
/*
|
||
* 函数功能:纯判据步进——按当前定值(prot_set RAM)+ 给定测量值推进所有元件
|
||
* 入口参数:now_ms - 单调时基(tick ms,回绕安全:差值法)
|
||
* meas - PE_COUNT 个测量值(工程量:A / V),NULL 视为全 0
|
||
* 返 回 值:无
|
||
* 限定条件:仅保护消费者任务上下文;调用方保证定值已装载
|
||
* 函数说明:越限方向由实例表决定;投退=0 或定值闭锁(定值校验和)→ 状态复位、
|
||
* 不判据。延时判定用 (uint32_t)(int32_t)(now - t0) >= dly,回绕安全。
|
||
*/
|
||
void prot_elm_eval(uint32_t now_ms, const float meas[PE_COUNT]);
|
||
|
||
/*
|
||
* 函数功能:适配层——从 phasor 使用区取 rms 组装测量数组后调 prot_elm_eval
|
||
* 入口参数:now_ms - 同上
|
||
* 说明:phasor 未就绪(-2,未满一周波)的实例本拍按"测量=上一拍值"处理会
|
||
* 引入陈旧判据 → 直接**整拍跳过**(不 eval),与 adc_task 跳拍同口径。
|
||
*/
|
||
void prot_elm_run(uint32_t now_ms);
|
||
|
||
/* 状态快照拷贝(NULL 安全;越界全零) */
|
||
void prot_elm_state(prot_elm_id_t id, prot_elm_state_t *out);
|
||
|
||
/* 动作位图(bit i = 元件 i asserted),供 L4 出口 / 心跳日志 */
|
||
uint32_t prot_elm_active_mask(void);
|
||
|
||
/* 启动位图(bit i = 元件 i picked),供「保护启动」记录边沿(task-10,2026-10-26):
|
||
* picked 是越限滞回后的电平,早于(或同拍于)asserted——只看 active_mask 会让
|
||
* "启动了但没到点"这一整段在记录里彻底消失,而它正是"保护启动"页要看的东西。 */
|
||
uint32_t prot_elm_pick_mask(void);
|
||
|
||
/*
|
||
* 元件动作边沿的记录归属(task-10「五类记录」)。
|
||
* ⚠ 本枚举刻意**不**用 syslog_id_t:那会把 App/log 的头拽进 algo 层,而
|
||
* App/algo/prot_elm.c 同时被 test/host/prot_dim 编进测试单元(那个运行器的
|
||
* include 路径里没有 App/log,且不在本道写域)→ 一改就在别人的单测上爆错。
|
||
* "元件 → 哪一类"是判据域事实(属主在本文件),"哪一类 → 哪个日志文件"是
|
||
* 记录域映射(属主在 App/task/protect_task.c 的一行三元),两边各自单源。
|
||
*/
|
||
typedef enum {
|
||
PROT_REC_TRIP = 0u, /* 跳闸型动作 → 事故记录 */
|
||
PROT_REC_ALARM, /* 告警型动作 → 保护告警记录 */
|
||
PROT_REC_NONE /* id 越界 → 调用方一条都不许落 */
|
||
} prot_rec_kind_t;
|
||
|
||
/*
|
||
* 函数功能:判定"该元件若发生动作上升沿,应归哪一类记录"
|
||
* 入口参数:id - 元件编号 prot_elm_id_t
|
||
* 返回值:PROT_REC_TRIP / PROT_REC_ALARM / PROT_REC_NONE(越界) prot_rec_kind_t
|
||
* 限定条件:任意上下文(只读 k_pe[] + prot_set RAM,不落任何状态)
|
||
* 函数说明:判据**唯一来源** = 该元件的跳闸投退定值项 g_prot_set_meta 里的
|
||
* PS_*_TRIP(其枚举注释即"0 告警 / 1 跳闸")。元件→投退项的对应关系
|
||
* 放在实例表 k_pe[] 的 trip_ctl 列(与 en_id/set_id/dly_id 同一张表,
|
||
* 新增元件只加一行);**本函数里没有第二份"哪些元件算跳闸"的名单**,
|
||
* 所以它不会与 g_prot_set_meta / k_pe[] / 整定视图门禁互相打架。
|
||
* 过压/欠压/零序过压/过频/低频五项本就没有 TRIP 投退项(告警类)→
|
||
* trip_ctl = PROT_ELM_NO_TRIP → 恒 PROT_REC_ALARM,这是照实反映,
|
||
* 不是兜底猜测。
|
||
* 定值巡检闭锁(prot_set_locked)不影响本判定:闭锁态下元件会被复位、
|
||
* 根本走不到动作上升沿,调用方无需在此重复判闭锁。
|
||
*/
|
||
prot_rec_kind_t prot_elm_record_kind(prot_elm_id_t id);
|
||
|
||
/* 实例名(ROM 常量,日志用) */
|
||
const char *prot_elm_name(prot_elm_id_t id);
|
||
|
||
#endif /* PROT_ELM_H */
|