ethercat-linux/docs/rt-link-verification-report.md

288 lines
15 KiB
Markdown
Raw Permalink Normal View History

# TwinCAT ↔ J1900 实时数据通讯验证报告EL6695 桥接)
> **版本**: 1.0
> **日期**: 2026-08-12
> **结论**: ✅ 全部通过4kHz 3 小时 soak 零错误8kHz RTT min 0.75ms / mean 1.04ms
> **关联文档**: `8b-bridge-design.md`、`8b-verification-methodology.md`、`500us-latency-plan.md`、`jitter-analysis.md`
---
## 1. 摘要
本报告覆盖 TwinCAT PC 与 J1900 嵌入式平台之间经 EL6695 EtherCAT 桥接的实时数据通讯验证,
包括数据完整性、长期稳定性、周期扩展1kHz→8kHz、双侧 DC-Synchron、RTT 延迟优化与
断电恢复能力。
**核心结果**
| 验证项 | 结果 |
|---|---|
| 数据完整性800B 载荷,双向交叉校验) | 3 小时 4537 万周期零错误 |
| 长期稳定性4kHz soak 11400s | bSync=True ×190 采样点nMismatch delta=0 |
| J1900 侧自校验 | 33.6M 帧 payload mismatch=0tx/rx err=0 |
| RTT8kHz + tx_rx RT 提权) | min 0.75ms / mean 1.04ms / max 1.38ms |
| 单向延迟(推导) | 典型 0.30.5ms,最坏 ~0.6ms |
| 死链路检测 | lag 指标 + bSync 双重敏感(实测 5 秒内可检出) |
| DC-Synchron双侧 | 从站侧固件 sync_mode=2 接受180s 同步计数器全零 |
| 断电恢复 | TwinCAT 自恢复 RunJ1900 重建 /tmp 后 <2 分钟恢复全链路 |
---
## 2. 系统架构与测试环境
### 2.1 硬件拓扑
```
TwinCAT PC (Windows, TwinCAT 3.1.4026.24)
└─ EtherCAT 主站网卡 "以太网 2" (TwinCAT-Intel PCI, MAC 00-15-17-8A-B3-DA)
└─ EK1100 → EL2202 → EL1252 → EL2262 → EL2008 → EL6851-0010 → EL6022
→ EL6695 (桥接端子, 主站侧 X2)
└─ EL6695 从站侧 X1 ←直连→ J1900 eth1
J1900 (Linux 6.6.135-rt74 PREEMPT_RT, Celeron J1900 4 核)
```
| 项 | 值 |
|---|---|
| TwinCAT AmsNetId | `169.254.176.217.1.1` |
| J1900 管理 IP | `192.168.68.100`DHCP曾漂移至 .101MAC `00:e2:69:34:71:2c` |
| SSH 跳板 | `tonycao@192.168.58.8` |
| EL6695 从站侧站址 | `0x1000` |
| J1900 内核 | 6.6.135-rt74PREEMPT_RTio_uring 可用) |
### 2.2 软件与工程
| 项 | 位置 |
|---|---|
| TwinCAT 工程800B 变体) | `C:\Users\tonycao\work\twincat3-auto-cli\TwinCAT_EL6695_Primary_800B\` |
| J1900 源码 | `C:\Users\tonycao\work\ethercat-linux`Rustethercrab 0.7 本地 patch |
| 构建目标 | `x86_64-unknown-linux-musl`(静态链接,零运行时依赖) |
| 关键 commits | `f0163d8`(800B) → `aabfe31`(DC-Synchron) → `cdb90c3`(800B 异步 FPWR) → `253f4b3`(J1900 DC) → `4083df0`(8kHz+RT 提权) |
| 配置备份 | tsproj `.bak-1k-dc` / `.bak-4k`TcTTO `.bak-1k` / `.bak-4k` |
### 2.3 载荷布局800B
| 偏移 | 内容 | 方向 |
|---|---|---|
| `[0..7]` | 序列号PLC 写 `tc_seq=nCycles`J1900 回写 `f(tc_seq)=tc_seq*7+3` | 双向 |
| `[8..15]` | J1900 本地周期计数 | 上行 |
| `[16..799]` | 图案区:`(seq + i) mod 256`J1900 原样回传) | 双向 |
| `[264..267]` | J1900 周期抖动 i32统计区不参与校验 | 上行 |
| `[268..271]` | J1900 payload mismatch 计数 | 上行 |
| `[272..279]` | 原始 tc_seq 保留(供 PLC 交叉验证) | 上行 |
---
## 3. 验证方法学
### 3.1 数据完整性证明链
单向"收到数据"不能证明通讯正确。本方案用**双向交叉校验 + 数学变换**构成闭环证明:
1. **PLC 侧写入**`aOut1[i] = (nCycles + i) mod 256`(图案区),`aOut1[0..7] = tc_seq`
2. **J1900 侧处理**(证明"读取+计算+写回"三个动作真实发生):
- 校验收到图案 `[16..256)``tc_seq` 一致(不一致计入 `payload_mismatch`
- 对序列号做不可由硬件桥接伪造的数学变换:`f(x) = x*7 + 3`
- 回写 `aIn1[0..7] = f(tc_seq)`,图案区原样回传,`[272..279]` 保留原始 tc_seq
3. **PLC 侧验证**
-`aIn1[0..7]` 反解 `nReturnedSeq = (x-3)/7`(整除性本身是一道校验)
- `bSync := 全部 aIn1[i] == (nReturnedSeq + i) mod 256`768 字节逐字节)
**设计要点**
- `f(x)=7x+3` 保证回传数据不可能由桥接端子透传/环回伪造
-`nReturnedSeq`(回传帧自带的序号)而非本地 `nCycles` 做图案比对,
使校验对传输滞后免疫——校验的是"回传帧内部自洽性"
- J1900 侧独立再做一遍正向校验,两侧互为佐证
### 3.2 新鲜度liveness证明
自洽性校验的盲区:回传通道冻结时数据仍自洽。对策:
- **`nMatchLag = nCycles - nReturnedSeq`**PLC 内每周期原子计算):
回传帧的产生时刻距当前的周期数。通道健康时稳定在小范围;
通道死亡时以任务频率无界增长
- **实测死链路响应**:杀掉 J1900 ticker 后 5 秒内 lag 从 6 → 8.1 亿且以 4000/s 增长,
bSync 同步翻 FalseEL6695 从站侧失联使输入映像清零)
- **反向验证**:重启 ticker 后 lag 立即回落至 46 周期
### 3.3 方法学盲区(如实声明)
| 盲区 | 说明 | 缓解 |
|---|---|---|
| 桥转发冻结而两侧 ESC 保持 OP | aIn1 冻结时自洽校验仍通过,任何黑盒测试无法检出 | 概率极低;需侵入式手段 |
| J1900 侧图案校验仅覆盖 `[16..256)`240/800 字节) | PLC 侧覆盖 768 字节,互补 | 可扩大 J1900 校验范围 |
| J1900 处理帧率低于发送帧率(设计性跳帧) | echo 恒为最新帧lag 指标证明),无陈旧累积 | 见 5.4 |
---
## 4. 指标详解
### 4.1 PLC 侧GVL_SyncADS 可读)
| 指标 | 类型 | 定义 | 意义与解读 |
|---|---|---|---|
| `nCycles` | ULINT | PLC 任务周期计数 | 任务存活与速率基准;速率 = Δ/Δt偏离任务频率即异常 |
| `bSync` | BOOL | 当前周期 768 字节图案全部匹配 | **瞬时**正确性。单次 False 可能是瞬态;持续 False = 链路/配置故障 |
| `nMismatch` | DINT | 累计失配字节数(仅 diff>0 时累加) | **历史**错误总量。soak 中看 delta=0注意 int32错误率 3M/s 时约 11 分钟回绕 |
| `nReturnedSeq` | ULINT | 回传帧携带的原始序号(反解后) | 回传链路的"时间戳";与 nCycles 之差即 lag |
| `nMatchLag` | DINT | `nCycles - nReturnedSeq`,每周期原子更新 | **新鲜度核心指标**:回传 RTT 的周期数表示。健康值=小范围稳定;无界增长=回传通道死 |
**ADS 采样注意**`nCycles` 与 `nReturnedSeq` 分两次读取会产生撕裂(高速任务下可读出负 lag 假象);
必须直接读原子计算的 `nMatchLag`
### 4.2 J1900 侧ticker S 行遥测)
| 字段 | 定义 | 异常含义 |
|---|---|---|
| `cyc` | J1900 处理循环计数 | 速率 = 实际处理能力上限的度量 |
| `raw` / `proc` | 收到的 tc_seq / 回写的 f(tc_seq) | 与 PLC 侧 nCycles 对账,验证双向一致 |
| `txe` / `rxe` | FPWR/FPRD 事务错误 | 持续增长 = 链路劣化或 ESC 掉态 |
| `late` | 异步 FPWR 响应未在下一周期收齐的次数 | 少量(<0.1%正常暴涨 = 总线拥塞或 RT 调度劣化 |
| `stale` | tc_seq 未变化(读到旧帧)占比 | spin 模式下少量正常跳帧100% = TwinCAT 侧停发 |
| `mono` | tc_seq 回退次数 | 非零 = 帧乱序/映像撕裂,严重异常 |
| `cerr` | J1900 内部计算自洽错误 | 必须恒为 0软件自检 |
| `mism` | J1900 侧图案失配累计 | 必须冻结delta=0 |
| `dcph` | EL6695 从站侧 DC 系统时间 mod 周期 | DC 时钟相位观测 |
| `dcdr` | DC 时钟相对 CLOCK_MONOTONIC 的累计漂移 | 无持续漂移补偿时有界 wander实测 ±几十 ppm |
### 4.3 时延类统计OnlineStats结束报告
| 统计 | 定义 | 实测3h soak, 4kHz spin |
|---|---|---|
| `exec_time` | 单周期处理耗时(读→变换→写就绪) | p50=25µs, p99=44µs, max=300µs |
| `period_jitter` | spin 循环相邻 fresh 检测的间隔偏差 | p50=12µs, mean=88µs受跳帧节奏支配非调度抖动 |
| `fprd_rtt` / `fpwr_rtt` | 单次事务往返 | 800B FPRD ≈ 160µs决定 spin 检测粒度) |
### 4.4 RTT 分解模型8kHz125µs/周期)
实测 RTT mean 1.04ms ≈ 8.3 周期,分解:
| 环节 | 典型耗时 | 性质 | 可优化性 |
|---|---|---|---|
| TwinCAT 输出量化(任务边界→帧发出) | ~62µs0125 | 整周期 | 仅能提频 |
| 正向:线缆+EL6695 桥固件转发 | ~150µs | 连续 | 桥固件决定,不可控 |
| J1900 spin 检测FPRD 轮询粒度 160µs | ~125µs0250 | 量化 | 受 800B 事务往返物理下限约束 |
| J1900 处理 + 异步 FPWR 上线 | ~45µs | 连续 | 已优化至极限2425µs exec |
| 回程:线缆+桥转发 | ~150µs | 连续 | 同上 |
| TwinCAT 输入量化(帧到达→任务读取) | ~62µs0125 | 整周期 | 仅能提频 |
| 整周期簿记lag 按整周期计) | ~125250µs | 量化 | — |
**单向延迟推导**TwinCAT→J1900去掉回程三项典型 **0.30.5ms**,最坏 ~0.6ms。
适用设定值级控制、配方下发、同步基准传递;紧伺服闭环受限于完整 RTT~1ms闭环带宽 ~100Hz 量级)。
---
## 5. 测试结果
### 5.1 配置演进总表
| 阶段 | TwinCAT 任务 | J1900 模式 | 结果 | commit |
|---|---|---|---|---|
| 8B 原理验证 | 1kHz | ticker | 通过XOR 逐字节证明) | `309aaba` |
| 800B + SM 精确匹配 | 1kHz | ticker | 5h 零错误18M 周期) | `f0163d8` |
| TwinCAT 侧 DC-Synchron | 1kHz | ticker | 激活干净90k 周期零错误 | `aabfe31` |
| spin-lock + 异步 FPWR | 4kHz | spin | J1900 2040/s数据零错误 | `cdb90c3` |
| J1900 侧 DC-Synchron | 4kHz | spin+dc | 180s 同步计数器全零 | `253f4b3` |
| **3 小时 soak** | **4kHz** | **spin+dc** | **全绿(见 5.2** | — |
| RTT 优化 | 8kHz | spin+dc+RT 提权 | RTT min 0.75ms / mean 1.04ms | `4083df0` |
### 5.2 3 小时 soak4kHz + spin + DC2026-08-11 22:12 → 01:21
**PLC 侧**ADS 每 60s 采样 ×190
| 指标 | 结果 |
|---|---|
| bSync | True ×190/190 |
| nMismatch delta | 0 ×190/190 |
| ADS 错误 | 0 |
| 任务速率 | 4000.9/s 恒定 |
| 总周期 | 45,370,909 |
**J1900 侧**`--duration 11400` 整):
| 指标 | 结果 |
|---|---|
| 处理周期 | 33,711,687~2957/s74% 帧率,设计性跳帧) |
| payload 校验 | checked=33,598,819mismatch=0 |
| tx_err / rx_err / comp_err | 0 / 0 / 0 |
| stale | 0.3%(跳帧读旧,正常) |
| late | 15,7410.05% |
| exec_time | p50=25µsp99=44µs |
| DC 漂移 dcdr | 3.2h 累计 ~-9.8ms(≈-0.85ppm,有界 wander |
### 5.3 DC-Synchron 验证细节
| 发现 | 证据 |
|---|---|
| ethercrab init 已分发从站侧 DC 系统时间 | 0x0920 offset 非零、0x0930 漂移补偿激活、0x0910 以真实速率推进 |
| EL6695 从站侧 ESC SYNC 寄存器0x0980+ECAT 侧不可读 | FPRD WKC=0写入 WKC=1固件经 PDI 自管) |
| 正确启用路径是 CoE | `0x1C32/0x1C33:01 sync_mode=2` 写入被固件接受且回读保持 |
| DC 模式下运行无副作用 | 180ssm_event_missed=0cycle_exceeded=0sync_error=0SM2+SM3 |
**未证实项**SYNC0 脉冲全程实际激活状态(收尾计数器复读失败);
dcph 全范围游走表明 J1900 处理时序锁的是帧到达spin而非 SYNC0 网格。
表述应为"DC 配置下数据通路无异常",而非"DC 对性能有贡献"。
### 5.4 RTT 优化实验矩阵
| 配置 | RTT min | RTT mean | RTT max | J1900 处理率 | 结论 |
|---|---|---|---|---|---|
| 4kHz AF_PACKET | 1.0ms | 1.45ms | 1.75ms | 2957/s (74%) | 基线 |
| 8kHz AF_PACKET | 0.75ms | 1.09ms | 1.5ms | ~4000/s (50%) | 两端量化减半生效 |
| 8kHz io_uring 后端 | 1.13ms | 1.42ms | 1.75ms | 2043/s | ❌ 阻塞式设计更差,弃用 |
| **8kHz + tx_rx RT 提权** | **0.75ms** | **1.04ms** | **1.38ms** | ~31004000/s | ✅ 当前最优 |
**结论**p50=1.0ms、min=0.75ms"1ms 内"在最优/中位情形达成mean 超出 4%。
剩余耗时为结构性桥固件转发、FPRD 检测粒度、两端量化),
16kHz 提频预期收益仅 ~60µs 且引入 TcTTO 整数 µs 取整、PLC exec 预算、EL6695 能力三重风险,不建议。
### 5.5 鲁棒性测试
| 场景 | 结果 |
|---|---|
| ticker 误退(默认 60s 时长) | PLC 侧 bSync→False、nMismatch 增长——故障可观测;`--duration 0` 为正确用法 |
| 死链路注入(杀 ticker | lag 5s 内 6→8.1 亿bSync=False重启后 46 周期恢复 |
| 双实例抢网卡(误操作注入) | 错误计数txe/rxe立即暴露err_streak 超限自动退出 |
| 整机断电重启 | TwinCAT 随 boot project 自恢复 Run+PLC Run4kHz 配置保持J1900 /tmp 清空需重建(脚本化 <2 分钟DHCP 地址漂移 .101.100 ARP 扫描定位 |
---
## 6. 已知限制与残余风险
1. **J1900 处理帧率 < 发送帧率**8kHz 时 ~50%):受 800B FPRD 事务往返 ~160µs 物理约束。
echo 恒为最新帧lag 指标证明),数据正确性不受影响,但每帧独立处理的场景不适用
2. **无持续 DC 漂移补偿**ethercrab 仅静态补偿dcdr 以 ±几十 ppm wander。
事件驱动spin交换不受影响若需 J1900 硬锁 DC 网格需加周期性 FRMW 补偿
3. **TwinCAT 试用许可 7 天过期**长期运行需周期性重新激活过期症状851 端口缺失、卡 Config 态)
4. **J1900 DHCP 地址漂移**:建议静态化或按 MAC 扫描定位(已备脚本化流程)
5. **方法学盲区**:桥转发冻结而 ESC 保持 OP 的失效模式黑盒不可检出(见 3.3
## 7. 结论与建议
**结论**TwinCAT 4kHz(250µs)/8kHz(125µs) + EL6695 桥 + J1900 spin-lock + 双侧 DC-Synchron
配置下800B 双向实时通讯经 3 小时 4500 万周期验证零数据错误;
RTT 达 min 0.75ms / p50 1.0ms / mean 1.04ms,单向延迟典型 0.30.5ms。
数据完整性、新鲜度、故障可观测性、断电恢复均经实证。
**建议**
1. 生产化时将图案区替换为真实过程数据(帧结构/序号校验/延迟特性已验证可直接复用)
2. soak 采样脚本已内置 lag 监控(`tc-ads-soak.ps1`),后续长测自动覆盖新鲜度
3. 若需 mean RTT 严格 <1ms评估 LRW 单帧交换 FMMU 配置改动中等前先量化收益
4. J1900 管理口建议配置静态 IP消除 DHCP 漂移运维成本
## 8. 附录:复现命令
```sh
# J1900 侧(经跳板)
ssh -J tonycao@192.168.58.8 root@192.168.68.100
/tmp/el6695_rt_dc eth1 --duration 0 --cycle-us 125 --spin --dc # 8kHz 常驻
/tmp/kill_el6695.sh # 停止全部实例
# TwinCAT 侧(非提权可读)
scripts\tc-ads-state.ps1 # 运行状态
scripts\tc-ads-quick.ps1 # 速率 + bSync
scripts\tc-ads-lag.ps1 # nMatchLag 新鲜度采样
scripts\tc-ads-mismatch-delta.ps1 # nMismatch 冻结检查
scripts\tc-ads-soak.ps1 -Minutes N -LogFile X # 长测采样WMI 方式后台启动)
scripts\tc-deploy-retry-800b.ps1 # 提权部署(构建+激活+重启)
```