- 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 截图
5.4 KiB
5.4 KiB
EtherCAT 跳拍优化实验报告
日期:2026-09-17
台子:i7-14700K + I210「以太网 2」100Mbps + GD32E508 从站(3 电机在线)
主判据:不跳拍率(late_per_s / skip_per_s,来自 /api/motor/dbg 拍环 k>0)
原始数据:lab/skip_meter/*.json
一、结论(按性价比)
| 措施 | 1ms late/s | 判定 |
|---|---|---|
| 基线(进程 Normal,原绑定) | ~10–25(漂) | 起点 |
| 进程 RealTime | 均值更好(~8–12) | 有效,保留 |
| 关 I210 上 VMware Bridge 等协议 | 有助(单独测过 4.1/s 一枪;混方差) | 有效,保留 |
| 关中断裁决 ITR=0 | 70/s | 有害,已还原 |
| 关 EEE | 98/s | 有害,已还原 |
| ITR=50(非法)/固定低 ITR | 更差或无效 | 已还原 |
| 关 IPv4/IPv6(本卡仅链路本地) | 无可测收益 | 已重新打开 |
| 周期 2ms | 0.06/s ≈ 不跳 | 主判据下的最优运行点 |
| 周期 4ms | 0 | 同上,更宽裕 |
主判据一句话:
- 必须 1ms:当前约 10–17 late/s(work p50≈366µs,余量只有 ~630µs,偶发 1ms 尖峰必跳)。
- 允许 2ms:约 0.06 late/s(16s 仅 1 拍),达成 500.00Hz,不跳拍率优先时选这个。
二、机理回顾(本轮再确认)
跳拍 = pdo_worker 自旋到绝对截止点时 next_t <= now,补 k 个周期。
本轮形态:
- send 长尾(
pcap_sendpacket≈1ms,rxc=1)— Npcap/驱动/DPC,不是从站。 - rx 长尾(等回包 ≈1ms,rxc≈200+)— 主机接收路径,不是总线被占。
从站 load_perm≈336‰、WKC 3/3、layout=dense,没有被别的 EtherCAT 用户抢走。
注意:本轮中后期 rx p50 从早晨的 ~90µs 变成 ~330µs(进程重启/绑定调整后未回到 90)。
这压缩了 1ms 档余量,是 late 从 ~10 抬到 ~15–25 的主要原因之一;机理未完全闭合(怀疑桌面负载/DPC 形态漂移,非网卡高级属性)。
三、已落地的改动(可回滚)
3.1 保留
-
ecat_native启动尝试 RealTime(tools/ecat/ecat_native.c)- 先提
SE_INC_BASE_PRIORITY_NAME再SetPriorityClass(RT)。 - 实测自设仍会被钳成 High(令牌无该特权时 API 仍可能返回成功/或被系统钳位)。
- 因此
esp32_server.py在 Popen 后从外部SetPriorityClass(RT)(能粘住,已验证)。 - 备份:
tools/ecat/build_native/ecat_native.pre-rt.exe。
- 先提
-
I210 绑定裁剪(仅「以太网 2」)
- 已禁用:
vmware_bridge,ms_pacer,ms_lldp,ms_rspndr,ms_lltdio,ms_server,ms_msclient - 仍启用:
INSECURE_NPCAP(必须)、ms_tcpip/ms_tcpip6(已恢复) - 快照:
lab/skip_meter/nic_bind_*.json
- 已禁用:
-
I210 高级属性:已还原为实验前原值(ITR=适应性,EEE 按系统,FlowControl Rx+Tx 等)。
3.2 运行态
- 周期:已恢复 1ms(与实验前一致,避免破坏你当前用法)
- WKC 3/3、OP、loop=1、
pcore_mask=0x50 - 进程优先级:当前为 RealTime(外部设置)
四、回滚
# 1) 恢复 I210 协议绑定
python scripts/skip_bind_experiment.py --restore
python scripts/skip_bind_noip.py --restore # 若曾关过 IP,脚本会 Enable
# 2) 恢复 I210 高级属性(用任一 nic_before_*.json)
python scripts/skip_nic_experiment.py --restore --snap lab/skip_meter/nic_before_1789580690.json
# 3) 还原旧主站二进制
# 先停 ecat_native,再:
Copy-Item tools\ecat\build_native\ecat_native.pre-rt.exe tools\ecat\build_native\ecat_native.exe -Force
# 然后由 esp32_server 自动重拉,或手动跑 ecat_web.bat
# 4) 进程优先级改回 High(不必还原绑定时用)
Get-Process ecat_native | ForEach-Object { $_.PriorityClass = 'High' }
网卡高级属性原始快照:lab/skip_meter/nic_before_1789580690.json(含 ITR=65535 等)。
五、标定/实验脚本
| 脚本 | 用途 |
|---|---|
scripts/skip_rate_meter.py |
标准跳拍率标定(主判据) |
scripts/skip_host_snapshot.py |
主机/I210/进程现场快照 |
scripts/skip_prio_ab.py |
High vs RealTime A/B |
scripts/skip_quiet_periods.py |
1/2/4ms 静默对比 |
scripts/skip_nic_experiment.py |
网卡高级属性实验 + --restore |
scripts/skip_bind_experiment.py |
绑定裁剪 + --restore |
scripts/skip_restart_native.py |
进程热重启对照 |
六、建议
- 不跳拍优先 → 生产用 2ms(本轮实测 16s 仅 1 拍 late)。若必须 1ms,接受 ~1%/拍 late,并保证 RealTime + 无 VMware 桥。
- 重启
esp32_server后,新代码会在拉起ecat_native时自动提 RealTime;当前若只重启 native 不重启 server,需再手动设一次。 - 勿再关 ITR/EEE 做“低延迟”优化——本台子上是反向的。
rx p5090→330µs 未闭合,下一轮可专查桌面 DPC(关 360/同步盘/任务管理器常刷)对照。
七、我在这轮里错过又改掉的判断
- 「关中断裁决能降 send 长尾」→ 实测 70/s,立刻还原。
- 「关 EEE 能降功耗相关抖动」→ 实测 98/s,立刻还原。
- 「进程自设 RealTime 会粘住」→ 日志显示成功但
PriorityClass=High,改为启动方外部设置。 - 首版标定器拿 unix 时间去比
now_s()拍环 → 恒 0 late,已修。