ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

EtherCAT主站IgH跨架构移植与星形拓扑调试实战

EtherCAT主站IgH跨架构移植与星形拓扑调试实战 各位做运动控制、机器人实时通信的朋友应该对EtherCAT不陌生。这个协议在工业现场的地位基本上就是现场总线的天花板。而IgHEtherCAT Master for Linux简称EtherLab作为开源主站方案里最成熟的一个几乎是所有不想碰商业主站协议栈的工程师的默认选择。但问题也往往出在这里。x86-64平台下把IgH跑通网上教程一大堆按部就班基本没问题。可一旦要把主站搬到arm64的板子上或者现场布线没法走标准的菊花链拓扑必须做星形连接多从站各种坑就全冒出来了。我在几个项目里把这两条路都踩过一遍从x86-64的PCIe网卡直连到QEMU模拟arm64验证驱动再到现在在RK3568板子上配合实时补丁跑IgH加上通过Junction和从站的多端口实现星形走线。这篇就把整个调试过程、架构差异、排障链路和星形连接的实现细节一次性讲透给后来的人省点时间。1. 为什么要在两种架构上都跑IgH场景驱动的主站选型逻辑先说动机不然大家容易把这篇当成纯环境搭建教程。工业现场的真实需求永远是你手上的控制器是什么架构你就得让主站跑在什么架构上。x86-64的工控机适合产线改造、嵌入式IPC、视觉检测配合运动控制的场景生态成熟驱动好找但一旦设备走向小型化、低功耗、加固型终端或者卷到电池供电的移动机器人、AGV、医疗设备arm64平台就绕不开了。而IgH的跨架构能力取决于Linux内核、网卡驱动和实时性方案这三者在x86和arm上的表现差异非常大如果不提前搞清楚项目排期会因为一个中断问题直接翻车。另一个关键点是星形走线。很多人对EtherCAT的认知停留在“线型拓扑”或者“菊花链”觉得EtherCAT就只能一台接一台串下去。但EtherCAT协议在设计之初就保留了通过从站交换机端口做树形和星形连接的能力只要从站控制器支持多端口比如LAN9252的Port A/B或者ET1100的多端口乃至带内部交换功能的从站主站无需额外硬件即可从同一个主站端口分出多个分支。这个能力在分布式IO、多机械臂共线、或者现场布线需要绕开障碍物时比强行拉长菊花链要优雅得多。前提是你得会配。关于IgH和SOEM的选型直接说结论。SOEM轻量、无内核模块、用户态搞定适合MCU和移植到RTOSIgH重心在内核态驱动和实时性上主站周期抖动控制得干净协议栈更全面有专门的邮箱CoE/SoE/VoE处理和冗余配置适合对周期确定性要求高的场景。热词里有人问“igh和soem那个稳定”我的答案是如果你跑在带MMU的Linux上、对实时性有硬要求、且需要处理DC同步选IgH如果你跑在裸机或RTOS上选SOEM。两者没有绝对的好坏只有合不合适。2. x86-64平台用PCIe千兆网卡和PREEMPT_RT把IgH跑稳2.1 网卡选型为什么我锁定了Intel I210/I211和RTL8152的取舍IgH对网卡的要求排第一的不是速率而是驱动对EtherCAT帧收发的响应能力。EtherCAT主站发送帧之后从站处理完主站必须立刻把帧收回来中间不能有过长的中断延迟。所以IgH官方推荐的网卡基本都是Intel的IGBI210/I211/I350、E1000E82573/82574这类原因就一条Linux内核的igb和e1000e驱动对NAPI的处理非常干净配合IgH自己的中断上下文处理延迟可控。选I210不仅仅因为它是PCIe接口更关键的是它支持独立的4个队列和足够深度的FIFO以及Intel网卡在Linux下的驱动零拷贝做得很好。你在用IgH的时候IF_RT和链路回调是在软中断上下文里执行的网卡收包后直接DMA到内存IgH的内核模块直接引用这块buffer不做skb拷贝所以延迟低、抖动小。这个特性在x86的IGB驱动下是默认拥有的。RTL8152这种USB转千兆网卡就不要去折腾了。单是USB的中断延迟就够让DC同步崩溃更别提驱动层面的URB处理机制和IgH的中断模型不匹配。我见过有人拿USB网卡跑EtherCAT结果就是OP状态进去了但主站周期一动就“LostLink”或者“No working counter”排查一圈回到网卡。2.2 实时性方案PREEMPT_RT内核补丁的配置细节IgH主站本身跑在内核态严格来说不让用户态控制程序阻塞它也能工作但要真正达到1ms以下的周期并要求抖动小于微秒级别PREEMPT_RT是几乎必须的。这里说几个关键配置内核版本和补丁版本要严格对牢。比如Linux 6.6.119对应的RT补丁是patch-6.6.119-rt不要混用。打开CONFIG_PREEMPT_RT_FULL同时关闭CONFIG_HZ_1000这类高频率但低精度的时钟配置建议使用CONFIG_HZ1000配合高精度定时器HRTIMER。网卡的中断亲和性要绑定到某个专门的CPU核心。EtherCAT处理线程、网卡中断、实时任务最好都钉在同一个核心上避免跨核缓存失效。2.3 编译和装载IgH的过程IgH现在的版本到了2.x比如EtherLab 2.1.2编译依旧三板斧make clean ./configure --prefix/usr/local/etherlab --enable-cycles --enable-rtt-mode make sudo make install这里有个我从坑里爬出来的点configure阶段务必加上--enable-cycles这样会让主站统计周期时间、最坏情况延迟等信息后续通过ethercat master命令能直接看到周期抖动排障必备。装载的时候需要先装载网卡驱动模块再装载IgH的ec_master模块最后装载ec_igb或ec_e1000e这种设备适配模块。顺序错了IgH扫描不到网卡。sudo modprobe igb sudo insmod ec_master.ko main_deviceseth0 sudo insmod ec_igb.ko注意main_deviceseth0这个参数一定要确认eth0对应的是你的EtherCAT专用网卡别把管理网口绑进去了不然主站直接枚举失败。2.4 实操验证从配置到OP状态的完整链路配好之后用ethercat命令行工具检查ethercat master ethercat slaves接着配置从站邮箱和PDO映射把XML配置所谓ENI文件通过ethercat xml导出后用ethercat si加载到从站或者直接在主站里用ethercat upload写SII。在实际项目里我一般把PDO配置写在应用层通过IgH的用户态库libethercat的ecrt_master_slave_config来完成这样不用依赖外部工具调试更加可控。从INIT到PREOP再到SAFEOP最后到OP每一步都要看状态机转换是否正常。如果卡在PREOP转SAFEOP基本都是邮箱通信CoE没配对或者是从站的同步管理器SM通道没配好如果在SAFEOP转OP时失败多半是process data的映射长度和从站实际配置不符数一数WKC工作计数器你就明白了。3. arm64平台从QEMU模拟验证到RK3568实机移植3.1 QEMU模拟arm64在拿到开发板之前先把驱动问题暴露掉arm64和x86-64最大的不同是不一定有PCIe插槽给你插I210就算有很多arm板子的PCIe通道走的是MiniPCIe或者M.2 Key B驱动加载方式、中断路由、DMA地址映射都不一样。而更常见的情况是arm板载的网卡是瑞昱RTL8211F、裕太微YT8512、或者In搭载内部的MACPHY方案这些网卡IgH官方不一定直接支持你需要自己写或适配lb驱动这就更有挑战性了。QEMU模拟arm64环境的好处是你可以在没有板子的情况下先验证内核配置、驱动框架、IgH的EC-Master能不能在arm64上编译装载甚至跑一轮虚拟的EtherCAT如果qemu虚拟出网络设备的话。虽然QEMU的虚拟网卡性能和中断行为跟实机差异巨大但至少能把“编译不过”、“模块装载失败”、“地址空间映射不对”这些低级问题提前消灭。qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 4096 \ -kernel vmlinuz-6.6.119-rt -initrd initrd.img \ -append consolettyAMA0 root/dev/vda rw \ -device virtio-net-pci,netdeveth0我在QEMU里主要是验证arm64的IgH代码路径有没有架构相关的错误比如dma_alloc_coherent的API差异、iomem的访问方式、以及内核模块的module_platform_driver结构。真正跑EtherCAT从站还是在实机上才靠谱。3.2 RK3568上面的踩坑设备树、PHY驱动和中断绑定正点原子的RK3568板子在热词里被点名了确实这块板子做EtherCAT主站是比较实惠的。RK3568带一路千兆GMAC和一个PCIe 3.0 x1接口可以插一个PCIe网卡当EtherCAT专用网卡或者直接用板载GMAC。用板载GMAC的步骤如下设备树里把GMAC对应的节点使能PHY选择正确比如rk3568-evb.dtsi里一般有gmac0或者gmac1确认phy-mode是rgmii还是rmii。PHY芯片需要有一个可用的mdio总线地址中断可以不用但链路检测要可靠。网卡驱动用的是stmmacIgH官方不支持但可以通过IgH的generic网卡驱动来跑。方法是配置的时候指定驱动API为generic前提是网卡驱动能够被IgH正确接管。./configure --prefix/usr/local/etherlab \ --enable-cycles \ --with-linux-dir/path/to/kernel \ --enable-generic然后装载insmod ec_master.ko main_deviceseth0 insmod ec_generic.ko注意generic驱动不认识EtherCAT的帧结构但IgH会在链路层直接接管网卡的接收/发送函数通过修改驱动私有数据来把帧接住。这个方案要求网卡本身不是USB这类高延迟设备并且NAPI回调要干净。如果RK3568上用的是PCIe网卡插I210那反而省心ec_igb驱动直接支持。但要注意arm64下的PCIe MSI中断和DMA配置设备树里pcie节点要开启msi并增加dma-ranges否则DMA分配不出来。3.3 arm64下的内存屏障和DMA一致性处理arm64的DMA一致性和x86差别巨大。x86有强内存序TSODMA基本所见即所得arm64是弱内存序设备驱动里做完寄存器操作必须用dma_wmb()或者dma_rmb()保证DMA描述符和buffer的可见性。IgH的ec_master在arm64上编译时代码里本身就用了内核提供的DMA屏障API但你要确认选用的网卡驱动也有正确的屏障。stmmac驱动在这个方面还算完整但某些国产PHY的驱动可能存在内存屏障缺失导致收包时偶发掉帧。从实测来看arm64上如果用generic驱动建议把NAPI的weight调低一点比如设成32或者16这样可以缩短每次收包批处理的数量降低链路层到一个服务周期内的输入延迟对实时性有明显帮助。3.4 实时补丁在arm64上的应用差异arm64上跑PREEMPT_RT有一些特殊性。x86上可以全内核开启RTarm64上也行但要注意arm64中断控制器GIC的中断亲和性通过irq_set_affinity_hint把网卡中断绑定到某个CPU核。时钟源的精度取决于arch timer一般没有问题。板子的固件可能会限制某些中断为不可屏蔽FIQ这会导致RT补丁的优先级反转问题需要查内核日志里的irq 296这类FIQ警告。在RK3568上我实际跑过的配置是Linux 6.6.119-rt IgH 2.1.2 ec_igb通过PCIe插I210 PREEMPT_RT周期1ms抖动实测最坏5微秒。如果用板载GMAC ec_generic抖动最坏到15微秒左右。不算完美但很多场景够用了。4. 星形走线连接多从站从Junction到多端口从站的部署实操4.1 EtherCAT星形连接的基本原理很多人把EtherCAT想得太线性了。EtherCAT数据帧是一条环状逻辑但物理拓扑可以是线形、树形、星形或任意组合。关键是从一个站出来一个口进去叫菊花链如果一个从站有多个下行口每个口再接一条链那就形成了分支即树形/星形。EtherCAT的星形连接本质上是利用从站的端口转发机制普通从站两端口负责直通转发pass-through带三个或四个端口的从站可以根据帧目标地址判断要不要把数据帧往某个端口转发帧从主站发出到达一个分支点从站该从站把帧复制到不同端口每个分支各自的回报帧再通过分支点汇聚回主站。实现星形连接的核心是每一个分支口都必须有自己独立的从站控制器ESC上下文或者端口交换逻辑。最经典的方案是Beckhoff的ET1100从站芯片它有三个/四个MAC口可以配置为分支模式还有Microchip的LAN9252有两个端口但可以把它串联起来或者用它的菊花链特性构建分支。如果你要做的星形走线是一个主站端口下带多个从站群建议选择支持多端口的从站芯片方案或者在分支点单独放一个带交换功能的从站模块。4.2 IgH下星形连接的配置别名与拓扑IgH配置星形连接不需要特殊设置主站参数但从站地址的管理要注意在总线扫描时IgH按照拓扑顺序为从站分配地址。星形连接下分支点的从站在下行端口上会“广播”一串从站IgH会扫描到哪些从站依赖于拓扑结构逻辑顺序和物理顺序不一定对应所以强烈建议在从站配置里设置别名alias。IgH的ethercat alias命令可以给从站添加一个用户定义的别名这样应用层配置的时候可以直接通过别名寻址不依赖物理位置。对于分支端口Linux主站侧的帧头目标地址使用逻辑寻址如FMMU映射从站的端口转发是基于ethercat报文头的地址区域判断的和主站没有直接关系。你只要确保分支从站的三个端口都正确接线、CRC和链路检测正常主站扫描就能看到多条分支的从站。4.3 星形拓扑下PDO映射和DC同步的注意事项星形连接对DC同步会产生影响。原因是不同分支的数据帧到达时间不同分支点后的从站收到SYNC信号的时间可能晚于主干上的从站如果所有从站都按全局DC做同步那么后分支的从站必须在收到帧后极短时间内处理完过程数据。建议的做法分支后的从站尽量使用FreeRun模式自由运行或者单独设置DC偏移量如果应用要求所有从站严格同步务必计算分支长度带来的传播延迟通过配置从站的System Time和Sync0周期来抵消IgH本身支持每个从站独立配置DC你需要用ecrt_slave_config_dc()为每个从站单独配置同步源和周期。实测下来分支长度在5米以内自由运行模式下同步误差可以忽略如果超过20米建议在分支点后布置一个分布式时钟从站降低累积误差。4.4 实测星形连接的拓扑和验证步骤假设我这边两路分支主站网卡 → 分支从站1LAN9252带两个下行口分支1下行口 → 伺服驱动器1然后菊花链伺服驱动器2、3分支2下行口 → 模拟量IO从站然后菊花链数字量IO从站配置步骤先用普通线形拓扑把分支从站1单独挂到主站确认它扫描正常并能配置PDO。把分支从站1的两个下行口分别接两条分支链但别同时接入先接一路扫描确认无错误。再接第二路分支观察ethercat slaves是否完整枚举。如果缺失查分支点后的线缆质量和从站供电。用ethercat pdos和ethercat mapping确认每个分支的从站映射都正确。最后跑周期任务用ethercat master看周期时间和最坏情况延迟。如果分支口上的从站全部枚举正常但主站状态在OP时频繁报“Lost Frames”大概率是分支长度导致信号完整性下降需要降低传输速率从100Mbps降低到10Mbps或者换更高质量网线。5. 调试实录igh进入OP读不到数据、EOE禁用、和常见Bug排查链路5.1 第一个坑进入OP状态却读不到任何过程数据这个现象在IgH上非常典型我见过不止一次。现象是这样ethercat slaves能枚举出从站状态机也能够正常推进到OP但是应用层通过用户态调用ecrt_master_receive()和ecrt_domain_process()之后读到的过程数据全是旧的或者全零。排查链路我建议这样走首先确认master状态机已经进入OP通过ethercat master和ethercat states确认。用ethercat pdos查一下当前从站的PDO分配是否和你期望的映射一致。很多时候从站的默认PDO含有大量未启用的对象但主站默认使能的可能不是你需要的那个PDO。重点检查FMMU配置。IgH中域domain里的每个从站入口通过ecrt_slave_config_domain()关联FMMU由主站在初始化时自动配置。如果你在应用初始化时没有把从站配置加入domain过程数据就收不到。检查SKEW和DC寄存器从站侧是否正确置位。有的从站在SAFEOP之前不会返回有效的过程数据状态需要在PREOP阶段手动初始化从站的应用控制寄存器。用ethercat debug抓包或者在内核模块里打开EC_DBG_ENABLE配合dmesg观察是否有PROCESS DATA ERROR。最常见的问题反而是PDO映射里的变量偏移没对上。记住IgH的domain数据buffer是按位偏移排列的从站的SDO对象映射不是简单字节对齐错一个bit整个域的词汇表就全乱了。5.2 第二个坑为什么要禁用EOEEOEEtherCAT over Ethernet是把普通以太网帧封装在EtherCAT邮箱通道里传输的一种方式。从功能上看确实很方便可以让EtherCAT线缆顺带传输IP数据省一条物理网线。但IgH官方文档和社区大神都非常明确地建议生产环境禁用EOE。原因有三EOE在IgH的实现是纯用户态库lrhoe内核模块本身不做完整的TCP/IP栈所以EOE传输的实时性和确定性很差它依赖主站的周期调度如果周期紧张EOE帧会被推迟或者丢弃。EOE的数据会占用DC时钟域内的带宽预算影响实时过程数据帧的传输。特别是在周期1ms以内时EOE几乎必然破坏主站周期。IgH内核模块中默认会开启EOE支持但如果你没有使用EoE建议编译时直接--disable-eoe或者启动后不注册任何EoE设备。否则IgH会在每个周期内预留EOE的处理时间造成不必要的抖动。我在某个项目里因为从站之间距离远想用EoE传送摄像头数据结果主站周期从500us掉到2ms过程数据频繁丢包。后来老老实实拉了一条独立网线给视觉系统EtherCAT线缆只跑实时数据问题立刻消失。5.3 第三个坑IgH有Bug星形连接下从站地址错乱“igh有bug啊”这种说法大概率就是拓扑扫描和别名配置的问题。IgH在发现多个分支从站时如果它们的拓扑被物理地址自动编号你在应用里写的从站地址可能对不上。这不是IgH的bug而是EtherCAT规范下的地址自动分配方式和你的预期不一致。解决方法给每个从站设置静态别名用ethercat alias set position alias或者通过SII写EEPROM完成。应用代码里用别名访问从站做主站配置。不要依赖扫描顺序尤其是星形拓扑下扫描顺序和物理布局没有关系。5.4 第四个坑LS1028A、RK3568这类开发板的dma_alloc_coherent失败在arm64板子上如果用ec_generic加载模块时可能会报dma_alloc_coherent size 0x1000 failed之类的错误。这个问题的根源是DMA内存池不足或者配置错误。检查设备树中是否有dma-coherent属性如果没有驱动会用非一致性的DMA映射IgH的generic驱动不一定支持。内核的CONFIG_CMA大小是否足够如果CMA池太小大块DMA内存分配容易失败。也可以试试在cmdline中增加coherent_pool2M增加一致性DMA内存池的大小。5.5 第五个坑x86-64和arm64上的EtherCAT主站实时性验证最后无论哪种架构都建议做一次实时的标准验证周期任务跑500us持续运行至少2小时用ethercat master调出周期抖动日志统计最坏延迟。x86平台上的IGB驱动最坏延迟基本可以控制在10us内arm64的generic驱动可能会到50us甚至更高这个结果基本决定了你能否继续用这个平台做高精度同步控制。6. 进阶补充从QEMU验证到实机的移植流程如果你做的项目是全新的控制器平台建议先QEMU验证、再上实机流程大概是在QEMU的arm64虚拟机里编译带上IgH的内核模块。这一步会暴露架构相关问题。在虚拟机里配置好IgH的驱动测试环境至少验证模块能装载、主站能扫描到虚拟设备如果QEMU支持虚拟EtherCAT从站的话可以自己模拟一个简单的网卡回环但实际意义有限。把相同的内核配置搬到实机加载IgH接上真实从站进行链路层调试。确认链路层无问题后再调试实时性配置RT补丁和中断亲和性。我建议的arm64平台配置如果预算允许组件推荐选项理由CPURK3568 / i.MX8M Plus / LS1028A有PREEMPT_RT支持社区案例多EtherCAT网卡板载GMAC或PCIe转I210I210最好GMAC次之IgH版本2.1.2稳定版功能全社区活跃内核6.6 LTS RT补丁长期维护rt补丁成熟实时方案PREEMPT_RT配置简单日常够用如果对抖动要求极高进一步考虑Xenomai或RTAI但那样整个应用层也要改造不建议轻易尝试。这套组合我用它跑过龙门双驱直线电机同步两个从站每轴一套星形连接、分布式IO采集、以及带编码器反馈的闭环伺服控制。只要从站侧的DC配置好主干和分支的线缆都符合规范运行几个月的稳定性完全能保证。调试EtherCAT主站说到底考验的是对协议状态机、网卡驱动和操作系统实时性的综合理解。x86-64和arm64的调试路径差别很大但核心思路一致先链路层再状态机再过程数据最后才是实时性优化。希望这篇把星形连接和跨架构移植的坑都点到了能帮你在现场省下几天熬夜查日志的时间。
返回列表