- twin_layout_blob_sized generalized: multi-entry TwinCAT line format (1 real @240bit + N continuation + remainder entry); 1024B path kept byte-identical; 800B = 27 entries verified on hardware - 800B constants (PAYLOAD/SM 800), deployed as el6695_rt_800b - 10-min + 5h stability runs: 18M cycles, zero errors, zero mismatches, PLC nMismatch frozen over the whole run (monitor_5h.csv evidence) - docs: 800B plan/design/verification/test-report chapters, jitter analysis (NFS rootfs stall primary cause), D2000 dev plan - scripts: 800B deploy/relink/verify, mismatch-delta, 5h monitor
7.7 KiB
EL6695 8B 双向通讯 — 验证说明文档
版本: 1.1(新增 §7 800B 验证) 日期: 2026-07-27 配套文档:
8b-bridge-design.md(设计)、8b-test-report.md(测试记录)
1. 验证目标
证明 TwinCAT PC 与 J1900 之间经 EL6695 桥接的 8 字节过程数据通道满足:
- 双向连通: TwinCAT → J1900、J1900 → TwinCAT 两个方向都通;
- 每字节有效: 8 个字节中的每一个都真实参与传输,而非只有个别字节(如计数器低位)在动;
- 经过软件处理: 回传数据确实经过 J1900 用户态程序的读-算-写,不是硬件环回或透传;
- 持续稳定: 连续运行无失配、无陈旧数据、无传输错误。
2. 为什么朴素方案不足以证明
2.1 失败案例: ULINT 计数器(8B 初版)
最初的 8B 设计直接把 nCycles(ULINT, 小端)拷入 aOut1[0..7],J1900 计算 f(x)=x*7+3 写回。该方案的问题:
| 字节 | 内容 | 变化频率 |
|---|---|---|
| 0 | nCycles 低字节 | 每周期 |
| 1 | 每 256 周期 | |
| 2 | 每 65536 周期 | |
| 3 | 每 1677 万周期(≈4.6 小时) | |
| 4–7 | 恒为 0 | 从不变化 |
结论:这种证据只能证明低 2~3 字节在传输,无法排除"高字节根本没被映射"的可能。用户指出的"不要只改变一个字节就说成功了"正是针对此类证据。
2.2 验证设计必须满足的性质
- 8 个字节互不相同(避免字节间串扰被掩盖);
- 8 个字节每周期全部变化(任何一字节断传都会立即表现为失配);
- 回传是逐字节独立的非平凡变换(证明每字节都被对端软件读取并处理);
- 校验容忍桥接管线延迟(不能假设固定的往返周期数)。
3. 验证协议原理
3.1 发送图案(TwinCAT 侧, 1 kHz)
aOut1[i] = (nCycles + i·32) mod 256, i = 0..7
性质:
- 步进 32、模 256:8 个值在同一周期内互不重叠;
- 每周期整体 +1:8 字节全部随周期变化;
- 以 256 为周期循环:任意 16 个连续 PLC 周期的 8 字节组两两不同(因为 16 < 256),这保证了历史环匹配不会出现跨周期误判。
3.2 J1900 变换
tx[i] = rx[i] XOR 0x5A, i = 0..7
- 逐字节独立: 第 i 字节的输出只依赖第 i 字节的输入 → 每个字节单独构成一条可检验的证据链;
- 软件才能产生: XOR 0x5A 不是硬件环回会出现的结果,证明数据进入了 J1900 用户态程序并被改写;
- 可逆: TwinCAT 侧用同一常数 XOR 即可还原比较。
3.3 历史环匹配(TwinCAT 侧)
桥接存在约 4 个 PLC 周期的管线延迟(TwinCAT 输出帧 → J1900 处理 → TwinCAT 输入帧)。因此不能用"aIn1 对应当前周期 aOut1"校验。
PLC 每周期把刚发送的 8 字节存入 16 槽历史环:
hW = nCycles mod 16
aHist[hW, 0..7] = aOut1[0..7]
校验时与全部 16 个历史槽做整组比较:
bSync = TRUE ⟺ ∃h: ∀i∈[0,7]: (aIn1[i] XOR 0x5A) = aHist[h, i]
nMatchLag = (hW − h + 16) mod 16
- 整组匹配: 只有 8 个字节同时等于某一历史周期发送值时才判真 — 任何一个字节出错都会导致失配;
- 延迟自测量: 匹配槽位直接给出往返延迟
nMatchLag,无需预设。
3.4 判读标准
| 判据 | 通过条件 | 实测 |
|---|---|---|
bSync |
持续 TRUE | ✅ |
nMatchLag |
稳定小值(< 16) | ✅ 恒为 4 |
nMismatch |
数据流建立后零增长 | ✅ 24s 窗口内不变 |
J1900 stale |
0% | ✅ |
J1900 tx_err/rx_err |
0 | ✅ |
4. 观测方法与时差说明
4.1 权威判据 vs 采样展示
- 权威判据: PLC 内部 1 kHz 实时执行的
bSync/nMismatch,数据在同一任务周期内一致采样; - 采样展示: ADS 读
aOut1/aIn1/nCycles是分多次请求完成的,彼此相差可达数毫秒。
因此 ADS 采样中 aIn1 XOR 0x5A 的 byte0 偶尔差 ±1(byte0 每周期变化,而 aOut1 与 aIn1 的快照时刻不同),例如:
aOut1(sent) = 3B-5B-7B-9B-BB-DB-FB-1B
aIn1^5A = 3A-5A-7A-9A-BA-DA-FA-1A ← byte0 差 1,其余 7 字节全等
这是观测时差,不是传输错误。当 ADS 两次读落在同一毫秒时,8 字节完全一致:
aOut1(sent) = 98-B8-D8-F8-18-38-58-78
aIn1^5A = 98-B8-D8-F8-18-38-58-78 ← 8/8 全等
4.2 逐字节验证示例(实测样本)
| 字节 i | 设计公式 | 发送 aOut1 | 接收 aIn1 | aIn1^0x5A | 判定 |
|---|---|---|---|---|---|
| 0 | (n+0)·1 | 98 |
C2 |
98 |
✓ |
| 1 | n+32 | B8 |
E2 |
B8 |
✓ |
| 2 | n+64 | D8 |
82 |
D8 |
✓ |
| 3 | n+96 | F8 |
A2 |
F8 |
✓ |
| 4 | n+128 | 18 |
42 |
18 |
✓ |
| 5 | n+160 | 38 |
62 |
38 |
✓ |
| 6 | n+192 | 58 |
02 |
58 |
✓ |
| 7 | n+224 | 78 |
22 |
78 |
✓ |
5. 验证覆盖矩阵
| 验证点 | 方法 | 覆盖 |
|---|---|---|
| TwinCAT→J1900 方向 | J1900 rx_buf 非零统计 + PLC 图案被 J1900 正确还原(能 XOR 回去) | ✅ |
| J1900→TwinCAT 方向 | aIn1 与历史环整组匹配 | ✅ |
| 字节 0..7 逐一 | 每字节独立图案 + 独立 XOR | ✅ |
| 软件处理证明 | XOR 0x5A 仅 J1900 用户态可产生 | ✅ |
| 桥接延迟 | nMatchLag 自测量(4 周期) | ✅ |
| 稳定性 | nMismatch 零增长、stale=0%、err=0 | ✅ |
| TwinCAT 配置持久性 | 激活后 _Boot tszip 中 SM2/SM3 记录检查 | ✅ |
6. 已知局限
- 验证图案为周期性确定图案,未做随机负载压力测试;
lag=4为当前拓扑/周期下的实测值,未验证不同任务周期下的行为;- 8B 配置不含诊断 PDO,"对端是否在线"需以数据流本身判断(失配即掉线)。
7. 800B 变体的验证方法
800B 工程采用序列号 + 图案 + 反推校验协议(类 1KB),与 8B 的 XOR 历史环不同,原因是 800B 要同时验证"大载荷每个字节"与"序号处理"两个维度。
7.1 协议与验证链
TwinCAT 发送: aOut1[0..7] = nCycles; aOut1[i] = (nCycles+i) mod 256
(i ∈ [16..263] ∪ [280..799], 避开 [264..279] 统计字段)
J1900 处理: tx[0..7] = rx_seq*7+3; tx[8..15] = 本地周期号;
tx[264..279] = 抖动/失配/原始 seq; 其余字节原样回显
TwinCAT 校验: nProcessedSeq = aIn1[0..7]
nReturnedSeq = (nProcessedSeq - 3) / 7 (MOD 7 = 0 才有效)
逐字节比对 aIn1[i] == (nReturnedSeq + i) mod 256
- 反推校验:J1900 的 f(x)=x·7+3 可逆,PLC 从回传值反推原始发送周期,无需预设管线延迟(实测 lag=4);
- J1900 侧自检:ticker 对图案区 [16..255] 做
(tc_seq+i) mod 256独立校验(mism计数),与 PLC 侧校验互为对侧证据。
7.2 与 8B 方法的取舍
| 维度 | 8B(XOR 历史环) | 800B(seq+图案反推) |
|---|---|---|
| 每字节独立性 | 强(每字节独立 XOR) | 中(图案含周期序号,错位立现) |
| 延迟测量 | 直接(nMatchLag) | 直接(nCycles − nReturnedSeq) |
| 大载荷成本 | 历史环 16×8B 比对/周期 | 768 字节比对/周期 |
| 适合 | 小载荷通路证明 | 应用级带宽验证 |
7.3 ADS 快照判读(800B 特有)
外部 ADS 校验脚本用 nReturnedSeq 重建预期图案时,因 nCycles/nReturnedSeq/aIn1 分次读取,可能出现 nReturnedSeq > nCycles(显示 lag 为负)与全图案"失配"的假象——以 PLC 内部 1kHz 实时计算的 bSync 为唯一权威判据;ADS 全数组读取仅用于非零覆盖率统计(800B 时应 ≈770+/800)。
7.4 800B 稳定性判据
| 判据 | 通过条件 | 实测 |
|---|---|---|
| J1900 周期完整 | 周期数 = 时长 × 频率 | 600000 / 600.0s ✅ |
J1900 mism |
0 | ✅ |
PLC nMismatch |
运行窗口内零增长 | 295s 窗口 delta=0;90s 确认 delta=0 ✅ |
| 传输错误 | tx/rx = 0 | ✅ |
| 非零覆盖率 | ≈770/800 | 775–776 ✅ |