简介:这套代码是基于IgH EtherCAT Master 1.5.2的实践开源项目,面向工业以太网总线开发者,尤其适合需要驱动伺服电机和IO板卡、学习PDO/SDO通信的工程师。资源共113个文件,以头文件(h)、源文件(c)、Makefile、Shell脚本和动态库(so)为主,整体压缩包仅1.25MB,便于快速获取与交叉编译。项目包含Sanyo、泰科伺服电机的力矩模式控制实例,覆盖电机使能、模式切换、力矩指令下发与反馈读取;同时提供ET1000 IO板的PDO/SDO控制及温湿度读取代码。代码区分ioctl原生接口和libethercat库两种调用方式,并附带二次封装库ecat_common_intermediate_interface,方便适配不同厂商设备;scripts目录可自动生成从站PDO/SDO配置,附有Ethercat调试问题记录。目前已有1091人学习,适合有一定EtherCAT基础并希望参考完整工程实现的开发者。
1. 从现场抖动到软主站:IgH EtherCAT 主站包的落地笔记
某项目,6 轴伺服联动,使用板卡方案在高速同步段开始丢脉冲。后来我们把主站换成了基于 IgH EtherCAT master 协议栈的软主站,载体就是 ethercatpack.7z 这个缩包。换来之后,一张普通千兆网卡直接吃 100us 周期,6 个伺服轴稳定在 OP 状态运行。刚拆这个包的人,最先容易被三个词唬住:PDO、SDO、DC。实际上,它们分别对应周期数据交换、非周期读写和从站时钟同步,每一条都有清晰排查路径。这篇笔记按我拆包的顺序展开:先讲协议栈结构,再讲编译加载,然后落到 PDO/SDO 的配置和具体踩坑,最后一章给你验证抖动的方法。适合刚接手软主站的电气工程师和嵌入式开发,新手能跟着来,熟手也能找到参数边界。
2. 主站协议栈选型:先分清 PDO、SDO 和 DC 再动手
2.1 EtherCAT 的主从框架与从站控制器
EtherCAT 在物理层用标准以太网线,但逻辑上和你熟悉的 TCP/IP 完全不同。主站发出的一帧报文会流过一串从站,每个从站内部的从站控制器硬件在帧经过的瞬间完成数据读取和插入,再传给下一站。注意,这个动作是硬件完成的,不是从站 CPU 跑出来的。所以你评估软主站时,心里要有两个边界:主站侧用 CPU 算周期,从站侧用硬件来消化帧转发延迟。实测中,一个 8 字节的从站数据改动,帧时间增量很小,但主站频率上去之后,CPU 占用会按字节数线性上涨,这点在设计轴数和 IO 点规模时要想清楚。
通用网卡驱动为什么能跑出微秒级周期?因为 IgH 主站模块绕过 Linux 内核标准协议栈,直接从网卡驱动层收发 EtherCAT 帧。这也是选型时不该自己写 socket 收包的原因。IgH 帮你把网卡收发、帧排队、从站状态机全部封装进内核模块,用户态只调用 API,接口成熟,比从零开始啃链路层协议省太多事。
2.2 PDO:过程数据的快递专线
PDO 全称 Process Data Object,按照对象字典里的映射关系,把输入和输出数据组装成固定长度的数据段,在每一个周期内随 EtherCAT 帧在网线上跑。名字里带周期两个字,是它的命根子。伺服驱动器的实际速度、扭矩、状态字走 PDO 上行,目标位置、控制字走 PDO 下行。
实践里只需要记一个公式:PDO 映射等于地址加上长度再加上偏移。地址就是对象字典的索引和子索引,长度由数据类型决定,偏移是整个 PDO 域里的相对位置。一个域就是多组 PDO 映射凑成的一段连续缓冲区。常见做法是先创建域,再把每个从站的 PDO 配置挂到域上,之后在实时循环里对这缓冲指针做拷贝。
可以用下面命令直接看从站上报的 PDO:
ethercat pdos -p 0参数说明:-p 0 固定扫描第一个从站,输出是这个从站配置的 RxPDO 和 TxPDO,每条 PDO 下列出映射的对象字典条目。看到这行输出,你才知道这套从站实际支持哪些周期数据,而不是靠猜。这里有一个容易被忽略的点:PDO 的长度单位可能是位,也可能是字节,要看从站 ESI 文件里的定义,很多第一次上手的人在这上面栽跟头。
2.3 SDO:对象字典的点对点客服
SDO 和 PDO 不同,它走的是邮箱通道,非周期、按需、一次一答,常用于配置参数、读故障记录、修改增益这类不需要每个周期都刷的数据。SDO 请求必须带上对象字典的 16 位索引和 8 位子索引,服务端回应可能分段传输,所以延迟不稳定,几十微秒到几毫秒都可能。
执行下面命令,把一个 32 位参数写入从站对象字典:
ethercat download -p 0 -t uint32 -c 0x6060 0 8这个命令不复杂:-p 0 选第一个从站,-t uint32 声明数据类型是 4 字节,-c 0x6060 0 指定对象字典地址,8 是写入值。对伺服驱动器来说,0x6060 通常是运行模式选择,值 8 是 CiA402 里的循环同步位置模式。写错索引时,从站会返回 abort 码,命令行工具会把它打出来,直接看码后面的说明去查就行。
注意,别把 SDO 写进实时循环。控制周期里只能放 PDO 数据拷贝,SDO 要放到初始化阶段或者慢速任务里,否则一次邮箱延迟波动会把你的周期抖动直接拉大几十倍。
2.4 DC 分布式时钟:多从站同步的关键
DC 不是必须开,但联调多轴时几乎总会开。每个从站有本地自由运行时钟,主站以第一个支持 DC 的从站为参考时钟,在运行中通过周期写入时间戳校准所有从站时钟偏差,再通过 SYNC 事件拉齐从站采样和输出时刻。
开了 DC 后,建议运行:
ethercat master看输出里的周期统计和从站时钟校准量。如果校准量稳定在个位数微秒以内,说明两侧晶振偏差被压住了;如果每次启动校准量都跳到几十微秒,多半和网卡驱动有关,要回到编译章节的网卡选型部分处理。我一般会拿同一组从站在不开 DC 和开 DC 两种配置下各测一次,用第 5 章的测量方法对比。对比结果能帮你判断抖动是来自主站调度,还是来自从站时钟偏差。
2.5 选型结论:软主站到底适合什么场景
| 对比项 | IgH 软主站 | 专用控制卡 |
|---|---|---|
| 周期能力 | 通常 100us 到 1ms,看 CPU 负载 | 50us 以下更稳定 |
| 扩展性 | 加轴等于加从站和内存 | 受卡上资源限制 |
| 灵活性 | 源码可改,协议行为可见 | 黑匣子,只能依赖厂商 API |
| 调试成本 | 内核模块加 dmesg 日志 | 厂商工具配合 |
| 上手难度 | 要懂 Linux,会编译模块 | 用 SDK 相对直白 |
如果只跑 1ms 周期、几十个 IO 从站,控制卡和软主站差别不大;要做 100us 周期且从站批量映射,IgH 的源码可读性就值回票价。反过来,只有两三个轴、希望开箱即用,专用卡更省时间。软主站的坑集中在实时性调度和协议栈配置上,控制卡的坑通常在后端支持和响应速度上,这一条要在立项时就想好。
3. 解包、编译、起主站:ethercatpack 落地的三个硬步骤
3.1 先清点包内文件
把 7z 压缩包解开:
7z x ethercatpack.7z cd EtherCATMaster tree -L 1输出一般是这几个目录:
EtherCATMaster/ ├── master/ # 内核模块源码 ├── devices/ # 网卡驱动模块源码 ├── tool/ # ethercat 命令行工具 ├── lib/ # 用户态库 ├── examples/ # 最小示例 ├── Documentation/ # PDF 和启动说明 ├── configure # 配置脚本 └── Makefile注意,tree -L 1 只列一层,避免把源码树深层结构刷屏。真正需要重点看的只有三个:master、devices 和 tool,examples 留到后面写应用时参考。
如果解压后没有 configure 脚本,只有 Makefile 和 Kbuild,说明这个版本走的是内核树外编译,你需要直接看 Makefile 里的 kbuild 段,里面有模块目标名。不要急着改代码,先把 README 过一遍,版本号和内核版本匹配关系通常写在第一屏。
3.2 编译前置:内核头文件必须精确匹配
这是最常见的翻车点。软主站本质是一个 Linux 内核模块,它要编译进哪个内核,就必须用那套内核的头文件。检查命令:
uname -r dpkg -l | grep linux-headers-$(uname -r)第一行拿到正在运行的内核版本,第二行确认系统里装了同版本内核头文件。如果第二行输出为空,说明没装或者版本对不上。常见做法是用 apt 或 yum 安装 linux-headers-$(uname -r),装完后再跑一次 grep 确认。
还要确认网卡。IgH 默认带一个通用千兆驱动模块 ec_generic,它不需要知道具体网卡芯片寄存器,但对网卡中断行为要求较高。有的板载网卡在压力下会丢中断,导致周期毛刺,而 dmesg 里看起来一切正常。我的经验是第一次实验务必用独立 PCIe 千兆网卡,不要用 Wi-Fi 或有线自动协商的复杂环境,也不要接交换机,主站网口直连第一台从站。
3.3 配置、编译、安装内核模块
./configure --prefix=/usr/local/ethercat --enable-generic --disable-werror make sudo make modules_install sudo make install参数说明:--prefix 决定用户态工具和库的安装根目录,后面所有命令都要认这个路径;--enable-generic 会编译通用网卡驱动模块 ec_generic;--disable-werror 是为了避免编译器把警示信息当错误,老内核配新 gcc 时经常需要这一句。如果中间报缺少头文件,回 3.2 补包,不要带着错误继续跑。
模块装好后,立即用 modinfo 查看生成的模块:
modinfo /lib/modules/$(uname -r)/kernel/drivers/net/ethercat/ec_master.ko这个命令列出模块依赖和参数名,比如 main_devices。如果 modinfo 显示未知参数,说明你安装的模块和当前内核不匹配,需要重新编译,别在这里浪费更多时间。
3.4 加载主站模块并扫描从站
加载顺序是先 ec_master,再 ec_generic。通用驱动会在模块加载时查看所有网卡,把没有被系统网络栈占用的网卡接管为主站设备:
sudo modprobe ec_master sudo modprobe ec_generic sudo dmesg | tail -30看到内核日志里出现 EtherCAT master 已创建的关键字,说明主站起来了。然后使用命令行工具:
sudo /usr/local/ethercat/sbin/ethercat slaves如果输出为空或显示没有发现从站,不要先怀疑主站,先检查网线连接和从站供电。正常时输出会按总线拓扑顺序打印从站序号和名字。
另一个经常被忽略的步骤是设置设备访问权限:ethercat 工具默认要读 /dev/EtherCAT0 设备节点,建议写一条 udev 规则把设备属主改成你的用户组,否则后面每次调命令都要 sudo,写日志和自动化脚本会很难受。系统开机自动加载,就把 modprobe 命令写进 /etc/modules,同时在 /etc/modprobe.d/ 里加一行,指定主站绑定哪块网卡,比如 options ec_master main_devices=00:11:22:33:44:55。这样服务器重启后主站设备不会莫名换到另一块网卡上。
4. PDO/SDO 实战与常见问题避坑:配置命令、API 调用和五条踩坑
4.1 域和从站 PDO 配置:一段最简主站代码
建立域和从站配置的惯用套路是写一个小程序,使用用户态库的 API。下面是最简配置骨架:
#include <ecrt.h> ec_master_t *master = ecrt_request_master(0); ec_domain_t *domain = ecrt_master_create_domain(master); ec_slave_config_t *sc = ecrt_master_slave_config( master, 0, 0, 0x00000000, 0x00000000); ecrt_slave_config_pdos(sc, EC_END);代码逻辑:ecrt_request_master 申请 0 号主站设备;ecrt_master_create_domain 创建一块域缓冲,所有 PDO 数据都映射进这块内存;ecrt_master_slave_config 把从站地址固定为总线上第 0 个从站。注意第四个和第五个参数分别是厂商号和产品号,真实从站要用 ESI XML 文件里的值替换,否则可能匹配不上。ecrt_slave_config_pdos 后面跟的是一组 PDO 描述,示例里用 EC_END 结尾占位,实际代码要把 RxPDO 和 TxPDO 的参数全部列清楚。
这段配置建议单独放进一个文件,比如 slave_config.c,它只负责把运动控制相关的映射表写明白,主循环不掺和。这样后面更换从站型号时,只需要改这一处的 PDO 映射表,其他代码不用动。
4.2 SDO 的两种读写姿势
命令行姿势适合现场排查:
ethercat upload -p 0 -t uint16 0x6040 0 ethercat download -p 0 -t uint16 0x6040 0 0x0006第一行读控制字,第二行把控制字写成 0x0006。upload 和 download 的参数格式固定:-p 从站序号,-t 数据类型,后面跟上对象字典的 16 位索引、8 位子索引,download 最后多一个值。如果你的从站对写入有保护,比如运行时不允许改模式,它会返回 abort 码,绝大多数情况是命令写得太急,等从站进入目标状态后再写一次就行。
程序里姿势是这样:
uint32_t value = 0; size_t size = 4; uint32_t abort_code = 0; int ret = ecrt_master_sdo_upload(master, 0, 0x6040, 0, &value, &size, &abort_code);代码逻辑:最后两个参数是返回结果,abort_code 在失败时用来解释原因,ret 为 0 才表示成功。这个 API 不能在实时循环里调用,因为 SDO 邮箱通信要等从站调度,一次可能几十毫秒,会直接冲毁周期。常见的误用是把它放在控制任务里读参数,前几次可能正常,从站响应稍慢就周期超时。
4.3 踩坑一:从站状态卡在 INIT,进不了 OP
现象:ethercat slaves 能列出从站,但状态永远停在 INIT,手动发 PREOP 也推不上去。
原因:多数情况是从站邮箱服务没起来,或者主站配置里没有包含从站要求的同步管理器设置。盒子里给的示例配置往往面向特定从站,你换型号后必须重新生成 ESI 匹配信息。
解决:先用命令行强制切状态,再逐条查 dmesg:
ethercat states PREOP ethercat states OP dmesg | tail -20如果还卡住,逐个从站手动设置状态,观察哪个从站先报错。确认是同步管理器配置后,回到 4.1 的配置代码里补齐 sync 参数。
4.4 踩坑二:PDO 数据错位,轴读数漂移
现象:速度值读出来固定不变,位置偶尔跳变,但通信本身没有报错。
原因:PDO 映射里子索引顺序写错,或者数据类型声明长度和实际不一致,导致域缓冲偏移整体错位。这个问题在只有一两个从站时不容易显形,轴多了以后互相干扰特别明显。
解决:用 ethercat pdos 打印从站实际生成的 PDO 布局,逐条对照代码里的映射表,重点核对每个对象字典条目的长度参数,以及子索引的排列顺序。别信从站说明书上的默认顺序,要以实际打印输出为准。
4.5 踩坑三:SDO 写入超时或返回 abort
现象:ethercat download 命令执行后卡住几十秒,最后返回错误码,dmesg 里能看到邮箱超时记录。
原因:从站处于 SAFEOP 或 OP 状态时,部分对象字典被保护,某些模式切换写不进去;还有可能是上一次 SDO 交互没有正确结束,邮箱通道被占用。
解决:先确认从站当前状态,把控制字写回到待机状态,再执行 SDO 写入。遇到 abort 码,查从站对应的对象字典说明,多数情况是值域不合法。五分钟解决不了就复位从站,重新走一遍状态机,不要在同一地址上反复试。
4.6 踩坑四:开了 DC 后抖动反而变大
现象:关 DC 时抖动在 10us 左右,开 DC 后涨到 50us,轴运行时有轻微噪声。
原因:主站网卡驱动中断处理不及时,SYNC 校准窗口一直在漂。更深层的原因是网卡中断没有绑定到固定 CPU 核,中断在多个核之间跳,实时线程和中断处理互相打断。
解决:把网卡中断绑到实时线程同一个 CPU 核上,用 irqaffinity 设置;再把实时线程优先级提到 SCHED_FIFO 80 以上。如果还是没有改善,直接换独立 PCIe 千兆网卡,板载网卡的晶振和中继电路质量经常在这里拖后腿。
4.7 踩坑五:重启后主站网口漂移
现象:系统本来跑得好好的,重启后 ethercat slaves 找不到从站,日志显示主站绑定了另一个网口。
原因:模块加载时没有显式指定网卡 MAC,系统枚举网卡顺序变了,主站接管了错误的网卡。
解决:在 modprobe 配置里固定 main_devices 参数为网卡 MAC,同时写 udev 规则用 MAC 生成固定网卡名。加载顺序固定之后,这个问题基本绝迹。
五条现象都是实操踩过的,前两条是环境问题,后三条是配置和机制问题。排查顺序建议始终是环境、状态机、同步配置,直接跳到最后一步通常会绕远路。
5. 看得见的周期与抖动脉冲:主站验证技巧
5.1 主站状态统计和测量方法
先验证主站健康度,运行:
ethercat master输出里通常有实际周期平均值和最大抖动,平均周期接近理论值且最大抖动稳定,初步判定通过。更严格的方式是把一个从站输出口配成测试信号,用示波器看信号周期波动。没有示波器时,在实时循环里记录两次 clock_gettime 的差值,累计 1000 个周期后取最大值和标准差。常见做法是把统计任务挂在独立慢速线程上,不影响控制路径。
5.2 优先级和中断绑核
调优先级收益相当明显:给主站实时线程设 SCHED_FIFO 优先级 80 到 99,给网卡中断设置 irq_affinity 固定到同一 CPU 核,避免中断在核间跳动。这个操作对 100us 周期影响最明显,强度不大,但做完后抖动统计往往能直接降一个档位。
有一次我把所有功能调完,周期统计看着正常,但轴一动就偶发报警,后来发现是主站没开 DC 且从站本身同步窗口设得过大。从那以后我每次部署完毕都会强制检查三件事:从站状态全部处于 OP、主站 dmesg 里没有周期超时记录、ethercat master 的抖动统计低于预期值的一半。复核通过才算调完。希望这些坑和技巧帮到你,少走这一段弯路。
本文还有配套的精品资源,点击获取