ethercat-linux/docs/8b-verification-methodology.md

154 lines
5.6 KiB
Markdown
Raw Normal View History

# EL6695 8B 双向通讯 — 验证说明文档
> **版本**: 1.0
> **日期**: 2026-07-27
> **配套文档**: `8b-bridge-design.md`(设计)、`8b-test-report.md`(测试记录)
---
## 1. 验证目标
证明 TwinCAT PC 与 J1900 之间经 EL6695 桥接的 **8 字节过程数据通道**满足:
1. **双向连通**: TwinCAT → J1900、J1900 → TwinCAT 两个方向都通;
2. **每字节有效**: 8 个字节中的**每一个**都真实参与传输,而非只有个别字节(如计数器低位)在动;
3. **经过软件处理**: 回传数据确实经过 J1900 用户态程序的读-算-写,不是硬件环回或透传;
4. **持续稳定**: 连续运行无失配、无陈旧数据、无传输错误。
---
## 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 小时) |
| 47 | 恒为 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. 已知局限
1. 验证图案为周期性确定图案,未做随机负载压力测试;
2. `lag=4` 为当前拓扑/周期下的实测值,未验证不同任务周期下的行为;
3. 8B 配置不含诊断 PDO,"对端是否在线"需以数据流本身判断(失配即掉线)。