15 KiB
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 数据完整性证明链
单向"收到数据"不能证明通讯正确。本方案用双向交叉校验 + 数学变换构成闭环证明:
- PLC 侧写入:
aOut1[i] = (nCycles + i) mod 256(图案区),aOut1[0..7] = tc_seq - J1900 侧处理(证明"读取+计算+写回"三个动作真实发生):
- 校验收到图案
[16..256)与tc_seq一致(不一致计入payload_mismatch) - 对序列号做不可由硬件桥接伪造的数学变换:
f(x) = x*7 + 3 - 回写
aIn1[0..7] = f(tc_seq),图案区原样回传,[272..279]保留原始 tc_seq
- 校验收到图案
- 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. 已知限制与残余风险
- J1900 处理帧率 < 发送帧率(8kHz 时 ~50%):受 800B FPRD 事务往返 ~160µs 物理约束。 echo 恒为最新帧(lag 指标证明),数据正确性不受影响,但每帧独立处理的场景不适用
- 无持续 DC 漂移补偿:ethercrab 仅静态补偿,dcdr 以 ±几十 ppm wander。 事件驱动(spin)交换不受影响;若需 J1900 硬锁 DC 网格需加周期性 FRMW 补偿
- TwinCAT 试用许可 7 天过期:长期运行需周期性重新激活(过期症状:851 端口缺失、卡 Config 态)
- J1900 DHCP 地址漂移:建议静态化或按 MAC 扫描定位(已备脚本化流程)
- 方法学盲区:桥转发冻结而 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。 数据完整性、新鲜度、故障可观测性、断电恢复均经实证。
建议:
- 生产化时将图案区替换为真实过程数据(帧结构/序号校验/延迟特性已验证可直接复用)
- soak 采样脚本已内置 lag 监控(
tc-ads-soak.ps1),后续长测自动覆盖新鲜度 - 若需 mean RTT 严格 <1ms,评估 LRW 单帧交换(需 FMMU 配置,改动中等)前先量化收益
- J1900 管理口建议配置静态 IP,消除 DHCP 漂移运维成本
8. 附录:复现命令
# 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 # 提权部署(构建+激活+重启)