feat(soe): B9 动作记录 + 时标 SOE(L4-4/L4-5)+ 104 M_SP_TB_1 自发
- 新增 App/log/soe_rec.{c,h}:64B 定长 SOE 记录纯编解码(CP56Time2a
时标 + 类型 + 元件号 + 单调序号 + 值 + sum8 撕裂校验),零 I/O 零 OS
依赖,主机 L0.5 覆盖(32 断言,含与 iec104 CP56 解码器交叉互证)
- 新增 App/log/soe_store.{c,h}:protectTask 边沿投递(取时标 + 组记录 +
SPSC 待发环/消息队列,零文件系统);defaultTask 经 syslog_drain 尾部
排空落 /log/soe.log(卷锁 try / FA_WRITE|FA_OPEN_APPEND / 校验字节数 /
容量满 unlink 重建,全套照 run.log 实证纪律;无卷损坏归类路径)
- protect_task.c:元件动作/返回、软压板投退、采样闭锁/恢复六类边沿
→ soe_store_post;post 内禁 DBG_*(protect 静态最坏链 872 B 不变,
改前/改后 stack_report 九任务逐字节一致),丢弃留痕挪 drain 侧
- iec104:单点 YX 自发改 M_SP_TB_1(30) 带 CP56 时标(总召/周期保持
M_SP_NA_1,单测两种都断言);link cfg 新增 epoch_ms 时标源回调
(NULL/无效 → IV 位如实置位);serv 绑 sys_clock(秒域时基,
ms 域 = 秒×1000,不造假亚秒)
- 主机单测:test/host/soe/(32 断言)+ iec104 94→97(TB 时标/IV);
iec104_master.py 解析 type 30(B6/B7 流不回归);decode_soe.py
台架解码断言工具(seq 单调/校验和/UTC 交叉)
- 注册:uvprojx + check_registration SIM_EXEMPT 点名(MCU-only 胶水)
- 文档(我方属主区):`App/log/README.md` 增 soe 节(64B 记录/单写者/
post 禁 DBG/UTC 交叉坑);`docs/子系统设计/IEC104上行设计说明.md`
§1 范围行 + §3.2 时标注 + §7 台架行 + §8 第 2 条销项 + 变更记录行
台架腿(bench 锁 B9,release --bench-pass):run_boot_test PASS;
--b7-pre 21/21、--b7-post 13/13(B6/B7 回归 + 确定性动作边沿);
自发 YX 上送 M_SP_TB_1 带 ts(11:00:51 动作 / 11:00:53 复归);
FTP 下载 /log/soe.log 30 条记录 decode PASS(seq 0..28 单调、
ELM_ASSERT 14 条、UTC 交叉一致);定值/压板已恢复默认。
台账 +1088 B(SPSC 环 512 + 静态 FIL 528 + 计数器)随合并由 Lead
回填(ram_baseline --write + check_mem_numbers --write)。
gate: only mem-budget/mem-numbers pending lead ledger backfill
(pre-commit --all-files: 29 Passed / 2 Failed / 0 Skipped;
hygiene self-check OK: no BOM/CRLF/mojibake/trailws/non-ASCII literal)
sync 追平 v2-on-ui(B8 freq + N33 抬栈)后复跑:@build 0/0
(Code=209492 RW=1104 ZI=154184);stack_report 九任务全 PASS、
protectTask 872 B/57% 不变;ci_local L0.5 15 runner 951/951
(freq 46 / soe 32 / iec104 97 / prot_set 90 / prot_elm 47)。
顺带修 protect_task.c 陈旧注释:定值巡检 31 项 → 40 项(B8 后)。
This commit is contained in:
@@ -125,9 +125,16 @@ static int f_clock(void *ctx, uint64_t ms)
|
||||
s_clock_ms = ms;
|
||||
return s_clock_rc;
|
||||
}
|
||||
/* B9 时标源假回调:s_epoch_val = UINT64_MAX → 时钟无效(CP56 IV) */
|
||||
static uint64_t s_epoch_val;
|
||||
static uint64_t f_epoch(void *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
return s_epoch_val;
|
||||
}
|
||||
|
||||
static iec104_link_t g_lk;
|
||||
static const iec104_link_cfg_t g_cfg = { 1u, cap_send, f_clock };
|
||||
static const iec104_link_cfg_t g_cfg = { 1u, cap_send, f_clock, f_epoch };
|
||||
|
||||
/* ---------------- 主站侧模拟(N(R) 单调,照真实主站) ---------------- */
|
||||
static uint16_t m_ns;
|
||||
@@ -204,6 +211,7 @@ static void reset_all(uint32_t now)
|
||||
| (1uLL << 22) | (1uLL << 30);
|
||||
s_clock_rc = 0;
|
||||
s_clock_ms = 0u;
|
||||
s_epoch_val = 1760234567000ULL; /* B9:固定时标(2025-10-12 UTC) */
|
||||
iec104_link_init(&g_lk, &g_cfg, NULL);
|
||||
iec104_link_open(&g_lk, now);
|
||||
m_reset();
|
||||
@@ -460,6 +468,7 @@ static void tc_cov_yx(void)
|
||||
{
|
||||
uint32_t now = 1000u;
|
||||
cap_t c;
|
||||
uint64_t back;
|
||||
|
||||
reset_all(now);
|
||||
handshake(now);
|
||||
@@ -467,16 +476,30 @@ static void tc_cov_yx(void)
|
||||
CHECK(cap_i_count() == 0, "TC-007 首 poll 无自发");
|
||||
s_f_bits |= (1uLL << 15); /* YX16(idx15)动作 */
|
||||
iec104_link_poll(&g_lk, now + 100u);
|
||||
CHECK((cap_i_count() == 1) && (cap_i(0, &c) == 0) && (c.type == 1u)
|
||||
/* B9:单点 YX 自发 = M_SP_TB_1(30)带 CP56Time2a 时标(SOE 上送路径) */
|
||||
CHECK((cap_i_count() == 1) && (cap_i(0, &c) == 0) && (c.type == 30u)
|
||||
&& (c.cot == IEC104_COT_SPONT) && (c.ioa == 16u)
|
||||
&& (c.obj_len == 1u) && (c.obj[0] == 1u), "TC-007 YX16 变位 COT3");
|
||||
&& (c.obj_len == 8u) && (c.obj[0] == 1u), "TC-007 YX16 变位 COT3 TB");
|
||||
if ((cap_i(0, &c) == 0) && (c.obj_len == 8u)) {
|
||||
CHECK(iec104_cp56_to_epoch_ms(&c.obj[1], &back) == 0,
|
||||
"TC-007 CP56 可解");
|
||||
CHECK(back == s_epoch_val, "TC-007 时标 = epoch_ms 源");
|
||||
}
|
||||
s_f_bits &= ~(1uLL << 15); /* 复归 */
|
||||
iec104_link_poll(&g_lk, now + 200u);
|
||||
CHECK((cap_i_count() == 2) && (cap_i(1, &c) == 0) && (c.ioa == 16u)
|
||||
&& (c.obj[0] == 0u), "TC-007 YX16 复归再变");
|
||||
s_f_bits |= (1uLL << 0); /* idx0 无效位 → 不触发 */
|
||||
CHECK((cap_i_count() == 2) && (cap_i(1, &c) == 0) && (c.type == 30u)
|
||||
&& (c.ioa == 16u) && (c.obj[0] == 0u), "TC-007 YX16 复归再变");
|
||||
/* B9 IV 路径:时标源无效 → CP56 IV 位如实置位 */
|
||||
s_epoch_val = UINT64_MAX;
|
||||
s_f_bits |= (1uLL << 16); /* YX17(idx16)动作 */
|
||||
iec104_link_poll(&g_lk, now + 300u);
|
||||
CHECK(cap_i_count() == 2, "TC-007 无效位变位不触发");
|
||||
CHECK((cap_i_count() == 3) && (cap_i(2, &c) == 0) && (c.type == 30u)
|
||||
&& (c.ioa == 17u) && ((c.obj[3] & 0x80u) != 0u),
|
||||
"TC-007 时钟无效 → CP56 IV 位");
|
||||
s_epoch_val = 1760234567000ULL;
|
||||
s_f_bits |= (1uLL << 0); /* idx0 无效位 → 不触发 */
|
||||
iec104_link_poll(&g_lk, now + 400u);
|
||||
CHECK(cap_i_count() == 3, "TC-007 无效位变位不触发");
|
||||
}
|
||||
|
||||
static void tc_cov_yc(void)
|
||||
|
||||
Reference in New Issue
Block a user