广州公司建站模板/百度网址收录入口
EtherCAT数据帧及SOEM报文数据结构介绍
- EtherCAT数据帧结构介绍
- 总报文
- 子报文
- SOEM报文结构介绍
- 总报文ecx_context
- 子报文ec_slave
- ec_group数据结构
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子报文数据结构,下面将分别对其进行介绍。
总报文ecx_context
/** 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;
子报文ec_slave
/** 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;
ec_group数据结构
/** for list of ethercat slave groups */
typedef struct ec_group
{/** logical start address for this group */uint32 logstartaddr;/** output bytes, if Obits < 8 then Obytes = 0 */uint32 Obytes;/** output pointer in IOmap buffer */uint8 *outputs;/** input bytes, if Ibits < 8 then Ibytes = 0 */uint32 Ibytes;/** input pointer in IOmap buffer */uint8 *inputs;/** has DC capabillity */boolean hasdc;/** next DC slave */uint16 DCnext;/** E-bus current */int16 Ebuscurrent;/** if >0 block use of LRW in processdata */uint8 blockLRW;/** IO segments used */uint16 nsegments;/** 1st input segment */uint16 Isegment;/** Offset in input segment */uint16 Ioffset;/** Expected workcounter outputs */uint16 outputsWKC;/** Expected workcounter inputs */uint16 inputsWKC;/** check slave states */boolean docheckstate;/** IO segmentation list. Datagrams must not break SM in two. */uint32 IOsegment[EC_MAXIOSEGMENTS];
} ec_groupt;