第2章 EtherCAT协议基础:数据帧结构、寻址方式与通信模式

各位同学,欢迎来到第二章。这一章我们聊聊EtherCAT协议最核心的几个概念。说实话,很多工程师做了好几年EtherCAT开发,对数据帧结构还是一知半解。我个人觉得,不理解帧结构,后面写主站代码就是空中楼阁。

咱们先看一个实际场景。你想想看,一个EtherCAT主站要控制100个伺服驱动器,每个周期都要读写位置、速度、电流数据。这些数据怎么塞进一个以太网帧里?怎么保证每个从站只拿自己的数据?这就是我们今天要解决的问题。

2.1 EtherCAT数据帧结构

EtherCAT数据帧,说白了就是标准以太网帧的“改装版”。它没有发明新的物理层,直接跑在标准以太网硬件上。这一点很重要——你不需要特殊的网卡,普通千兆网卡就能跑。

来看帧结构:

+----------------+----------------+----------------+----------------+
|  Ethernet Header  |  EtherCAT Header |  EtherCAT Datagrams  |  FCS  |
|  14 bytes       |  2 bytes        |  44~1498 bytes   |  4 bytes |
+----------------+----------------+----------------+----------------+

嗯,这里要注意。EtherCAT的以太网帧类型是 0x88A4。我在项目中遇到过有人把类型配成 0x0800(IP协议),结果从站根本不认。这个坑我踩过,大家记住就好。

EtherCAT数据报(Datagram)才是真正的核心。一个帧里可以塞多个数据报,每个数据报结构如下:

字段 长度 说明
数据报头 10 bytes 包含寻址信息、长度、命令等
数据 0~1486 bytes 实际读写的数据
工作计数器(WKC) 2 bytes 从站处理完数据后递增

这里有个关键点——工作计数器(WKC)。我习惯把它叫做“握手信号”。每个从站处理完数据报后,会把WKC加1。主站收到返回帧后,检查WKC就知道数据有没有被正确处理。如果WKC不对,说明有从站没响应或者处理失败。

核心要点:EtherCAT数据报是“路过式”处理的。帧从主站发出,经过每个从站时,从站只处理属于自己的数据,然后继续转发。最后一个从站把帧原路返回。这种机制让EtherCAT的实时性远超传统现场总线。

2.2 寻址方式

EtherCAT的寻址方式,说实话,刚开始看确实有点绕。但搞懂了之后你会发现,它设计得非常巧妙。

主要有三种寻址方式:

  • 设备寻址(Device Addressing):直接指定从站地址。每个从站在上电时会被分配一个位置地址(Auto Increment Address)或者配置地址(Configured Station Address)。
  • 逻辑寻址(Logical Addressing):把整个EtherCAT网络映射成一段连续的内存空间。主站直接读写这段内存,从站自动处理映射关系。
  • 广播寻址(Broadcast):所有从站都处理同一个数据报。常用于同步或者初始化。

我个人在实际项目中用得最多的是逻辑寻址。为什么?因为逻辑寻址让主站代码写起来最舒服。你想想看,你只需要维护一个巨大的数组,每个从站的数据对应数组中的某一段。读写操作就像操作本地内存一样简单。

举个例子:

// 逻辑寻址示例:主站映射了100个从站,每个从站占64字节
#define SLAVE_DATA_SIZE  64
#define TOTAL_SLAVES     100

uint8_t logical_memory[TOTAL_SLAVES * SLAVE_DATA_SIZE];

// 读取第5个从站的位置数据
uint32_t position = *(uint32_t*)&logical_memory[5 * SLAVE_DATA_SIZE + 0x10];

嗯,这里要注意。逻辑寻址需要主站在初始化阶段配置好FMMU(现场总线内存管理单元)。每个从站内部都有一个FMMU,负责把逻辑地址映射到物理地址。我曾经遇到过一个问题:FMMU配置错了,导致两个从站的数据互相覆盖。排查了整整一天才找到原因。

避坑指南:配置FMMU时,一定要检查起始地址和长度是否与其他从站重叠。我建议在初始化完成后,做一个全网的读写校验测试,确保每个从站的数据都能正确访问。

2.3 通信模式

EtherCAT的通信模式分为两大类:周期性通信和非周期性通信。这两种模式在工业现场各有用途。

2.3.1 周期性通信(Process Data)

周期性通信,也叫过程数据通信。说白了就是每个周期固定交换的数据。比如伺服驱动器的位置、速度、电流,IO模块的输入输出状态。

特点:

  • 固定周期,通常1ms以内
  • 数据量小,但实时性要求高
  • 使用逻辑寻址,效率最高
  • 通过PDO(过程数据对象)映射

我做过一个项目,要求125微秒的周期。当时用的就是周期性通信模式。说实话,125微秒的周期对主站CPU压力很大,每个周期只有不到100微秒的时间来处理数据。这种情况下,代码必须高度优化,连函数调用都要尽量减少。

2.3.2 非周期性通信(Mailbox)

非周期性通信,也叫邮箱通信。用于传输配置参数、诊断信息、固件升级等非实时数据。

特点:

  • 不固定周期,按需触发
  • 数据量大,但实时性要求低
  • 使用设备寻址或广播寻址
  • 通过CoE(CANopen over EtherCAT)、SoE(Servo Drive over EtherCAT)等协议

举个例子,你需要在运行时修改伺服驱动器的PID参数。这个操作不需要每个周期都做,用邮箱通信最合适。主站发一个SDO请求,从站处理完后回复。

注意事项:千万不要在周期性通信中混入大量非周期性数据。我曾经见过一个案例,有人在每个周期都发邮箱数据,结果导致周期抖动超过50微秒,整个系统都不稳定。记住:周期性通信走PDO,非周期性通信走邮箱,两者要分开。

2.4 实际应用中的选择

好了,讲完理论,咱们聊聊实际怎么选。

我个人的经验是:

  • 运动控制场景(伺服、步进):必须用周期性通信,周期建议1ms以内
  • IO控制场景:周期性通信,周期可以放宽到2~5ms
  • 参数配置、固件升级:非周期性通信,用邮箱
  • 诊断监控:非周期性通信,但要注意不要影响周期

最后说一句。EtherCAT协议看起来复杂,但核心就是数据帧、寻址、通信模式这三板斧。搞懂了这些,后面写主站代码就会轻松很多。下一章我们开始讲主站源码的整体架构,到时候你会看到这些基础知识是怎么落地的。

好,今天就到这里。有问题随时交流。