ffd462ef3c
卡 5(protect_task.c 第⑤闭锁源,「数据可信」§4.3 决策 1=闭锁): - UA/UN/IA 的 adc_cal VALID 未全置位 → prot_elm_init + 本拍不 eval;每拍现查 flags、无自有状态(卡 12 标定写入后自动解锁);判据链优先级 = 采样可信在前、 标定可用在后(数据都是旧的谈不上标定) - 边沿日志用 DBG_INFO 而非 [ERR]:未标定是出厂常态、非故障,且 @test 禁用 [ERR](「默认构建保护不动作 = 期望」的台架判据同步项已在 MR 报 lead); SOE 分型 SOE_T_CAL_BLOCK/RESUME(soe_rec.h 枚举尾追加,值 6/7——reader 侧 显示标签映射归道B reader,MR 已报) - 台架旁路 = 编译期宏 DTU_BENCH(§4.3:不进 cfg 不进 104;本仓所有提交目标 都不定义它 = 产品恒强制闭锁) 卡 6(下游三常数按工程量重定,依据同源 docs/任务规划/数据可信.md §2.3): - FREQ_AMP_MIN(freq.h):语义从拟定码值域重定为二次值 V——50 V = 0.5×Un (标称 100 V),断保险/PT 空载/浮空必低于之;数值沿用 50.0f 属巧合并在 注释明写;eng=0 过渡期本门恒失效 → OF/UF 按必不启动填充,与卡 5 同向安全 - k_yc[].deadband(iec104_pts.c):9 点按「额定 0.5 %」规则重定:电压类 0.5 %×100 V=0.5、电流类 0.5 %×1 A=0.005、频率维持 0.5 Hz 绝对值(非额定 比,卡 10 运行参数化);标称基准与 prot_set 头部同源,防两处真相 - g_prot_set_meta[](prot_set.c):数值/范围复核结论=不动(0~4×标称自洽), 文件头补量纲口径块:A/V = 二次值、标称 100 V/1 A、OV120=1.2Un/UV20=.2Un/ 3U0 15=.15Un、OC1/2/3=10/5/2×Ir、OL=1.0×Ir;PS_ID_COUNT/blob VER 未动 - iec104 套件 TC-008 死区用例同步重定标(100.4 带内 / 101.25 越带),97/97 卡 7(test/host/prot_dim 新套件,真实链 adc_cal→ring→phasor→prot_elm): - 用例从 ADC 码值出发、显式写出 code↔二次值互逆换算(dim_code vs apply), 折算点被旁路或量纲再错位断言立刻翻转(M4 判据⑥「不该动作时不动作」) - 合成 ROM 覆写(#undef K_Q16 宏)模拟卡 12 标定后板级口径,走 adc_cal_set 正规路径置 VALID;b=-30 码全链对消进 rms 断言 - 38/38:基线静默(含 OL 低定值陷阱)、反错配对照(raw 码值灌环复现历史事故 必假动作 vs 经折算必静默)、OC1/2/3+OL+OV+UV+3U0 七类逐一:越限定值→ 受控启动拍→dly-2 不动作/+5 动作→返回系数带内保持→跌破释放、双件聚合位图 独立性(撤 IA 只回 OC1) 测试与注册:prot-dim-unit-test 钩子 + TC-HOST-PROTDIM 族(游标 010,B 层口径 同 ADCHEALTH/ADCCAL 先例);无新 MCU 源文件(uvprojx/SIM_EXEMPT 零改动) gate:@build 0 错 0 警(Code=215640 RO=21388 RW=1220 ZI=131980 vs 基线 215440/19780/1220/131980 → Flash +1808 B、RAM 零增量);protectTask 静态最坏 链 872 B/margin 1176 B(57%)PASS,adcTask 不变;staged 门禁除 mem-numbers/ mem-budget(台账漂移,回填归 lead)外全绿: gate: only mem-budget/mem-numbers pending lead ledger backfill BOM/CR/U+FFFD/字面量 ASCII 已逐文件自查(本轮未触碰带 BOM 文件)
124 lines
5.3 KiB
C
124 lines
5.3 KiB
C
/*
|
||
* 模块名称:SOE Record — 事件顺序记录编解码(纯逻辑,双端可测)
|
||
* 模块功能:定长 64B SOE(Sequence-of-Events)记录的构建与解析:
|
||
* CP56Time2a 时标 + 记录类型 + 元件号 + 单调序号 + 值 + 校验和。
|
||
* **零 I/O、零 OS 依赖**(仅 stdint/string)→ 主机侧 L0.5 离线单测
|
||
* (落实登记簿 A-4 约束 1"协议/记录与硬件 I/O 分离")。
|
||
* 记录口径(docs/算法/继电保护功能复现规划.md §3.4 L4-4/L4-5,B9):
|
||
* 落盘文件 = /log/soe.log(8.3 合规;FF_USE_LFN=0 约束),定长 64B 一条
|
||
* (照 run.log 先例:count = filesize/64 O(1)、容量满删除重建)。
|
||
* 独立于 run.log 的理由:run.log 是文本记录(时间戳+epoch+UTF-8 描述,
|
||
* syslog_get_record/UI 按文本读),SOE 是二进制结构化记录(时标/类型/
|
||
* 序号/值),混入同一文件会破坏现有文本读者。
|
||
* 记录布局(64B,多字节字段一律小端):
|
||
* [0] 版本 SOE_REC_VER
|
||
* [1] 类型 soe_type_t
|
||
* [2] 元件号(prot_elm_id_t;SOE_ELM_NONE=0xFF = 非元件事件)
|
||
* [3] 标志位(bit7 IV = 记录时时钟无效,CP56 IV 位同步置位)
|
||
* [4..7] 序号 seq(uint32 小端;上电内单调,跨复位重启计数——见 soe_store.h)
|
||
* [8..14] CP56Time2a(7B,IEC 60870-5-4 §5.1.6;秒域时基 → ms 字段恒 0)
|
||
* [15..18] epoch 秒(uint32 小端;IV 时置 0,主机解码交叉校验用)
|
||
* [19..22] 值 value(uint32 小端;语义随类型,见 soe_type_t 注释)
|
||
* [23..62] 保留(恒 0)
|
||
* [63] 校验和 = sum8([0..62])(撕裂/半写检测,解析侧拒绝不匹配)
|
||
* 创建日期:2026-10-12(B9)
|
||
*/
|
||
#ifndef SOE_REC_H
|
||
#define SOE_REC_H
|
||
|
||
#include <stdint.h>
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/* 记录尺寸与版本(定长;改布局必须升 SOE_REC_VER) */
|
||
#define SOE_REC_SIZE 64u
|
||
#define SOE_REC_VER 1u
|
||
|
||
/* 字段偏移(解析/主机解码工具共用口径) */
|
||
#define SOE_OFF_VER 0u
|
||
#define SOE_OFF_TYPE 1u
|
||
#define SOE_OFF_ELM 2u
|
||
#define SOE_OFF_FLAGS 3u
|
||
#define SOE_OFF_SEQ 4u /* 4B */
|
||
#define SOE_OFF_CP56 8u /* 7B */
|
||
#define SOE_OFF_EPOCH 15u /* 4B */
|
||
#define SOE_OFF_VALUE 19u /* 4B */
|
||
#define SOE_OFF_SUM 63u
|
||
|
||
/* 标志位 */
|
||
#define SOE_FLG_IV 0x80u /* bit7:记录时时钟无效(CP56 IV 位同步置位) */
|
||
|
||
/* 非元件事件的元件号 */
|
||
#define SOE_ELM_NONE 0xFFu
|
||
|
||
/*
|
||
* 记录类型(值语义随类型):
|
||
* 1 元件动作 value = 元件状态打包(bit0 asserted / bit1 picked / bit2 enabled)
|
||
* 2 元件返回 value = 同上(返回瞬间的旧状态快照)
|
||
* 3 软压板退出 value = 0
|
||
* 4 软压板投入 value = 1
|
||
* 5 采样闭锁 value = adc_health 闭锁位图(触发时的 hf & mask)
|
||
* 6 采样恢复 value = 0
|
||
*/
|
||
typedef enum {
|
||
SOE_T_ELM_ASSERT = 1u,
|
||
SOE_T_ELM_RETURN,
|
||
SOE_T_PLATE_OUT,
|
||
SOE_T_PLATE_IN,
|
||
SOE_T_SAMPLE_BLOCK,
|
||
SOE_T_SAMPLE_RESUME,
|
||
/* 未标定闭锁(「数据可信」卡 5,2026-10-25 道A 追加):UA/UN/IA 的 VALID
|
||
* 未全置位 → 判据停走;与采样闭锁分型,边沿各留一条记录 */
|
||
SOE_T_CAL_BLOCK,
|
||
SOE_T_CAL_RESUME,
|
||
SOE_T_COUNT /* 哨兵值,非有效类型 */
|
||
} soe_type_t;
|
||
|
||
/* 解析产物(字段原样拷贝;CP56 不在此层换算,主机工具解码) */
|
||
typedef struct {
|
||
uint8_t ver;
|
||
uint8_t type;
|
||
uint8_t elm_id;
|
||
uint8_t flags;
|
||
uint32_t seq;
|
||
uint8_t cp56[7];
|
||
uint32_t epoch_s;
|
||
uint32_t value;
|
||
} soe_rec_t;
|
||
|
||
/*
|
||
* 函数功能:构建一条 64B SOE 记录(纯计算,无 I/O;任意上下文可调)
|
||
* 入口参数:rec - 输出缓冲(SOE_REC_SIZE 字节,不可为 NULL) uint8_t *
|
||
* type - 记录类型 soe_type_t(越界按 SOE_T_COUNT 处理为保留 0)
|
||
* elm_id - 元件号(非元件事件传 SOE_ELM_NONE) uint8_t
|
||
* flags - 标志位(SOE_FLG_IV = 时钟无效) uint8_t
|
||
* seq - 单调序号 uint32_t
|
||
* epoch_s - 墙钟 epoch 秒(IV 时传 0;同时 flags 须带 SOE_FLG_IV)
|
||
* value - 类型相关值 uint32_t
|
||
* 返回值:无
|
||
* 函数说明:epoch_s → CP56Time2a(UTC 分解,Hinnant civil 日历算法,与
|
||
* iec104_asdu.c 同一算法族;钳位 [2000-01-01, 2127-12-31],
|
||
* ms 字段恒 0——sys_clock 秒域时基,如实登记)。
|
||
* flags 带 IV 时 CP56 byte2 bit7 置位(标准"时间无效"语义)。
|
||
*/
|
||
void soe_rec_build(uint8_t *rec, uint8_t type, uint8_t elm_id, uint8_t flags,
|
||
uint32_t seq, uint32_t epoch_s, uint32_t value);
|
||
|
||
/*
|
||
* 函数功能:解析一条 64B SOE 记录(校验版本 + 校验和)
|
||
* 入口参数:rec - 原始记录(SOE_REC_SIZE 字节,不可为 NULL) const uint8_t *
|
||
* out - 解析输出(不可为 NULL) soe_rec_t *
|
||
* 返回值:0 成功 / -1 参数错 / -2 版本不符 / -3 校验和不符(撕裂/半写) int
|
||
* 函数说明:只读,不改动 rec。类型/标志不做强校验(前向兼容:新版本类型
|
||
* 旧解析器可读),版本与校验和是硬门槛。
|
||
*/
|
||
int soe_rec_parse(const uint8_t *rec, soe_rec_t *out);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* SOE_REC_H */
|