ethercat-linux/docs/scope-waveform-design.md
Tony Cao 21b2d3bf99 J1900 <-> TwinCAT 1 kHz verification over EL6695 bridge
Re-implementation of rustbootd's ecat_el6695_* examples as a single binary
with fixes found in review and on hardware:

- DC-follow PLL hardened against period-2 hunting: slew-limited anchor
  (+/-50us/cycle), bistable-trap snap re-anchor, re-prime on stale deadline
- drift-free absolute-grid ticker mode; probe mode for timestamp forensics
- bounded-memory online stats (histograms), graceful SIGINT/SIGTERM shutdown
  with full report, error-streak abort
- timestamp plausibility filter comparing against the previous raw sample
  (avoids the deadlock after a startup outlier)
- XFC scope waveform options: --el2202 (with --el2202-dual), --el2262,
  --el1252 latch timestamp readback with per-channel edge statistics
- register access unified in regs.rs: named bit constants everywhere,
  read-modify-write for enable/activation bytes
- vendored patched ethercrab 0.7.1 (sdo_write_complete, send_raw_coe)

Verified on J1900 (PREEMPT_RT 6.6.135): 600k cycles/600s exact 1 kHz,
tx/rx zero errors, phase_err p50=164us std=5us; EL2202<->EL1252 loopback
edge interval mean 2000.24us std=24.65us.
2026-07-22 08:55:41 +08:00

9.5 KiB
Raw Blame History

TwinCAT Scope 通讯周期/抖动波形设计

  • 日期2026-07-21
  • 状态:设计已确认,待实现
  • 相关项目:ethercat-linuxJ1900 侧 el6695-rtfree/TwinCATProject1/PlcSyncTwinCAT 侧 PLC

1. 目标

在 TwinCAT Scope View 中以波形直观展示 J1900 ↔ TwinCAT 经 EL6695 桥的 1 kHz 通讯的周期抖动,用于实时观测和稳定性评估。

2. 原理

让 PLC 每个 1ms 任务周期计算若干"测量变量",用 TwinCAT Scope View 按 PLC 任务周期1 kHz 采样率)经 ADS 符号采样绘图。现有数据通路已经齐 全PLC 每周期刷新 aOut1(序列号 + 图案 + 发送时间戳J1900 侧 el6695_rt 每周期将 SM3 载荷原样回显到 SM2 并在字节 [8..16] 写入自己的 周期号。

关键洞察:发送时间戳(F_GetSystemTime)经回显路径原样返回,往返测量 全程在 TwinCAT 自己的时钟域内,无跨时钟域误差——这是端到端抖动的 理想波形信号。

3. 波形通道设计

# Scope 通道 来源 含义 正常形态
1 nRttUs nEchoTimestamp - nSendTimestampaIn1[256..263] 回显时间戳 本周期发送时间戳) 端到端往返延迟(同时钟域) ~4000µs 水平带,带宽 = 抖动
2 nInSeqDelta nReturnedSeq 的周期差分 TwinCAT 视角的输入帧间隔 恒为 10 = 重读旧帧2 = 丢帧
3 nJ1900Delta nJ1900Cycle 的周期差分 J1900 循环节拍在 TwinCAT 侧的投影 恒为 1偏离即对端周期异常
4 nJ1900JitterNs J1900 写入回显帧 payload[264..268] 的自测唤醒抖动i32 LE 对端内部定时质量 follow 模式锁定后 <1µs
5 nJ1900PhaseErrNs payload[268..272] 的相位误差i32 LE 对端读点与 TC 网格的相位 ~165µs 直线,慢漂移可见

通道优先级1 > 2 > 3 > 4 > 5。

  • 通道 1 把"周期抖动"直接变为 µs 量级波形,是最有价值的一条。
  • 通道 2/3 把 1 kHz 周期本身可视化为恒 1 直线,任何毛刺都显眼。
  • 通道 4/5 需要 J1900 侧配合(见 §4.2),用于观测对端内部状态。

4. 实现方案

4.1 PLC 侧PlcSync 工程,追加 ~20 行 ST

GVL_Sync.TcGVL 增加:

nRttUs          : DINT;   // 端到端往返 (us),同时钟域
nInSeqDelta     : DINT;   // nReturnedSeq 周期差分
nJ1900Delta     : DINT;   // nJ1900Cycle 周期差分
nJ1900JitterNs  : DINT;   // J1900 自测唤醒抖动 (ns),来自 aIn1[264..267]
nJ1900PhaseErrNs: DINT;   // J1900 相位误差 (ns),来自 aIn1[268..271]
nPrevRetSeq     : ULINT;  // 差分寄存器
nPrevJ1900      : ULINT;  // 差分寄存器

