EtherCAT数据帧及SOEM报文数据结构介绍

EtherCAT数据帧及SOEM报文数据结构介绍

  • EtherCAT数据帧结构介绍
    • 总报文
    • 子报文
  • SOEM报文结构介绍
    • 总报文
    • 子报文

EtherCAT数据帧结构介绍

总报文

参照电子科技大学,蒲婉玲的学位论文“EtherCAT 主站与从站设计与实现”,Ether CAT 通信帧结构采用标准以外网帧结构,是通过对传统协议进行修改形成,在标准协议里插入专用帧类型的 Ether CAT 数据帧,也就是说,标准协议的数据内容就是 Ether CAT 的数据帧。专用帧类型用 0x88A4 进行标记。也因为如此,Ether CAT 通信可被标准的以太网通信完全兼容。
报文数据结构
在这里插入图片描述
在这里插入图片描述

子报文

子报文包含命令、索引、地址区长度、标志位、状态位、数据区和工作计数器等 7 个部分。报文中的命令一般是 8 位,用来表示报文寻址方式和读写操作;索引就是帧编码;从站通信地址是地址去中的 32 位二进制码;标志位 M 是后续报文的表示,如果 Ether CAT 数据帧有多个子报文,除最后一个子报文的标志位外,其他子报文的标志位都需要被职位;子报文数据属于用户自定义部分,长度一般是 1486 个 byte。
在这里插入图片描述

SOEM报文结构介绍

soem文件包中的ethercatmain.h文件中,定义了ecx_context报文数据帧结构和ec_slave子报文数据结构,下面将分别对其进行介绍。

总报文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/** Context structure , referenced by all ecx functions*/
struct ecx_context
{
   /** port reference, may include red_port */
   ecx_portt      *port;
   /** slavelist reference */
   ec_slavet      *slavelist;
   /** number of slaves found in configuration */
   int            *slavecount;
   /** maximum number of slaves allowed in slavelist */
   int            maxslave;
   /** grouplist reference */
   ec_groupt      *grouplist;
   /** maximum number of groups allowed in grouplist */
   int            maxgroup;
   /** internal, reference to eeprom cache buffer */
   uint8          *esibuf;
   /** internal, reference to eeprom cache map */
   uint32         *esimap;
   /** internal, current slave for eeprom cache */
   uint16         esislave;
   /** internal, reference to error list */
   ec_eringt      *elist;
   /** internal, reference to processdata stack buffer info */
   ec_idxstackT   *idxstack;
   /** reference to ecaterror state */
   boolean        *ecaterror;
   /** reference to last DC time from slaves */
   int64          *DCtime;
   /** internal, SM buffer */
   ec_SMcommtypet *SMcommtype;
   /** internal, PDO assign list */
   ec_PDOassignt  *PDOassign;
   /** internal, PDO description list */
   ec_PDOdesct    *PDOdesc;
   /** internal, SM list from eeprom */
   ec_eepromSMt   *eepSM;
   /** internal, FMMU list from eeprom */
   ec_eepromFMMUt *eepFMMU;
   /** registered FoE hook */
   int            (*FOEhook)(uint16 slave, int packetnumber, int datasize);
   /** registered EoE hook */
   int            (*EOEhook)(ecx_contextt * context, uint16 slave, void * eoembx);
   /** flag to control legacy automatic state change or manual state change */
   int            manualstatechange;
};

需要特别注意

  • 1 从站个数int *slavecount;
  • 2 从站列表 ec_slavet *slavelist;

