EtherCAT数据包含2B的数据头和44~1948B的数据区。数据区由多个子报文组成。由于EtherCAT本身是通过以太网数据帧的形式传输,因此其协议帧中会携带以太网的帧头。
其中,解释如下:
(1)以太网数据帧头:EtherCAT协议基于以太网数据帧形式传输,携带以太网数据帧头包含目的地址6 Bytes, 源地址6 Bytes和基于IEEE 802.3的帧类型0x88A4,长度为2 Bytes。
(2)目的地址:接收方的MAC地址,总长度6 Bytes, 48 bits.
(3)源地址:发送方的MAC地址,总长度 6 Bytes, 48 bits.
Mac地址:通常是48位长,格式为XX:XX:XX:XX:XX:XX,其中XX是十六进制数字。
// -------------------------------------------------------------------------------
// 常用MAC地址定义
// -------------------------------------------------------------------------------
// 广播地址
const ETHERNET_ADDRESS_LEN BroadcastEthernetAddress = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
// 第一个广播地址
const ETHERNET_ADDRESS FirstMulticastEthernetAddress = {0x01, 0, 0x5e, 0, 0, 0};
// 空MAC地址
const ETHERNET_ADDRESS NullEthernetAddress = { 0, 0, 0, 0, 0, 0 };
// --------------------------------------------------------------------------------
// 以太网数据帧头的数据结构定义
// --------------------------------------------------------------------------------
typedef struct TETHERNET_FRAME
{
ETHERNET_ADDRESS Destination; // 目的地址
ETHERNET_ADDRESS Source; // 源地址
USHORT FrameType; // 主机字节顺序
}ETHERNET_FRAME, *PETHERNET_FRAME;
(4)帧类型:帧类型根据标准定义有不同类型,其中EtherCAT固定使用0x88A4。
#define ETHERNET_FRAME_TYPE_ECAT 0x88A4 // EtherCAT数据帧的以太类型
#define ETHERNET_MAX_FRAME_LEN 1518 // 以太网数据帧的最大长度, 6+6+2+2+1498+4
(5)EtherCAT数据由EtherCAT数据头和EtherCAT数据区组成。
(6)EtherCAT头由长度、保留位和类型组成。其中长度表示EtherCAT数据区长度,即所有子报文长度总和;类型中,1表示与从站通信,其余数据保留。
// --------------------------------------------------------------------------------
// EtherCAT数据头定义
// --------------------------------------------------------------------------------
typedef struct TETYPE_88A4_HEADER
{
USHORT Length : 11; // 后续数据长度
USHORT Reserved : 1; // 保留
USHORT Type : 4; // 由ETYPE_88A4_TYPE_xxx定义
}ETYPE_88A4_HEADER, *PETYPE_88A4_HEADER;
#define ETYPE_88A4_HEADER_LEN sizeof(ETYPE_88A4_HEADER)
// --------------------------------------------------------------------------------
// EtherCAT 数据帧类型定义
// --------------------------------------------------------------------------------
#define ETYPE_88A4_TYPE_ECAT 1 // ECAT header follows
#define ETYPE_88A4_TYPE_ADS 2 // ADS header follows
#define ETYPE_88A4_TYPE_IO 3 // IO
#define ETYPE_88A4_TYPE_NV 4 // Network Variables
#define ETYPE_88A4_TYPE_CANOPEN5 5 // ETHERCAT_CANOPEN_HEADER follows
(7)EtherCAT数据区由多个子报文组成,子报文中包含子报文头、子报文数据和工作计数器WKC。
(7.1) 命令:寻址方式和读写方式定义。
// --------------------------------------------------------------------------------
// EtherCAT 命令类型定义,寻址方式将在下一节做介绍
// --------------------------------------------------------------------------------
typedef enum
{
EC_CMD_TYPE_NOP = 0, // 没有操作
EC_CMD_TYPE_APRD = 1, // 主站使用顺序寻址在从站中*读取*一定长度的数据
EC_CMD_TYPE_APWR = 2, // 主站使用顺序寻址在从站中*写入*一定长度的数据
EC_CMD_TYPE_APRW = 3, // 主站使用顺序寻址与从站*交换*数据
EC_CMD_TYPE_FPRD = 4, // 主站使用设置寻址与在从站中*读取*一定长度的数据
EC_CMD_TYPE_FPWR = 5, // 主站使用设置寻址与在从站中*写入*一定长度的数据
EC_CMD_TYPE_FPRW = 6, // 主站使用设置寻址与从站*交换*数据
EC_CMD_TYPE_BRD = 7, // 主站从所有从站的物理地址读取数据并做逻辑或
EC_CMD_TYPE_BWR = 8, // 主站广播写入所有从站
EC_CMD_TYPE_BRW = 9, // 与所有从站交换数据,对读取的数据做逻辑或
EC_CMD_TYPE_LRD = 10, // 主站使用逻辑寻址在从站*读取*一定长度的数据
EC_CMD_TYPE_LWR = 11, // 主站使用逻辑寻址在从站*写入*一定长度的数据
EC_CMD_TYPE_LRW = 12, // 主站使用逻辑寻址与从*站交*换数据
EC_CMD_TYPE_ARMW = 13, // 由从站读取数据,并写入后所有从站地址相同
EC_CMD_TYPE_EXT = 255, // 由从站读取数据,并写入后所有从站地址相同
}EC_CMD_TYPE;
(7.2)索引:帧编码。
// --------------------------------------------------------------------------------
// EtherCAT 数据帧INDEX定义
// --------------------------------------------------------------------------------
#define EC_HEAD_IDX_ACYCLIC_MASK 0x80
#define EC_HEAD_IDX_SLAVECMD 0x80
#define EC_HEAD_IDX_EXTERN_VALUE 0xFF
(7.3) 地址区:从站地址
(7.4) 长度:报文数据区长度
(7.5) R:保留位
(7.6)M:后续报文标志
(7.7)状态位:中断到来标志
(7.8) 数据区:子报文数据结构定义
(7.9) WKC:工作计数器,用于记录子报文被从站操作的次数。子报文每次被从站正确处理后WKC增加一个量。
为使更清楚的认识EtherCAT数据帧结构,以下贴上Ethernet数据帧结构图作为对比。
!图转自: https://www.cnblogs.com/qishui/p/5437301.html
!图转自 以太网帧结构-CSDN博客
其中可以看出,Ethernet的帧结构与EtherCAT帧结构的异同。去除Ethernet前导码部分,其中帧类型部分EtherCAT协议定义成了0x88A4。对于IP数据区,EtherCAT做出与以太网协议帧有主要差异的定义,这部分的原因是基于在这样一个系统中传输率的考虑。