MAIN.TcPOU 末尾追加:

// Waveform channel 1: same-clock-domain round-trip time.
IF GVL_Sync.nEchoTimestamp > 0 AND GVL_Sync.nEchoTimestamp >= GVL_Sync.nSendTimestamp THEN
    // F_GetSystemTime 单位为 100ns
    GVL_Sync.nRttUs := ULINT_TO_DINT((GVL_Sync.nEchoTimestamp - GVL_Sync.nSendTimestamp) / 10);
ELSE
    GVL_Sync.nRttUs := -1;
END_IF

// Waveform channels 2/3: per-cycle deltas of the echoed sequence numbers.
GVL_Sync.nInSeqDelta  := ULINT_TO_DINT(GVL_Sync.nReturnedSeq - GVL_Sync.nPrevRetSeq);
GVL_Sync.nJ1900Delta  := ULINT_TO_DINT(GVL_Sync.nJ1900Cycle  - GVL_Sync.nPrevJ1900);
GVL_Sync.nPrevRetSeq  := GVL_Sync.nReturnedSeq;
GVL_Sync.nPrevJ1900   := GVL_Sync.nJ1900Cycle;

// Waveform channels 4/5: J1900 self-measured diagnostics from the payload.
MEMCPY(ADR(GVL_Sync.nJ1900JitterNs),   ADR(GVL_Sync.aIn1[264]), 4);
MEMCPY(ADR(GVL_Sync.nJ1900PhaseErrNs), ADR(GVL_Sync.aIn1[268]), 4);

布局约束(重要):图案校验覆盖字节 [16..255],发送时间戳占 [256..263] 因此 J1900 诊断字放在 [264..271],不会触发 nMismatch

需要重新激活配置(free/rt-activate2.ps1TwinCAT PLC 任务会中断几秒。

4.2 J1900 侧el6695-rt 小改,无副作用)

在回显之后、fpwr 之前,把本周期自测值写入回显帧:

// 回显之后:
tx_buf[264..268].copy_from_slice(&(jitter_ns as i32).to_le_bytes());
// follow 模式的相位误差ticker 模式写 0
tx_buf[268..272].copy_from_slice(&(phase_err_ns as i32).to_le_bytes());

交叉编译部署即可,不影响现有协议与 PLC 校验逻辑。

4.3 Scope 工程配置

  1. XAE 中 PlcSync 工程旁新建 TwinCAT Measurement / Scope 工程。
  2. 新建 YT Chart数据源选 PLC 符号ADS采样率挂到 PLC 任务 1 kHz与数据更新率一致
  3. 将 §3 的 5 个变量拖为通道;通道 1µs与通道 2/3计数分双 Y 轴。
  4. 长时间观测ADS 记录受缓冲限制,如需小时级统计,在 PLC 中追加滑动 窗口 min/max 寄存器(例如每 1000 周期输出一次窗口极值Scope 只画 统计曲线。

5. 验收标准

  • 跑 60s el6695_rtfollow 模式Scope 中:
    • nRttUs 为 ~4000µs 水平带(实测均值 ~4.04.3 个 PLC 周期);
    • nInSeqDeltanJ1900Delta 恒为 1无毛刺
    • nJ1900JitterNs < 1µs锁定后nJ1900PhaseErrNs ≈ 165µs 直线。
  • 停掉 J1900 侧程序,通道 2/3 应立即偏离 1断链可见

6. 备注

  • 参考实现的 follow 代码从 data[258..266] 读发送时间戳,与 PLC 实际 写入位置 aOut1[256..263] 错位 2 字节——通道 1 必须使用 256 偏移。
  • 断链时 EL6695 输出替代值(全 0nEchoTimestamp 为 0通道 1 输出 -1 作为无效标记。

7. 示波器方案EL2202已实现 2026-07-21

除 Scope 软件波形外,--el2202 参数让 el6695_rt 每周期翻转 EL2202 (总线 [1],站地址 0x1001的一个数字输出示波器可直接观察 ~500Hz 方波的沿抖动(= J1900 RT 环路发送时序抖动PREEMPT_RT + follow 锁定下 为 µs 级)。

实现要点(实机验证通过):

  • 简单 DO 端子无邮箱SM/FMMU 仅在组 PREOP→SAFEOP 转换时由主站编程; 本程序跳过该转换EL6695 走裸配置),因此 EL2202 的 SM0 也手动配置: 起始 0x0F00、长度 1、ctrl 0x44、enable 0x09按 EEPROM 类别 41
  • EL2202 过程字节语义EEPROM PDO 0x1600/0x1601 实证): bit0=通道1数据, bit1=通道1三态(高阻), bit2=通道2数据, bit3=通道2三态。 单通道写 0x01/0x00双通道--el2202-dual)必须写 0x05/0x00—— 写 0x03 会把通道 1 置高阻,表现为"输出 1 失效"(实测踩中)。
  • 裸 AL 驱动 SAFEOP→OP写 0x01 回读验证通过后才启用逐周期翻转。
  • 翻转帧使单圈执行时间 ~410µs → ~650µs帧开销为主仍在 1ms 预算内); 60s 回归60000 周期精确 1kHztx/rx/el2202 错误均为 0 phase_err p50=164µs、std 5.3µs与不开 EL2202 时一致)。
  • 升级路径:总线 [3] EL2262XFC 时间戳输出)可在 DC 网格精确翻转,与 EL2202 沿做双通道对比获得绝对相位基准;[2] EL1252XFC 时间戳输入) 可回采沿时刻做数值统计。

