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之所以能实现高速同步,靠的就是这个精巧的数据帧结构——一个帧里塞多个子报文,每个子报文独立寻址,WKC确保每个从站都处理到位。
调试小技巧:当你怀疑通信有问题时,第一件事就是抓包看WKC。如果WKC不对,要么是从站没响应,要么是寻址配置错了。我90%的通信问题都是通过检查WKC定位的。
好了,数据帧结构就讲到这里。记住三个关键词:一帧多报、灵活寻址、WKC校验。搞懂了这些,EtherCAT的通信机制你就掌握了七成。
公众号:蓝海资料掘金营,微信deep3321