Files
DCU_DesktopController/docs/compose/spec/ecat-rx-stuck.md
T
cbb e91d53e0fc feat(ecat): 启动后把 ecat_native 提到 RealTime;跳拍优化实验脚本与报告
- esp32_server: Popen 后外部 SetPriorityClass(RT/High),native 自设会被钳成 High
- 入库 skip_* 标定/实验脚本与 REPORT_ecat_skip_opt_20260917
- 前端 WIP:layout/app/polling/boot_ecat/index
- 不含 lab/skip_meter 原始采样与 preview 截图
2026-09-17 02:32:20 +08:00

3.4 KiB
Raw Blame History

feature, status, updated, branch, commits
feature status updated branch commits
ecat-rx-stuck in-progress 2026-09-16 main

EtherCAT 从机帧接收异常(输入全 0 / 发帧后才流动)

Report

真机验收(2026-09-16,主站 kick 已上线):motor/start 不发业务帧 即 wkc=3/3、rxraw.layout=dense、magic=0xA5、gseq=429、motors=1、wr=0。 日志:OP 后输入已流动(magic=1 diag=1 rx 431→431),踢帧 8 拍。

[S1] Problem

EtherCAT 进入 OP 后,主站 /api/motor/pdoin 与 /api/motor/rxraw 整包 600B 全 0: 无 dense magic(0xA5)、gseq=0、桥 rx_count=0、段 5 诊断 seq=0、app/load.valid=false。 现场 wkc=2/3(期望 3)。用户一旦经 /api/motor/send 发出任意帧,输入立刻流动: wkc=3/3、magic=A5、电机槽/桥状态出现。之后 wr 楔死恢复次数持续上涨。

真机复现(2026-09-16,GD32 APP 1.6.41 + 主站 native):

  1. motor/start → 日志「OP 后输入无流动…重走 INIT→OP」→ 仍全 0
  2. motor/send 一帧 → 同一秒内 pdoin 出现 dense 布局与真实电机状态
  3. SPI /spi/speedtest 正常(ESP32↔GD32 链路本身无病)

[S2] Design

根因(主)

从站 SSC 在 SM-Synchron 下应用与输入映射靠 SM2 事件(PDI_Isr)驱动; MainLoop 的 free-run 分支在 bEcatFirstOutputsReceived==TRUE 后整段跳过。 主站 idle 输出 seq=0 时,从站 processOutput/冷启动路径迟迟不把输入 PDO 真正填进 ESC——buildInput+fillDiagTail 依赖 EcatPdo_Process() 被调用。 主站一旦发送(seq 沿变化)→ outputProbe 全量读 → 冷启动/应用路径苏醒 → 输入开始流动。

次因

  1. 主站 OP 活性判据过窄(do_op_start):只看两次 pump_cycles 之间 bridge.rx_count 是否变化。无 CAN 流量时 rx_count 恒 0 → 必判「无流动」→ 无意义重走 INIT→OP;有流量时 12ms 窗口也可能采不到 → 同样误判。
  2. 从站 1.6.33 新鲜度救援只写不填(EcatDbg_OpInputFreshness):输入冻结时 只调 PDO_InputMapping(),从空的 s_inBuf 拷 0 写 ESC,等于把「冻结」固化成「全 0」。
  3. 从站 1.6.41 warm-jump 跳过 RST# 的路径本身可接受(BYTE_TEST 门),但与上述 「应用未醒」叠加后,首帧前输入窗口长期全 0。

修复契约

侧 行为
主站 进 OP 后、起循环前:用 dlc=0 + seq 沿 的空输出连打数拍,制造 outputProbe 边沿、不发 CAN。活性判据改为「输入含 dense magic 或 diag seq 非 0 或 rx_count 变化」。
从站 EcatDbg_OpInputFreshness 强制刷新前先 EcatPdo_Process(),再 PDO_InputMapping()。
从站版本 patch → 1.6.42(仅救援路径,无布局变更,可与主站独立升级)。

[S3] Out of Scope

  • 不改 PDO 线格式 / SII / 600B 布局
  • 不改 SPI 协议(0xE8 撕裂已有 ESP32 侧未提交修复,另案)
  • 不回退 1.6.41 warm-jump 探针策略(BYTE_TEST 门保留)
  • 不改电机/CAN 桥业务语义

Tasks

  • T1: 主站 OP 后 seq 沿踢帧 + 活性判据加宽 — acceptance: 不发业务帧时 pdoin 出现 0xA5 且 gseq 可前进 (covers: S2)
  • T2: 从站新鲜度救援先 Process 再 InputMapping — acceptance: PDI 停摆时主站读到非全 0 输入 (covers: S2)
  • T3: 真机复验 start 后不 send 即有输入 — acceptance: motor/start 后 2s 内 rxraw.layout=dense (covers: S2; depends: T1)