子报文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/** for list of ethercat slaves detected */
typedef struct ec_slave
{
   /** state of slave */
   uint16           state;
   /** AL status code */
   uint16           ALstatuscode;
   /** Configured address */
   uint16           configadr;
   /** Alias address */
   uint16           aliasadr;
   /** Manufacturer from EEprom */
   uint32           eep_man;
   /** ID from EEprom */
   uint32           eep_id;
   /** revision from EEprom */
   uint32           eep_rev;
   /** Interface type */
   uint16           Itype;
   /** Device type */
   uint16           Dtype;
   /** output bits */
   uint16           Obits;
   /** output bytes, if Obits < 8 then Obytes = 0 */
   uint32           Obytes;
   /** output pointer in IOmap buffer */
   uint8            *outputs;
   /** startbit in first output byte */
   uint8            Ostartbit;
   /** input bits */
   uint16           Ibits;
   /** input bytes, if Ibits < 8 then Ibytes = 0 */
   uint32           Ibytes;
   /** input pointer in IOmap buffer */
   uint8            *inputs;
   /** startbit in first input byte */
   uint8            Istartbit;
   /** SM structure */
   ec_smt           SM[EC_MAXSM];
   /** SM type 0=unused 1=MbxWr 2=MbxRd 3=Outputs 4=Inputs */
   uint8            SMtype[EC_MAXSM];
   /** FMMU structure */
   ec_fmmut         FMMU[EC_MAXFMMU];
   /** FMMU0 function */
   uint8            FMMU0func;
   /** FMMU1 function */
   uint8            FMMU1func;
   /** FMMU2 function */
   uint8            FMMU2func;
   /** FMMU3 function */
   uint8            FMMU3func;
   /** length of write mailbox in bytes, if no mailbox then 0 */
   uint16           mbx_l;
   /** mailbox write offset */
   uint16           mbx_wo;
   /** length of read mailbox in bytes */
   uint16           mbx_rl;
   /** mailbox read offset */
   uint16           mbx_ro;
   /** mailbox supported protocols */
   uint16           mbx_proto;
   /** Counter value of mailbox link layer protocol 1..7 */
   uint8            mbx_cnt;
   /** has DC capability */
   boolean          hasdc;
   /** Physical type; Ebus, EtherNet combinations */
   uint8            ptype;
   /** topology: 1 to 3 links */
   uint8            topology;
   /** active ports bitmap : ....3210 , set if respective port is active **/
   uint8            activeports;
   /** consumed ports bitmap : ....3210, used for internal delay measurement **/
   uint8            consumedports;
   /** slave number for parent, 0=master */
   uint16           parent;
   /** port number on parent this slave is connected to **/
   uint8            parentport;
   /** port number on this slave the parent is connected to **/
   uint8            entryport;
   /** DC receivetimes on port A */
   int32            DCrtA;
   /** DC receivetimes on port B */
   int32            DCrtB;
   /** DC receivetimes on port C */
   int32            DCrtC;
   /** DC receivetimes on port D */
   int32            DCrtD;
   /** propagation delay */
   int32            pdelay;
   /** next DC slave */
   uint16           DCnext;
   /** previous DC slave */
   uint16           DCprevious;
   /** DC cycle time in ns */
   int32            DCcycle;
   /** DC shift from clock modulus boundary */
   int32            DCshift;
   /** DC sync activation, 0=off, 1=on */
   uint8            DCactive;
   /** link to config table */
   uint16           configindex;
   /** link to SII config */
   uint16           SIIindex;
   /** 1 = 8 bytes per read, 0 = 4 bytes per read */
   uint8            eep_8byte;
   /** 0 = eeprom to master , 1 = eeprom to PDI */
   uint8            eep_pdi;
   /** CoE details */
   uint8            CoEdetails;
   /** FoE details */
   uint8            FoEdetails;
   /** EoE details */
   uint8            EoEdetails;
   /** SoE details */
   uint8            SoEdetails;
   /** E-bus current */
   int16            Ebuscurrent;
   /** if >0 block use of LRW in processdata */
   uint8            blockLRW;
   /** group */
   uint8            group;
   /** first unused FMMU */
   uint8            FMMUunused;
   /** Boolean for tracking whether the slave is (not) responding, not used/set by the SOEM library */
   boolean          islost;
   /** registered configuration function PO->SO, (DEPRECATED)*/
   int              (*PO2SOconfig)(uint16 slave);
   /** registered configuration function PO->SO */
   int              (*PO2SOconfigx)(ecx_contextt * context, uint16 slave);
   /** readable name */
   char             name[EC_MAXNAME + 1];
} ec_slavet;

其中需要特别关注的是

  • 1 从站id /** ID from EEprom */ uint32 eep_id;
  • 2 输出指针/** output pointer in IOmap buffer */ uint8 *outputs;
  • 3 输入指针/** input pointer in IOmap buffer */ uint8 *inputs;