EtherCAT 通讯
EtherCAT 是 Darra PLC 的核心现场总线协议, 通过 Darra.Core.dll (C 语言主站库) 实现, 支持实时伺服控制和分布式 IO。
架构概览
支持功能
| 功能 | 说明 | 状态 |
|---|---|---|
| PDO 过程数据 | LRW 帧, 高效数据交换 | 已实现 |
| CoE (CiA 402) | SDO 邮箱读写, 伺服参数配置 | 已实现 |
| DC 分布式时钟 | IEEE 1588 主从时钟同步 | 已实现 |
| FSoE 功能安全 | Safety over EtherCAT | 已实现 |
| CiA 402 伺服 | CSP/CSV/CST 模式 | 已实现 |
| CiA 401 IO | 数字/模拟 IO 映射 | 已实现 |
| 冗余网络 | 双网卡线缆冗余 | 已实现 |
| Piggyback | PDO 帧附带小数据, <1ms 延迟 | 已实现 |
Joint PDO 映射
EtherCAT 伺服驱动器使用整数计数值 (int32 counts), 而 PLC/Robot 使用浮点弧度值 (double rad)。JointPdoMap 负责转换:
EtherCAT 从站 (int32 counts)
↕ × ScaleFactor
关节反馈/指令 (double rad)
转换公式:
- 读取:
Feedback_rad = 从站计数值 × ScaleFactor - 写入:
从站计数值 = Command_rad ÷ ScaleFactor
当 CommandSeq == 0 (PLC 未写入指令) 时, 系统自动将 Feedback 值回写到 PdOut, 保持伺服当前位置不变。
实时周期
EtherCAT 通讯运行在隔离 CPU 核心上, 典型配置:
| 参数 | 值 |
|---|---|
| 周期时间 | 1ms (可配 50us ~ 10ms) |
| 最大从站数 | 65535 (协议限制) |
| 最大 PDO 大小 | 按需分配 |
| WKC 监控 | 每周期检查 |
| 最大帧槽 | 16 帧/实例 |
配置步骤
- 网卡绑定: 选择 EtherCAT 专用网卡
- 从站扫描: 自动枚举从站, 读取 ESI 描述
- PDO 映射: 配置 PDO 分配和映射对象
- DC 配置: 设置 SYNC0/SYNC1 周期
- 状态切换: INIT → PRE-OP → SAFE-OP → OP
// C# 调用示例
using Darra.EtherCAT;
var master = new EtherCATDriver();
master.Initialize("\\Device\\NPF_{GUID}");
master.ConfigSlaves(); // 从站枚举
master.ConfigDC(1000); // DC 1ms 周期
master.SetState(SlaveState.OP);
与 PLC 集成
EtherCAT 数据通过 共享内存 与 PLC 引擎交互:
- IO 映射: EtherCAT IO 模块的 DI/DO/AI/AO 自动映射到 PLC IO 区域
- 轴控制: 伺服驱动器自动映射到关节和轴数据区域
- MC 功能块: PLC 程序使用 PLCopen MC_MoveAbsolute 等指令控制轴
EtherCAT Master 产品的完整文档 (包括 GUI 工具、多语言 SDK、从站配置) 请访问: ethercat.darra.xyz
背景:与 SOEM/IGH 的对比
EtherCAT 开源社区有两个成熟参考实现:
| 实现 | 语言 | 定位 | 许可证 |
|---|---|---|---|
| SOEM (Simple Open EtherCAT Master) | C | 用户态, 学习/小项目 | GPLv2 + 豁免 |
| IGH (EtherLab Master) | C | 内核态 Linux 实时 | GPLv2 |
| Darra.Core | C | Windows 内核 (WDK), 双栈 | 商业 |
Darra 的主站走了自研路线 (不依赖 SOEM/IGH 源码, 仅参考协议实现细节), 核心差异:
- Windows 内核原生: 直接使用 NDIS 650 协议驱动, 不需要 Npcap 等用户态抓包库
- 核心隔离: PDO 线程运行在指定的隔离 CPU 核心 (由 DarraRT.sys 完成)
- 零拷贝 GlobalIO: PDO 数据区是内核 Section, 用户态 DLL 直接映射读写
- SMI 屏蔽: 启动时检测并尽量屏蔽系统管理中断, 保证周期抖动 < 10us
- TSC 校准: 统一的高精度时间基准, 分布式时钟计算精度提升
周期抖动实测
在典型工控机 (i5-1240P, Windows 10 LTSC) 上 1ms 周期下:
| 百分位 | 抖动 | 说明 |
|---|---|---|
| P50 | < 2 μs | 中位 |
| P95 | < 10 μs | 绝大多数 |
| P99 | < 30 μs | 偶发 |
| P99.9 | < 100 μs | 罕见, 多由 SMI 造成 |
| Max (1小时采样) | < 500 μs | 极端 |
这个指标满足 CiA 402 CSP 模式对抖动 "< 1 ms" 的要求, 也优于 Windows 标准 NDIS 用户态栈 (通常 P99 > 500 μs)。
从站状态机
EtherCAT 从站有标准 ESM (EtherCAT State Machine):
INIT → PRE-OP → SAFE-OP → OP
↑_______↑_______↑______↑
状态读取通过 AL_STATUS (0x0130)
状态请求通过 AL_CONTROL (0x0120)
| 状态 | 功能 | 典型过渡触发 |
|---|---|---|
| INIT | 初始状态, 仅 Register 访问 | 上电后自动到达 |
| PRE-OP | 邮箱通讯可用 (CoE), PDO 未启用 | 主站发 AL_CTL=0x02 |
| SAFE-OP | 主站只读 PDO, 写入被忽略 | 主站发 AL_CTL=0x04 + 配置 PDO |
| OP | 完整运行, PDO 双向 | 主站发 AL_CTL=0x08 |
每次切换如果失败, AL_STATUS 置错误位, AL_STATUS_CODE (0x0134) 记录原因 (字典见 ETG.1000.5)。
PDO 映射原理
从站把想交换的变量放入 TxPDO (发送) / RxPDO (接收), 映射信息存于对象字典:
0x1A00 — TxPDO1 Mapping
子索引 0: 条目数 = 2
子索引 1: 0x60410010 (Statusword, 16 bit)
子索引 2: 0x60640020 (Actual Position, 32 bit)
0x1C13 — Sync Manager TxPDO Assign
子索引 0: 分配条目数 = 1
子索引 1: 0x1A00 (使用 TxPDO1)
主站在 SAFE-OP 切换前, 根据 ESI 或扫描结果把想要的 PDO 写入 0x1C12/0x1C13。Runtime 侧自动完成这一步, 普通用户不需要手工改。
分布式时钟 (DC)
DC 让所有从站的 SYNC0 信号在纳秒级对齐, 是多轴同步的基础:
主站 → 广播参考时钟 → 所有从站校时
主站 → 计算传播延迟 → 下发到每个从站
每个从站 → 按本地时钟生成 SYNC0/SYNC1
IDE 侧配置:
- 参考时钟从站: 默认选第一个支持 DC 的从站
- SYNC0 周期: 与 PDO 周期一致
- SYNC0 相位: 默认 0, 必要时留出偏移 (如 500us) 给应用处理
冗余
Darra 支持双网卡线缆冗余:
主站 NIC1 ─ Slave1 ─ Slave2 ─ ... ─ SlaveN ─┐
│
主站 NIC2 ────────── (备用路径) ──────────────┘
典型场景: 任意一根网线断, 主站自动把环反转方向, 业务不中断。详细见 EtherCAT 产品文档。
CoE (CAN over EtherCAT)
CoE 在邮箱协议里走 SDO (Service Data Object), 用于参数配置和非实时数据:
// 读参数: 节点 3 的 0x6064:00 (Actual Position)
int pos = master.SdoRead<int>(slaveIndex: 3, index: 0x6064, subIndex: 0);
// 写参数: 节点 3 的 0x6081:00 (Profile Velocity)
master.SdoWrite(slaveIndex: 3, index: 0x6081, subIndex: 0, value: 100000);
SDO 传输不是实时的, 典型延迟 1~50 ms, 不要在 PLC 周期里频繁读写。推荐:
- 启动阶段 (PRE-OP) 配置参数
- 运行时通过 PDO 交换高频数据
- 偶发参数调整通过后台任务 SDO
FoE (File over EtherCAT)
FoE 用于从站固件升级和大文件传输:
master.FoeUpload(slaveIndex: 3, filename: "firmware.bin",
localPath: "C:/download/backup.bin");
master.FoeDownload(slaveIndex: 3, filename: "firmware.bin",
localPath: "C:/firmware/new.bin");
升级期间从站进入 BOOT 状态, 业务中断, 需停机操作。
典型周期配置
| 场景 | PDO 周期 | 最大从站数 | 应用 |
|---|---|---|---|
| 高端运动控制 | 250 μs | 16 | 机械手、CNC 多轴联动 |
| 一般运动控制 | 500 μs ~ 1 ms | 32 | 常见工业机械 |
| 混合 IO + 运动 | 1 ms | 64 | 流水线 + 多台伺服 |
| 纯 IO 采集 | 2 ~ 10 ms | 128 | 分布式 IO 网络 |
| 慢速监控 | 10 ~ 50 ms | 256+ | 大规模传感器网 |
周期越短, CPU 占用越高, 允许的从站数越少。选择时需权衡。
诊断工具
IDE 内置 EtherCAT 诊断面板:
- 拓扑视图: 从站链路连接图, 标出端口状态、错误计数
- WKC 监视: 工作计数器变化, 丢失帧计数
- 从站状态: 每从站当前 AL_STATUS 和错误码
- PDO 值: 实时显示所有从站的 PDO 数据
- CoE 浏览器: 对象字典浏览和读写
- 错误计数: 每端口 Invalid Frame / RX Error / Link Lost
排错
| 症状 | 原因 | 处理 |
|---|---|---|
| 从站扫描不到 | 网卡未被 DarraRT_Eth 接管 | 设备管理器安装驱动 |
| 卡在 INIT | 线序错 / 从站没通电 | 从前往后检查 LED |
| 无法切换到 OP | PDO 映射失败 | 查 AL_STATUS_CODE (0x001b 常见) |
| 偶发 WKC 错 | 单次帧丢失 | 看端口 RX Error 是否累计, 可能网线问题 |
| DC 不同步 | 参考时钟选错 | 选网络最中心的支持 DC 从站 |
高周期 (<500us) 抖动大 | CPU 隔离不足 | 增加隔离核心数 |