ARTICLE DETAIL

资讯详情

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

Linux下EtherCAT主从站实战:IgH主站与LAN9252从站联调指南

Linux下EtherCAT主从站实战:IgH主站与LAN9252从站联调指南 EtherCAT主从站这套东西说实话我刚接触的时候也头大。协议栈、ESC芯片、主机驱动、实时性调试每一环单独看都有文档但真正把它们串起来跑通还是踩了不少坑。最近我把主站跑在RK3568的Linux上用的IgH开源主站从站则是一块基于LAN9252的IO板卡后面又挂了一个LAN9253的采集节点整套链路从零开始调通前后花了三周多。这篇实战指南就是把这段时间的选型思路、从站设计要点、Linux主站配置、联调步骤和排障经验完整记录下来内容同时覆盖主站侧和从站侧适合正在做EtherCAT开发、手里已经有硬件但不知道从哪里下手的工程师参考。1. 方案选型为什么是Linux IgH LAN9252/92531.1 主站方案商业主站和开源主站怎么权衡EtherCAT主站方案其实不算少商业的有倍福TwinCAT、KPA、Acontis等开源的主流就是IgH EtherCAT Master。我做这个项目之前先明确了一点是要快速跑通验证还是要能深度定制。如果只是配合倍福的PLC使用TwinCAT无疑是最省事的但它是基于Windows的而且要往自研ARM板卡上移植几乎不可能。Acontis这类商业主站功能完整、支持好但授权费用对很多中小项目来说不低而且同样是黑盒出了问题只能提工单。我最终选了IgH原因有三个第一它开源代码结构清晰出问题可以直接跟踪到内核模块里第二它支持通用网卡驱动在x86和ARM上都能跑正好契合我要在RK3568上做主站的需求第三社区活跃参考资料相对多遇到问题不至于完全没地方问。IgH在Linux上的形态是一组内核模块加一套用户态工具。核心模块是ec_master它负责EtherCAT帧的收发、状态机管理和DC分布式时钟同步。实际使用时还需要一个网卡驱动模块比如e1000e、igb如果不限定具体网卡就用ec_generic通用模块。用户态工具是ethercat命令能查询从站信息、配置PDO、控制主站启停调试阶段基本离不开它。1.2 从站方案LAN9252/9253到底适合做什么EtherCAT从站和普通以太网设备最大的区别在于从站的数据交换是靠专用的ESC芯片完成的也就是EtherCAT Slave Controller。LAN9252和LAN9253都是Microchip的从站控制器核心协议处理完全由硬件完成主CPU不需要一帧一帧解析EtherCAT报文只需通过PDI接口读写过程数据就行。LAN9252集成度比较高适合做体积紧凑的从站板卡比如数字量IO、模拟量采集、简单伺服接口这类末端节点。它的外围电路相对简单晶振、电源、网络变压器加上去就能跑起来省掉了很多模拟前端设计的麻烦。LAN9253则适合用在需要更多端口的链式拓扑里做中间节点或者需要多路分支的场合。实际项目中我通常把LAN9252用的末端IO上LAN9253放在两个链路段中间这样既控制了成本也能保证级联能力。可能有人会问为什么不选ET1100或者AX58100。ET1100是老牌ESC芯片性能很强但外围时序要求高并行接口用起来比LAN9252的SPI麻烦AX58100价格有优势但开发资料和兼容性验证相对少。LAN9252/9253对硬件设计友好SSC从站协议栈支持也完整所以我选了这一系。1.3 整套系统的硬件拓扑这套系统的结构非常典型RK3568主板作为主站设备Linux系统里跑IgH主站EtherCAT数据从主板的一个千兆GMAC口出来通过网线进入第一块LAN9252从站板再级联到后面的LAN9253节点最后回到主站。主站每发一帧数据从站边收边转每个站都把属于自己的那部分数据填到帧里或取走然后继续往后传。这个“边收边转”的机制就是EtherCAT高效的关键。你可以把它想成一条流水线一个包裹从首站出发经过每个工位时工位只处理和自己相关的货物然后立刻把包裹传给下一个工位。它和你平时上网那种“请求-应答”模式完全不同所以主站和所有从站之间并没有网络延迟叠加的问题一个扫描周期能把整条链路的输入输出全部刷新一遍。2. 从站硬件设计与LAN9252核心机制2.1 LAN9252最小系统设计要点从站硬件这块我吃过不少亏。先列一个LAN9252最小系统的配置25MHz有源晶振、3.3V核心供电和VDDIO分组、网络变压器和RJ45、SII EEPROM、PDI接口引出。如果只是做IO从站这样的电路板已经够了。晶振是首要注意点。LAN9252对时钟精度有要求一定要用低抖动的晶振layout时靠近芯片放置走线尽量短。我最早画的板子晶振离ESC引脚有点远结果从站偶尔出现链路抖动后来把晶振挪近问题立刻消失。供电设计上LAN9252内部有数字内核和PHY要注意模拟电源和数字电源分开最好用磁珠或LC滤波隔开。网络变压器选型也很关键要选支持百兆以太网的中间抽头接法参照数据手册这里偷懒后面就会有各种幽灵故障。两个网口都是集成PHY直接输出的不需要外接PHY芯片。MDI差分对之间要加共模电感更稳但这会稍微增加成本。信号线长度尽量等长参考地平面要完整这些是百兆以太网布线的基本要求但EtherCAT对这种稳定性更敏感因为它是工业级确定性通信。2.2 SM、FMMU和DC到底在干什么开始写从站逻辑前一定要把SM、FMMU、DC这三个概念弄明白否则后面配PDO、看同步时序会一头雾水。SM是同步管理器相当于主站和从站CPU之间的数据通道。EtherCAT定义一个SM通道时同时规定了数据的传输方向、触发方式和缓存区大小。比如输入SM负责从从站CPU那里把数据搬到ESC缓存输出SM负责把主站送来的数据放到ESC缓存并产生一个中断通知从站CPU来取。对主站来说SM就是它和从站交换过程数据的管道。FMMU负责地址映射。EtherCAT报文在网线上运行时的地址叫逻辑地址所有从站共享这段地址空间但每个从站只处理映射到自己FMMU的那一段。FMMU把网线上的逻辑地址空间映射到从站本地物理地址空间主站配置好之后从站硬件会自动完成数据搬运CPU完全不用管这段地址转换逻辑。打个比方FMMU就像公司前台快递送到公司前台按收件人把包裹分发到对应工位从站CPU就是坐在工位上的员工只关心自己桌上多了什么文件不用关心包裹怎么分拣的。DC是分布式时钟。工业现场经常有几十个从站要让它们在同一时刻一起执行动作不能依赖主站“挨个发指令”的方式那样最后一个站执行时第一个站已经等了一段时间。DC的做法是主站在每个周期发带时间戳的帧每个从站硬件根据帧里的时间戳校准自己的本地时钟然后对齐触发信号。所有从站相当于每天对时一次的手表虽然各自计时可能有一点点漂移但不断校准后就能在同一个时间点“齐步走”。2.3 EEPROM的SII配置与烧录陷阱从站板上那颗EEPROM就是SII存着从站的身份和通信参数包括Vendor ID、Product Code、Revision Number、Serial Number、SM配置、FMMU配置等。LAN9252上电时会自动从EEPROM读取这些信息主站扫描链路时就会读这些内容来识别从站。这里有几个非常容易翻车的点。第一EEPROM型号必须兼容LAN9252要求的SPI访问方式我用的是常见Microchip 24AA系列和Atmel AT24C系列都正常。第二烧录前一定要确认字节序和地址映射不同工具可能对高低字节的处理不一致写反了会让主站读出完全错误的数据。第三烧录完成之后必须复位ESC或者重新上电让LAN9252重新加载EEPROM否则芯片里还是旧数据你会以为烧录没生效。我最初烧录时犯过一个很蠢的错误Vendor ID填了0x00000000结果主站扫描能看到链路但无法识别出具体厂商型号后面配置PDO也会失败。Vendor ID、Product Code这些信息看起来很简单实际上决定了IgH主站能否正确匹配从站信息字典所以这里一定不要随便填。2.4 从站固件和PDI数据交换流程从站CPU这边的固件我用的是SSC生成的从站协议栈代码跑在STM32上LAN9252和STM32之间走SPI接口。SSC全称是EtherCAT Slave Stack Code是倍福提供的从站协议栈生成工具默认已经实现了EEPROM读写、状态机切换、PDO数据维护这些底层逻辑用户只需要把过程数据配置对再写好应用层处理函数就行。PDI接口选SPI还是并口取决于从站CPU的处理能力和数据量需求。简单IO我直接用SPI接线少如果有大量模拟量或高速数据交换可以考虑并行接口。SSC工程里会把SPI中断服务和数据访问函数自动生成好实际要改的地方主要是定义输入输出数据长度、指定SM通道号、实现用户应用处理函数比如读IO、写IO。过程数据的流向是这样的主站周期开始发送输出数据帧LAN9252通过输出SM收下数据产生PDI中断STM32在中断里通过SPI把数据读走然后置位IO输出反过来STM32采集IO输入写到输入SM缓存区下一帧主站发送时自动把输入数据带回去。整个过程在微秒级完成这就是为什么EtherCAT能做硬实时控制。3. Linux主站环境搭建从内核到IgH驱动3.1 内核准备实时性和网卡驱动IgH主站对内核有一定要求尤其是实时性。EtherCAT是硬实时总线周期抖动如果太大伺服控制就没法做。我在RK3568上直接用了带PREEMPT_RT补丁的Linux内核这个方案在工业上已经非常成熟。编译RT内核时要注意几个配置项CONFIG_PREEMPT_RT必须开启CONFIG_HZ建议设成1000这样系统时钟粒度是1ms级配合高精度定时器能达到足够精确的调度。还有一个容易忽略的点EtherCAT网卡对应的中断要尽量避免和其他高频率设备共享否则中断响应会被拖慢。IgH主站的网卡绑定方面RK3568的GMAC驱动在内核里一般是通用的stmmac驱动。第一次编译我图省事直接用了--enable-generic对应ec_generic模块它是通过通用以太网接口访问网卡的优点是适配性好缺点是性能比专用驱动模块略差。对于验证demo完全够用但如果要做高负载多从站或者高速IO建议研究一下对应网卡的专门封装模块比如e1000e、igb这类能把驱动层开销压到更低。3.2 编译安装IgH主站的完整步骤IgH主站源代码在EtherLab的GitLab上版本迭代不算快但稳定性很好。下载源码后先执行bootstrap生成configure脚本然后configure、make、make install这是标准的开源软件三连。我常用的configure参数是./bootstrap ./configure --prefix/opt/etherlab --enable-generic --disable-8139too make sudo make install--prefix指定安装路径我装到/opt/etherlab下方便和系统自带的库隔离。--enable-generic是启用通用网卡模块如果你确定要用某个特定网卡芯片可以加对应的enable选项。安装完成后把/opt/etherlab/sbin加到PATH里后面用ethercat命令就不用写全路径了。接着配置要绑定的网卡。编辑/etc/ethercat.conf打开下面这行MASTER0_DEVICE00:11:22:33:44:55把MAC地址换成自己EtherCAT专用网口的地址。然后加载模块sudo /opt/etherlab/sbin/ethercatctl start这个命令会读取配置文件并加载ec_master、ec_generic等模块。如果一切正常执行ethercat master能看到主站版本和周期统计信息。这里有个大概率会踩的坑如果网卡已经被NetworkManager或者systemd-networkd管理它会抢占网卡导致模块加载失败。解决办法是写一个udev规则或者直接在NetworkManager里把这个接口ignore掉专门留给EtherCAT使用。3.3 隔离网卡与中断优化主站用的网卡一旦绑定给IgH就不能再当普通网口用了。所以最好有一块独立的网口专门做EtherCAT通信其他的网口照常管理。我这个项目里RK3568双网口正好一分为二一个负责SSH和文件传输另一个单独给EtherCAT互不干扰。实时性优化方面我做了三件事一是把EtherCAT网卡的中断绑定到固定的CPU核上方法是在内核启动参数中加isolcpus或者在运行时设置/proc/irq/N/smp_affinity二是关闭CPU调频和深度睡眠避免核间延迟导致周期抖动三是用cyclictest确认系统的实时性基线如果这个都达不到个位数毫秒后面EtherCAT周期就好不了。如果只是做普通IO采集不追求微秒级同步很多优化可以先跳过等实际发现抖动超标再处理。但我建议从一开始就把中断绑定做好因为后期再改内核启动参数往往要动启动脚本和分区麻烦得很。4. 主从站联调从扫描到周期运行4.1 用ethercat命令扫描拓扑硬件上电主站启动正常后第一步肯定是看从站有没有被识别到。执行ethercat slaves -v如果能列出从站会看到类似下面的信息0 0:0 PREOP MyIO_LAN9252输出从左到右分别是主站索引、从站地址、当前状态、是否有DC能力、从站名称。如果链路异常这里什么都看不到或者只能看到一部分从站。调试阶段要熟悉几个常用命令ethercat state # 查看所有从站状态 ethercat states -4 # 将主站状态切换到OP ethercat pdos -e 0 # 查看0号从站的PDO映射 ethercat reg_read -p 0 -a 0x0130 -t uint8 # 读从站寄存器我一般先用ethercat slaves -v确认从站数量和名字再用ethercat reg_read去读从站AL状态寄存器看看它停留在哪个状态。正常链路启动后主站会引导所有从站从Init状态一路走到OP状态如果某个从站卡在SafeOP多半是PDO映射或DC配置有问题。4.2 配置PDO主站只知道“数据块”默认情况下主站虽然能扫描到从站但那只是一个“裸设备”主站并不知道这个从站有多少输入输出、数据怎么排布。这些信息来自从站EEPROM里的PDO映射表或者由主站应用代码显式配置。命令行里可以用ethercat cdef进行临时配置但实际项目更常使用应用代码里的配置函数因为这样可维护、可版本控制。IgH C API的做法是拿到从站配置结构体后调用ecrt_slave_config_pdos()传入PDO数组指定每个PDO的索引、方向和包含的对象。我做IO从站时两个PDO就够了一个输入PDO32位输入一个输出PDO32位输出。在代码里定义好对象映射static ec_pdo_entry_info_t io_inputs[] { {0x6000, 0x01, 32}, // 输入32位 }; static ec_pdo_info_t pdos_in[] { {0x1A00, 1, io_inputs}, // 输入PDO }; static ec_pdo_entry_info_t io_outputs[] { {0x7000, 0x01, 32}, // 输出32位 }; static ec_pdo_info_t pdos_out[] { {0x1600, 1, io_outputs}, // 输出PDO };这里0x6000和0x7000是对象字典索引32表示位宽。主站根据这个映射把从站的过程数据当作一个固定结构来解析。对于真正做驱动器类项目PDO映射可能会复杂很多会有伺服的位置、速度、力矩、控制字、状态字等几十个对象但配置原理完全一样。4.3 写一个最小主站应用命令行能验证通信但真实项目还是要写主站应用代码。最简单的主站程序大概分为几步请求主站句柄、创建域、配置从站PDO、创建过程数据指针、激活主站、周期发送接收。下面是一个高度简化的C程序骨架#include ecrt.h static ec_master_t *master; static ec_domain_t *domain; int main(void) { master ecrt_request_master(0); domain ecrt_master_create_domain(master); ec_slave_config_t *sc ecrt_master_slave_config( master, 0, 0, VENDOR_ID, PRODUCT_ID); ecrt_slave_config_pdos(sc, 2, pdos_in, pdos_out); ecrt_master_activate(master); unsigned char *input_data ecrt_domain_data(domain); struct timespec wake_time; clock_gettime(CLOCK_MONOTONIC, wake_time); while (1) { clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, wake_time, NULL); // 读输入 uint32_t in *(uint32_t *)(input_data offset); // 写输出 ecrt_master_send(master); // 发送输出帧 ecrt_domain_process(domain); // 处理接收到的输入帧 wake_time.tv_nsec PERIOD_NS; // 固定周期 } }这里核心是ecrt_master_send和ecrt_domain_process分别在周期开始和结束时调用形成完整的数据交换闭环。实际项目里我还会加周期超时统计、紧急停止逻辑和状态机切换但骨架就是上面这样。IgH的示例代码里还有更完整的实时任务样例通常在examples/rt_main.c里直接参考改很方便。有一点要注意主站激活后状态机必须在OP状态才能交换过程数据程序里可以在主站激活后主动调用ecrt_master_activate并等待从站进入OP或者用工具命令先切换过去。4.4 DC同步和抖动验收我做的从站支持DC所以联调里专门验证了分布式时钟同步。主站开启DC支持后从站的系统时间会自动与首站对齐。我用IgH的统计接口观察周期抖动运行半小时后抖动基本稳定在1us以内这在LAN9252这种集成PHY的从站上已经是非常健康的数据。如果抖动量很大比如几十us甚至到ms级优先查三处第一网卡中断是否被其他驱动干扰第二系统是不是有大量CPU负载导致周期任务调度延迟第三从站DC配置是否真的被主站启用可以用ethercat dc查看各站的DC状态。还要提醒一个容易忽略的点如果链路里同时有支持DC和不支持DC的从站主站会把不支持DC的节点排除在同步域外。这种混合链路虽然能工作但同步精度会下降所以在初调阶段尽量用同一型号或者至少都带DC的从站否则排查问题时会多很多干扰因素。5. 常见问题与排查技巧实录5.1 主站扫描不到从站先查这五处这个问题排第一因为所有人都遇到过。我遇到过的情况主要有五类网线/变压器虚焊或接错、从站板上电但LAN9252没有正确复位、EEPROM烧录错误导致从站状态异常、主站网卡没绑对或MAC地址写错、链路首尾对应关系搞反。排查顺序很有讲究。先用ethercat master确认主站模块已经正常加载再用dmesg | grep ec_master看有没有“No slave found”或链路错误。网线部分用普通电脑测一下这个口能不能作为普通网络通信如果普通网络都不通说明物理层有问题。然后检查从站的AL状态寄存器读0x0130如果寄存器读出来是0x0012这种非正常值大概率是从站没有经过正确配置流程。从站板卡上电后LAN9252必须能从EEPROM读到有效配置并进入Init状态。如果EEPROM是空的或者校验失败从站不会正确响应主站的数据报表现就是扫描的时候链路断开。这种情况先不管主站先单独用烧录器把EEPROM内容写好再说。我这里给一个排查速查表方便现场直接对着看现象常见原因解决办法扫描不到任何从站网线/变压器故障或主站网卡绑定错误换线检查NetName核对MAC地址能看到链路但无法识别从站名EEPROM里Vendor ID/Product Code错误重新烧录SII复位ESC从站能到PREOP但卡SafeOPPDO映射配置错误或DC参数不匹配核对PDO定义确认SM配置通信不稳定偶发断帧网络变压器/电源纹波问题检查模拟电源检查layout周期抖动大中断共享、CPU频率变化、驱动性能绑定中断核关闭调频5.2 帧错误和链路不稳定EtherCAT是工业以太网物理层稳定是一切的基础。我调试时用ethtool观察网卡统计如果RX errors、CRC errors持续增长说明链路质量很差。这种情况下先别怀疑主站软件大概率是硬件层面有干扰。常见的物理层杀手有三个电源纹波过大网络变压器选型不对或者差分对布线不等长。有一个土办法很有效启动主站后跑去从站板卡旁边手轻压一下变压器附近走线区域如果帧错误数立刻变化说明有虚焊或阻抗不连续的地方重新焊接比瞎改软件有效得多。另外要注意EtherCAT帧不是普通IP数据报普通以太网工具和大部分交换机都不能正确处理。调试时不要在这个链路上插交换机或者普通路由器否则会把帧搞坏。要抓包就开启Linux网卡的混杂模式后用Wireshark抓但要确认网卡驱动没有被IgH独占否则抓不到真实流量。5.3 从站状态机卡住怎么定位从站状态机是EtherCAT从站的“生命线”从Init、PreOP、SafeOP到OP每步都有严格条件。如果从站卡在SafeOP而不进OP常见原因是主站配置的PDO和从站实际SM配置不匹配或者从站要求的DC配置没有满足。定位问题时先用ethercat states看各从站的目标状态再用ethercat reg_read读0x0130寄存器也就是AL Status。注意这个寄存器的bit0到bit3表示当前状态bit4到bit7保留bit8以上会有错误指示位。如果AL Status是0x0012就说明它停在SafeOP并且有错误标志。最快的方法是把主站的日志打开。IgH在主站代码里定义了很多调试宏CONFIG_EC_DEBUG_QUEUE这类开起来后会把链路错误、状态机切换失败的原因打印到内核日志。生产环境不建议开太高但联调阶段开起来能省一半时间。5.4 EEPROM和SII相关的那些坑EEPROM的问题真的太常见了我单独把它拿出来说。EEPROM烧录完成后不要着急接主站先在从站板卡上电后用SPI逻辑分析仪直接抓LAN9252读取SII的波形确认数据是正常的。这一步能提前过滤掉90%的“主站认不到从站”问题。SII里除了身份信息还有重要的同步管理配置。很多从站EEPROM模板默认SM 0和SM 1是邮箱通信SM 2和SM 3才是过程数据。如果你的从站不做邮箱通信只做IO那这两个邮箱SM配置就要置成无效。我在一个项目里就是因为SM 0和SM 1没有禁用主站一直尝试初始化邮箱通信结果很晚才发现是SII配置问题而不是代码问题。5.5 调试工具链推荐联调阶段我常用的工具清单如下Wireshark抓链路层帧分析EtherCAT数据报结构ethtool和mii-tool检查网卡物理状态逻辑分析仪抓SPI和PDI接口时序示波器看DC同步信号和SYNC中断。如果这些都没有至少也要有串口日志输出否则现场出了问题真的是抓瞎。对于IgH主站来说ethercat debug这个命令也很实用可以实时打印主站的状态统计信息包括发送帧数、错误帧数、从站状态变化次数等。一般我在验证阶段会把它加到脚本里定期执行记录到日志文件跑一个晚上再回头分析。最后补充一个实际经验调EtherCAT这种跟硬件强相关的系统最忌讳的就是“改一行代码就急着上电跑一把”因为很多问题不是代码逻辑问题而是硬件状态问题。我的习惯是每次做改动后先跑一遍固定的自检流程看dmesg、查ethercat master、扫描从站、看AL状态寄存器全部通过才进行下一步。这个过程看起来很慢但确实能帮你把变量控制住快速定位到底是哪一环出了偏差。还有个小技巧就是一定要把从站EEPROM的配置导出一份备份放到版本管理里。不同批次板卡的EEPROM内容可能被刷成不同版本没有备份的话你会发现新旧两块板卡做主从站联调时偶尔表现不一致排查半天结果只是SII配置差异。这个细节虽然不起眼但在量产和多人协作开发时能省下大量沟通成本。最后想说的是EtherCAT主从站开发并没有想象中那么高不可攀。硬件缩到LAN9252这种高集成ESC软件用IgH开源主站整个系统的入手门槛已经低了很多。只要把协议状态机、PDO映射和DC同步这三个核心问题弄通再配一盘逻辑分析仪和一根靠谱的网线剩下的就是耐心排障的体力活。希望这篇实战记录能给正在做同类型项目的你一点帮助。
返回列表