Full RT link verification report: methodology, metric analysis, 3h soak, RTT optimization, DC-Synchron findings
This commit is contained in:
parent
4083df04fb
commit
9db5cf4504
287
docs/rt-link-verification-report.md
Normal file
287
docs/rt-link-verification-report.md
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
# 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=0,tx/rx err=0 |
|
||||
| RTT(8kHz + tx_rx RT 提权) | min 0.75ms / mean 1.04ms / max 1.38ms |
|
||||
| 单向延迟(推导) | 典型 0.3–0.5ms,最坏 ~0.6ms |
|
||||
| 死链路检测 | lag 指标 + bSync 双重敏感(实测 5 秒内可检出) |
|
||||
| DC-Synchron(双侧) | 从站侧固件 sync_mode=2 接受,180s 同步计数器全零 |
|
||||
| 断电恢复 | TwinCAT 自恢复 Run;J1900 重建 /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,曾漂移至 .101,MAC `00:e2:69:34:71:2c`) |
|
||||
| SSH 跳板 | `tonycao@192.168.58.8` |
|
||||
| EL6695 从站侧站址 | `0x1000` |
|
||||
| J1900 内核 | 6.6.135-rt74(PREEMPT_RT,io_uring 可用) |
|
||||
|
||||
### 2.2 软件与工程
|
||||
|
||||
| 项 | 位置 |
|
||||
|---|---|
|
||||
| TwinCAT 工程(800B 变体) | `C:\Users\tonycao\work\twincat3-auto-cli\TwinCAT_EL6695_Primary_800B\` |
|
||||
| J1900 源码 | `C:\Users\tonycao\work\ethercat-linux`(Rust,ethercrab 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 同步翻 False(EL6695 从站侧失联使输入映像清零)
|
||||
- **反向验证**:重启 ticker 后 lag 立即回落至 4–6 周期
|
||||
|
||||
### 3.3 方法学盲区(如实声明)
|
||||
|
||||
| 盲区 | 说明 | 缓解 |
|
||||
|---|---|---|
|
||||
| 桥转发冻结而两侧 ESC 保持 OP | aIn1 冻结时自洽校验仍通过,任何黑盒测试无法检出 | 概率极低;需侵入式手段 |
|
||||
| J1900 侧图案校验仅覆盖 `[16..256)`(240/800 字节) | PLC 侧覆盖 768 字节,互补 | 可扩大 J1900 校验范围 |
|
||||
| J1900 处理帧率低于发送帧率(设计性跳帧) | echo 恒为最新帧(lag 指标证明),无陈旧累积 | 见 5.4 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 指标详解
|
||||
|
||||
### 4.1 PLC 侧(GVL_Sync,ADS 可读)
|
||||
|
||||
| 指标 | 类型 | 定义 | 意义与解读 |
|
||||
|---|---|---|---|
|
||||
| `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 分解模型(8kHz,125µs/周期)
|
||||
|
||||
实测 RTT mean 1.04ms ≈ 8.3 周期,分解:
|
||||
|
||||
| 环节 | 典型耗时 | 性质 | 可优化性 |
|
||||
|---|---|---|---|
|
||||
| TwinCAT 输出量化(任务边界→帧发出) | ~62µs(0–125) | 整周期 | 仅能提频 |
|
||||
| 正向:线缆+EL6695 桥固件转发 | ~150µs | 连续 | 桥固件决定,不可控 |
|
||||
| J1900 spin 检测(FPRD 轮询粒度 160µs) | ~125µs(0–250) | 量化 | 受 800B 事务往返物理下限约束 |
|
||||
| J1900 处理 + 异步 FPWR 上线 | ~45µs | 连续 | 已优化至极限(24–25µs exec) |
|
||||
| 回程:线缆+桥转发 | ~150µs | 连续 | 同上 |
|
||||
| TwinCAT 输入量化(帧到达→任务读取) | ~62µs(0–125) | 整周期 | 仅能提频 |
|
||||
| 整周期簿记(lag 按整周期计) | ~125–250µs | 量化 | — |
|
||||
|
||||
**单向延迟推导**(TwinCAT→J1900,去掉回程三项):典型 **0.3–0.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 小时 soak(4kHz + spin + DC,2026-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/s,74% 帧率,设计性跳帧) |
|
||||
| payload 校验 | checked=33,598,819,mismatch=0 |
|
||||
| tx_err / rx_err / comp_err | 0 / 0 / 0 |
|
||||
| stale | 0.3%(跳帧读旧,正常) |
|
||||
| late | 15,741(0.05%) |
|
||||
| exec_time | p50=25µs,p99=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 模式下运行无副作用 | 180s:sm_event_missed=0,cycle_exceeded=0,sync_error=0(SM2+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** | ~3100–4000/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;重启后 4–6 周期恢复 |
|
||||
| 双实例抢网卡(误操作注入) | 错误计数(txe/rxe)立即暴露,err_streak 超限自动退出 |
|
||||
| 整机断电重启 | TwinCAT 随 boot project 自恢复 Run+PLC Run(4kHz 配置保持);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.3–0.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 # 提权部署(构建+激活+重启)
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user