3. EtherCAT数据帧结构:数据帧格式、寻址方式、工作计数器(WKC)

各位工程师朋友,咱们今天聊聊EtherCAT的数据帧。说实话,搞懂数据帧结构,是理解整个EtherCAT协议的基础。你想想看,所有分布式时钟的同步信息,都是通过这个数据帧在总线上跑来跑去的。我刚开始接触EtherCAT时,第一件事就是把数据帧格式打印出来贴在工位上,天天看。

3.1 数据帧格式——以太网里的“特快专列”

EtherCAT的数据帧,说白了就是标准以太网帧里塞了一个“EtherCAT头”。它没有重新发明轮子,而是巧妙地利用了以太网类型字段0x88A4来标识自己。嗯,这里要注意:EtherCAT数据帧可以直接跑在以太网上,也可以封装在UDP/IP里(端口号0x88A4)。

一个标准的EtherCAT数据帧结构如下:

+----------------+----------------+----------------+----------------+
|  目的MAC地址(6B) |  源MAC地址(6B) | EtherType(2B)  | EtherCAT头(2B) |
|                 |                 |    = 0x88A4    |                 |
+----------------+----------------+----------------+----------------+
|                    EtherCAT数据区(44-1498B)                      |
|  +-----------+-----------+-----------+-----------+-----------+  |
|  | 子报文1头 | 子报文1数据 | 子报文2头 | 子报文2数据 | ...       |  |
|  +-----------+-----------+-----------+-----------+-----------+  |
+----------------------------------------------------------------+
|                         FCS(4B)                                 |
+----------------------------------------------------------------+

EtherCAT头只有2个字节:

  • 长度字段(11位):表示整个EtherCAT数据区的长度,单位是字节。我遇到过有人把这个长度算错,结果从站根本收不到数据。
  • 保留位(1位):目前没用,但别乱改它。
  • 类型字段(4位):1表示与从站通信,其他值用于特殊用途。

数据区里可以塞多个子报文。每个子报文都有自己的头、数据和工作计数器。这就是EtherCAT的厉害之处——一个数据帧可以同时跟多个从站“对话”。

核心要点:EtherCAT数据帧是“一帧多报”的。一个以太网帧里可以打包最多16个EtherCAT子报文,每个子报文独立寻址、独立处理。

3.2 寻址方式——怎么找到你要的那个从站?

EtherCAT的寻址方式有好几种,我刚开始学的时候觉得有点绕。但搞清楚了,其实就两种思路:按位置找按名字找

3.2.1 设备寻址

设备寻址就是直接指定某个从站。有两种模式:

  • 顺序寻址:从站按物理位置编号。第一个从站是0,第二个是1,依此类推。这种方式在启动时配置很常用。
  • 节点寻址:每个从站有一个唯一的节点地址(1-65535)。这个地址可以静态配置,也可以动态分配。

我个人习惯在项目初期用顺序寻址做调试,因为接线顺序一目了然。但正式运行时,一定要用节点寻址,否则换根网线位置变了,整个系统就乱了。

3.2.2 逻辑寻址

逻辑寻址是EtherCAT最强大的地方。它把整个网络映射成一个连续的虚拟地址空间(4GB大小)。每个从站把自己的部分寄存器或内存映射到这个空间里。主站发一个逻辑寻址的报文,所有从站同时判断自己是否命中这个地址范围。

举个例子:

// 假设从站1的输入映射到逻辑地址0x00001000,长度4字节
// 从站2的输入映射到逻辑地址0x00001004,长度4字节
// 主站发送逻辑读报文,地址0x00001000,长度8字节
// 从站1自动填充前4字节,从站2自动填充后4字节
// 主站一次读取就拿到了两个从站的数据

这就是分布式时钟同步的基础——所有从站可以同时处理同一个逻辑寻址报文,实现真正的“同时”采样。

我的经验:逻辑寻址的地址映射表一定要在系统启动时一次性配置好。我曾经在运行中动态修改映射,结果导致某个从站采样数据错位,查了两天才找到原因。

3.3 工作计数器(WKC)——数据帧的“回执单”

工作计数器,简称WKC,是EtherCAT子报文里一个2字节的字段。它的作用很简单:记录这个子报文被多少个从站处理过

每个子报文都有一个WKC字段。主站发送时,WKC初始化为0。每个从站处理完这个子报文后,会根据操作类型增加WKC的值:

操作类型 WKC增加值 说明
读操作 +1 从站成功读取数据
写操作 +1 从站成功写入数据
读写操作 +3 从站同时完成读写

主站收到返回的数据帧后,会检查WKC的值是否等于预期值。如果不相等,说明有从站没处理成功,或者处理了多次。嗯,这里要注意:WKC是EtherCAT协议里最常用的错误检测手段。

避坑指南:我曾经遇到一个情况,某个从站固件有bug,每次处理子报文时WKC加了2次。结果主站发现WKC总是比预期大,就认为通信异常,不断重发。整个网络性能直接掉了一半。排查了整整一天,最后用抓包工具才发现是WKC计数异常。

WKC的检查逻辑其实很简单:

// 伪代码示例
uint16_t expected_wkc = 0;
for (每个从站) {
    if (从站参与此报文) {
        expected_wkc += (操作类型 == 读写) ? 3 : 1;
    }
}
if (received_wkc != expected_wkc) {
    // 通信异常,需要处理
    handle_communication_error();
}

3.4 知识体系总览

说了这么多,咱们用一张图把整个数据帧结构串起来。这张图是我自己画的,把数据帧格式、寻址方式和WKC的关系都理清楚了。

EtherCAT数据帧知识体系 标准以太网帧 (EtherType = 0x88A4) 目的MAC | 源MAC | EtherType | EtherCAT头 | EtherCAT数据区 | FCS EtherCAT子报文 (可包含多个) 子报文头 | 数据 | WKC | 子报文头 | 数据 | WKC | ... 最多16个子报文,总长度44-1498字节 数据帧格式 • 以太网封装 • EtherCAT头(2B) • 子报文结构 寻址方式 • 设备寻址 • 逻辑寻址 • 广播寻址 工作计数器(WKC) • 读操作 +1 • 写操作 +1 • 读写操作 +3 核心逻辑 主站发送数据帧 → 从站根据寻址方式处理 → 更新WKC → 返回主站 → 主站校验WKC WKC是判断通信是否成功的“金标准”

这张图把咱们今天讲的内容都串起来了。从以太网帧开始,到子报文,再到三种核心概念。你想想看,EtherCAT之所以能实现高速同步,靠的就是这个精巧的数据帧结构——一个帧里塞多个子报文,每个子报文独立寻址,WKC确保每个从站都处理到位。

调试小技巧:当你怀疑通信有问题时,第一件事就是抓包看WKC。如果WKC不对,要么是从站没响应,要么是寻址配置错了。我90%的通信问题都是通过检查WKC定位的。

好了,数据帧结构就讲到这里。记住三个关键词:一帧多报、灵活寻址、WKC校验。搞懂了这些,EtherCAT的通信机制你就掌握了七成。


公众号:蓝海资料掘金营,微信deep3321