8. XFC 方案 B/C已实现 2026-07-21

8.1 关键事实(实机 EEPROM 探明)

  • EL1252/EL2262 均无 CoE/邮箱(手册 §4.5 "This device has no CoE" EEPROM SM 类别 41 中无邮箱 SM配置只能走 EEPROM 默认值 + 裸寄存器。
  • EEPROM 类别在 41SM40FMMU 用途)、50/51PDO 不是 4。EL2262 输出 SM0@0x1000ctrl 0x64, enable 0x09 EL1252 输入 SM0@0x1000。
  • EL1252 锁存时间戳直接在 ESC 寄存器里PDO 0x1A13 的存储位置): 0x09AE=status0、0x09AF=status1、0x09B0=Latch0Pos、0x09B8=Latch0Neg、 0x09C0=Latch1Pos、0x09C8=Latch1Neg通道 1→Latch0通道 2→Latch1。 无需 SM/OP 配置PREOP 下即可 fprd 读取。
  • 两台端子的 DC 时钟0x910出厂即在运行自由跑未总线同步

8.2 方案 B--el2262DC 网格基准方波)

  • 配置 EL2262 DC 同步单元0x0990=启动时间(当前+100ms)、 0x09A0=0x09A4=1ms、0x0980=0x03SYNC0+SYNC1 激活);手动配 SM0 0x1000/1B/0x64/0x09裸 AL 驱动 OP。
  • 数据在 SYNC 事件才应用 → 输出沿锁定 DC 1ms 网格,与帧到达抖动无关。
  • 注意该端子本台硬件版本EEPROM 未提供 StartTimeNextOutput PDO 32 位版本见新固件),采用 SYNC 锁定方式实现。

8.3 方案 C--el1252(沿时间戳回采统计)

  • 每周期 fprd 34B @0x09AE跟踪两个通道 LatchXPos 变化,输出上升沿 间隔统计(名义 2ms与沿在 1ms 周期内的相位统计。
  • 帧预算:每帧往返 ~160-245µs。A+C 或 B+C 组合 = 4 帧/周期, 单圈执行 ~898µs锁相保持phase_err p50≈164µsA+B+C 五帧超预算, 不要同开。

8.4 接线与验证步骤(需要现场操作)

端子点位(三种 2 通道端子布局相同,已核手册):点 1 = 通道 1 点 2/6 = +24V点 3/7 = 0V点 4/8 = PE接地不是通道 2 点 5 = 通道 2

  1. EL2202 输出 1点 1→ EL1252 输入 1点 1 --el2202 --el1252el1252_ch1_edge_interval 应为 2000µs 均值、 抖动 µs 级。
  2. EL2262 输出 1点 1→ EL1252 输入 2点 5 --el2262 --el1252el1252_ch2_edge_interval 同样 2000µsch2_edge_phase 应锁定在固定相位DC 网格)——与通道 1环路驱动 的相位漂移对比即为环路相位误差。
  3. 示波器双通道CH1=EL2262 点 1DC 基准、CH2=EL2202 点 1环路 驱动),地夹接点 3/70V勿接点 4/8 的 PE