05 主站实现:IgH EtherCAT Master 与 SOEM
本文重点:Linux 平台上两个最常用的开源 EtherCAT 主站栈——IgH EtherCAT Master(内核态)与 SOEM(用户态)——的架构、API 使用模式、对比选型,以及运行主站所需的实时环境配置。
面向读者:准备在 PC/工控机上跑 EtherCAT 主站的机器人/工控工程师。具体 API 签名、版本行为以官方文档为准:IgH(etherlab.org、gitlab.com/etherlab.org/ethercat)、SOEM(github.com/OpenEtherCATsociety/SOEM)。
1. 主站栈全景
EtherCAT 主站只需要一块普通以太网卡(MAC 层直接收发原始帧),不需要专用硬件,因此主站的差异全部体现在软件栈上:
| 主站 | 类型 | 运行环境 | 许可 | 典型场景 |
|---|---|---|---|---|
| Beckhoff TwinCAT | 商用 | Windows + 实时扩展 | 商业许可 | 事实标准、工程工具链最完整(扫描、ESI 管理、示波) |
| Acontis EC-Master | 商用 | Linux/Windows/RTOS/裸机 | 商业许可 | 需要商业支持、认证、跨平台的产品 |
| KPA EtherCAT Master | 商用 | 多平台 | 商业许可 | 同上 |
| IgH EtherCAT Master(EtherLab) | 开源 | Linux(内核模块) | GPLv2(内核部分)/ LGPL(用户库,以随源码的 COPYING 为准) | Linux 实时控制、ros2_control 集成的主流选择 |
| SOEM(Simple Open EtherCAT Master) | 开源 | 用户态 C 库,可移植 | GPLv2(带链接例外的历史版本存在,以仓库 LICENSE 为准) | 嵌入式、快速原型、对内核无侵入 |
| SOEM 的兄弟项目 SOES | 开源 | 从站协议栈 | 同 SOEM | 自研从站固件 |
许可细节随版本变动(SOEM 曾从 GPLv2+例外调整过表述),商用闭源集成前务必阅读当前版本的 LICENSE 文件,以官方仓库为准。
选型的第一性问题:
- 要不要硬实时 + DC 高精度同步? → 伺服多轴插补(CSP 周期 ≤1ms)基本要求 IgH + PREEMPT_RT(或 Xenomai/RTAI),或商用栈。
- 能不能改内核 / 装内核模块? → 不能(如某些嵌入式 Linux、容器环境)则选 SOEM。
- 要不要商业支持与责任兜底? → 要则 Acontis/KPA/TwinCAT。
2. IgH EtherCAT Master(EtherLab)
2.1 架构:内核态主站
1 | ┌────────────────────────────────────────────┐ |
关键点:
- 主站运行在内核:周期帧的组装、收发在内核上下文完成,配合 native 网卡驱动可以把中断路径做到最短。
- 网卡驱动两种模式:
ec_generic:不改网卡驱动,通过内核网络协议栈的 raw 接口收发。部署最简单(任何网卡都能用),但每帧多走一遍网络栈,抖动更大。- native 驱动(
ec_igb、ec_e1000e、ec_r8169等):IgH 为特定网卡型号打补丁的专用驱动,网卡被主站独占、完全绕过 Linux 网络栈。支持的网卡型号和内核版本强绑定,选硬件前先查官方仓库devices/目录和文档。
- 一块网卡 = 一条总线:被主站接管的网卡不再出现在
ip link中作普通网卡使用。 - 配置文件
/etc/ethercat.conf(或发行版对应位置):MASTER0_DEVICE(网卡 MAC 地址)、DEVICE_MODULES(驱动模块名)。
2.2 应用 API:典型生命周期
用户态通过 libethercat(头文件 ecrt.h)与 /dev/EtherCAT0 交互。典型代码骨架(函数名以你所用版本的 ecrt.h 为准):
1 |
|
要点:
| 阶段 | 规则 |
|---|---|
ecrt_request_master 前 |
内核模块已加载、从站已上电(主站会自动扫描总线) |
ecrt_activate 前 |
所有 domain / slave_config / PDO 注册必须完成;激活后配置冻结 |
| 周期循环 | receive → process → (业务) → queue → send 的顺序固定;先收后发,本周期收到的是上一周期发出的帧 |
| DC 模式 | 还需周期调用 ecrt_master_application_time() / ecrt_master_sync_reference_clock() / ecrt_master_sync_slave_clocks()(具体组合以版本文档为准) |
| 实时约束 | 循环内不得 malloc、不得写日志到磁盘、不得调用可能阻塞的系统调用 |
2.3 ethercat 命令行工具
IgH 附带的 ethercat 工具直接与内核主站交互,是不写一行代码就能验证总线的手段(详细排障用法见 07-组网调试与排障.md):
1 | ethercat slaves # 列出从站:位置、状态(INIT/PREOP/SAFEOP/OP)、名称 |
3. SOEM(Simple Open EtherCAT Master)
3.1 架构:用户态、无内核依赖
SOEM 是一个纯 C 库,通过 raw socket(Linux 上 AF_PACKET,Windows 上 WinPcap/npcap)直接收发 0x88A4 帧:
1 | ┌─────────────────────────────┐ |
- 不需要内核模块,不需要网卡专用驱动,
sudo(或CAP_NET_RAW)即可运行 → 部署极简,适合嵌入式和交叉编译。 - 代价:每帧都经过内核网络栈 + 系统调用边界,抖动天花板比 IgH native 驱动高;实时性依赖应用自己做好(RT 调度、绑核)。
- 单进程内嵌主站:主站生命周期 = 应用进程生命周期,没有”多个应用共享一个主站”的概念。
3.2 典型 API 流程
以广泛流传的 simple_test.c 模式为例(函数名基于经典 ec_ 前缀 API;新版 SOEM 2.x 改为显式 context API,以官方仓库当前文档为准):
1 |
|
SDO 访问:ec_SDOread() / ec_SDOwrite()(非周期,配置阶段使用)。
3.3 SOEM 的适用位置
- 嵌入式控制器(RT Linux 板卡、甚至配合移植层跑在 RTOS 上)。
- 工具类程序:扫描器、EEPROM 烧写器、产测脚本。
- 从站开发时的对测主站。
- 轴数少、周期 ≥1ms、对抖动要求不极端的机器。
4. IgH vs SOEM 对比
| 维度 | IgH EtherCAT Master | SOEM |
|---|---|---|
| 运行位置 | 内核模块 + 用户库 | 纯用户态库 |
| 网卡要求 | generic 任意网卡;native 驱动仅支持特定型号(低抖动) | 任意网卡(raw socket) |
| 实时性上限 | 高(native 驱动 + PREEMPT_RT,周期可到 100µs 级) | 中(受网络栈/系统调用抖动限制,1ms 级周期为宜) |
| 部署复杂度 | 高:编译内核模块、匹配内核版本、配置驱动接管网卡 | 低:编译一个库,给权限即可 |
| DC 分布式时钟 | 完整支持(参考时钟同步、SYNC0/1 配置 API) | 支持(ec_configdc + ec_dcsync0),主站侧时钟伺服需应用自己实现 |
| 许可 | GPLv2(内核);用户库许可以源码 COPYING 为准 | GPLv2(历史上带链接例外,以 LICENSE 为准) |
| 多应用共享主站 | 支持(内核主站可被多个用户程序 request) | 不支持(主站内嵌于单进程) |
| 多主站/多网卡 | 支持多个 master 实例(EtherCAT0/1…) | 每进程可 init 不同网卡,冗余口有 ec_init_redundant |
| 命令行工具 | ethercat 工具链完整 |
自带示例程序(slaveinfo、eepromtool 等) |
| 内核版本耦合 | 强(补丁/驱动需随内核维护) | 无 |
| 典型搭档 | ros2_control(ethercat_driver_ros2)、EtherLab、LinuxCNC | 嵌入式、SOES 对测、原型 |
经验法则:多轴伺服 + DC 同步插补 → IgH;快速验证、嵌入式、IO 为主 → SOEM。
5. 实时环境:主站跑得准的前提
EtherCAT 的确定性一半靠总线协议,另一半靠主站按时发帧。普通 Linux 调度下,周期任务可能被随意抢占、迁移 CPU、被中断打断,抖动轻松达到几百微秒甚至毫秒级——这会直接变成 DC 同步误差和从站看门狗超时。
5.1 为什么不能用普通调度
| 干扰源 | 后果 | 对策 |
|---|---|---|
| CFS 公平调度 | 周期任务被普通负载挤占 | SCHED_FIFO 高优先级 |
| CPU 迁移 | cache 冷、唤醒延迟 | isolcpus + CPU affinity |
| 无关中断 | 打断实时任务 | IRQ affinity 移走无关中断 |
| 内核不可抢占段 | 毫秒级延迟尖峰 | PREEMPT_RT 补丁内核 |
| 页缺失/换出 | 不可预期停顿 | `mlockall(MCL_CURRENT |
| CPU 频率调节/C-state | 唤醒延迟 | performance governor、限制 idle 深度 |
5.2 配置 checklist
1 | # 1. PREEMPT_RT 内核(发行版 rt 内核或自编译) |
1 | // 周期任务标准写法:TIMER_ABSTIME 消除累积误差 |
验证手段(cyclictest、抖动统计)见 07-组网调试与排障.md。
6. ESI 与 ENI 文件的角色
| 文件 | 全称 | 谁提供 | 内容 | 谁消费 |
|---|---|---|---|---|
| ESI | EtherCAT Slave Information(XML) | 从站厂商 | 单个从站的身份(Vendor/Product)、SM 配置、可选 PDO 映射、DC 模式、EEPROM 内容模板 | 配置工具(TwinCAT 等)、离线组态;从站 EEPROM(SII)里存的是其精简二进制形式 |
| ENI | EtherCAT Network Information(XML) | 配置工具从 ESI + 拓扑生成 | 整条总线的配置:从站顺序、初始化命令序列、周期帧结构、过程映像布局、DC 参数 | 遵循 ETG.2100 的主站(TwinCAT、Acontis 等)直接加载执行 |
开源栈的差异:
- IgH 和 SOEM 都不需要 ENI 文件。它们在线扫描总线(读 EEPROM/SII、读对象字典),配置由应用代码(
ecrt_slave_config_pdos/ec_config_map)表达——等价于把 ENI 的信息写进了程序。 - ESI 文件对开源栈仍有用:查从站的 PDO 对象、DC 模式参数(如
AssignActivate值 0x0300)、EEPROM 烧写恢复。 - 商用工具链(TwinCAT)走 “导入 ESI → 组态 → 导出 ENI → 主站执行” 的离线流程,可追溯性更好,是量产设备的常见做法。
7. 小结与选型建议
- ros2_control 多轴伺服:IgH + PREEMPT_RT + native 网卡驱动,是社区验证最充分的组合(见下一篇)。
- 嵌入式 / IO 采集 / 原型:SOEM,半天可以跑通第一帧。
- 量产、需认证与支持:评估 Acontis / KPA / TwinCAT。
- 无论哪个栈,实时环境配置(§5)不可省略——主站软件再好,调度抖动 1ms 一样丢同步。
下一篇:06-ROS2与EtherCAT集成.md —— 把 EtherCAT 主站接入 ros2_control 的两条路线。
正在加载留言…