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:
@@ -20,6 +20,7 @@
|
||||
/* ---------------- 类型标识(DL/T 634.5104,仅定义本期子集) ---------------- */
|
||||
#define IEC104_T_M_SP_NA_1 1U /* 单点遥信 SIQ */
|
||||
#define IEC104_T_M_DP_NA_1 3U /* 双点遥信 DIQ */
|
||||
#define IEC104_T_M_SP_TB_1 30U /* 单点遥信+CP56时标 SIQ+7B(B9 SOE 自发) */
|
||||
#define IEC104_T_M_ME_NC_1 13U /* 遥测短浮点 float+QDS(§1.5 口径) */
|
||||
#define IEC104_T_C_SE_NC_1 50U /* 定值写(短浮点)float+QDS */
|
||||
#define IEC104_T_C_DC_NA_1 52U /* 双点遥控 QDC(82H 选 / 02H 执行) */
|
||||
|
||||
@@ -270,11 +270,18 @@ static int s_scan_step(iec104_link_t *lk, uint8_t *budget, uint8_t periodic) {
|
||||
|
||||
/*
|
||||
* 函数功能:突发(COV)上送——pend 暂存逐点 SQ=0 COT=3,发成功才清位
|
||||
* 函数说明:单点遥信(idx≥4)自发用 **M_SP_TB_1**(SIQ + CP56Time2a,B9:
|
||||
* 变位带时标 = SOE 上送路径);双点(idx<4,V0.1 恒 IV)保持
|
||||
* M_DP_NA_1;总召/周期扫描仍走 s_scan_step 的 M_SP_NA_1/M_DP_NA_1
|
||||
* (时标只用于自发,标准语义——防"全量换型")。
|
||||
* 时标 = cfg->epoch_ms(ctx);NULL/UINT64_MAX → CP56 IV 位如实置位。
|
||||
*/
|
||||
static void s_spont_step(iec104_link_t *lk, uint8_t *budget) {
|
||||
uint8_t body[5];
|
||||
uint8_t body[8]; /* 最大 = SIQ + CP56(7)(M_SP_TB_1) */
|
||||
uint8_t i;
|
||||
uint8_t d;
|
||||
uint8_t blen;
|
||||
uint8_t type;
|
||||
int rc;
|
||||
|
||||
while ((*budget > 0u) && ((lk->pend_yx != 0u) || (lk->pend_yc != 0u))) {
|
||||
@@ -288,11 +295,24 @@ static void s_spont_step(iec104_link_t *lk, uint8_t *budget) {
|
||||
}
|
||||
iec104_pts_yx_read(i, &d);
|
||||
body[0] = d;
|
||||
rc = s_send_asdu(lk,
|
||||
(i < 4u) ? IEC104_T_M_DP_NA_1
|
||||
: IEC104_T_M_SP_NA_1,
|
||||
1u, IEC104_COT_SPONT, 0u, 1u,
|
||||
(uint32_t)i + 1u, body, 1u, 0u);
|
||||
blen = 1u;
|
||||
if (i < 4u) {
|
||||
type = (uint8_t)IEC104_T_M_DP_NA_1;
|
||||
} else {
|
||||
uint64_t ems = (lk->cfg->epoch_ms != NULL)
|
||||
? lk->cfg->epoch_ms(lk->ctx)
|
||||
: UINT64_MAX;
|
||||
|
||||
type = (uint8_t)IEC104_T_M_SP_TB_1;
|
||||
(void)iec104_epoch_ms_to_cp56((ems == UINT64_MAX) ? 0u : ems,
|
||||
&body[1]);
|
||||
if (ems == UINT64_MAX) {
|
||||
body[1 + 2] |= 0x80u; /* CP56 byte2 bit7 IV:时钟无效如实上送 */
|
||||
}
|
||||
blen = 8u;
|
||||
}
|
||||
rc = s_send_asdu(lk, type, 1u, IEC104_COT_SPONT, 0u, 1u,
|
||||
(uint32_t)i + 1u, body, blen, 0u);
|
||||
if (rc != 0) {
|
||||
return; /* k 窗满:pend 位保留,下次续发 */
|
||||
}
|
||||
|
||||
@@ -56,6 +56,10 @@ typedef struct {
|
||||
void (*send_apdu)(void *ctx, const uint8_t *apdu, uint16_t len);
|
||||
/* C_CS 时钟同步:epoch 毫秒;NULL 或返回 -1 → 否定确认 */
|
||||
int (*clock_sync)(void *ctx, uint64_t epoch_ms);
|
||||
/* 时标源(B9):当前 epoch 毫秒(M_SP_TB_1 自发用)。
|
||||
* NULL 或返回 UINT64_MAX = 时钟无效 → CP56 IV 位如实置位。
|
||||
* 纯读(sys_clock 推算),不得阻塞、不得有副作用。 */
|
||||
uint64_t (*epoch_ms)(void *ctx);
|
||||
} iec104_link_cfg_t;
|
||||
|
||||
/* 链路实例(胶水层静态持有,零堆) */
|
||||
|
||||
Reference in New Issue
Block a user