Ethercat学习-SOEM主站源码解析(DC部分)

张开发
2026/4/13 8:34:24 15 分钟阅读

分享文章

Ethercat学习-SOEM主站源码解析(DC部分)
文章目录SOEM DC模式源码简介示例用图ecx_porttimeecx_parentportecx_configdc如果从站不支持DC如果从站支持DCSOEM DC模式源码简介示例用图本文中都会围绕着这个图来讲,从站的port编号依次为0,3,1,2在SOEM中,与DC相关的文件是ethercatdc.c、ethercatdc.h。在这里面主要用到的是ecx_configdc、ecx_dcsync0、ecx_dcsync01、ecx_porttime、ecx_prevport、ecx_parentportecx_porttimestaticint32ecx_porttime(ecx_contextt*context,uint16 slave,uint8 port){............}这个函数很简单,就是根据输入的从站编号和端口编号返回端口锁存的时间,也就是示例图中的tA0,tB0,tC0…tE1,tB2,tA1。ecx_parentportstaticuint8ecx_parentport(ecx_contextt*context,uint16 parent){......returnparentport;}查找与当前从站相连的前一个从站(parent)的端口。输入的是parent编号。当前从站的parent编号是在ecx_config_init中计算的。以示例图为例,SlaveA的parent是0,表示master;SlaveB的parent是1,表示从站1;SlaveC的parent是2,表示从站2;SlaveE的parent是2,表示从站2…这个函数默认输入端口是port0,然后从port3开始查找使用的端口,当找到使用端口后会返回该端口号,并将该端口的使用标记改为未打开,这样防止重复计算。例如SlaveC的parent是SlaveB,计算出为port1,然后将其标记为未打开,这样下次再计算SlaveE的parentport的时候就会跳过port1,得到port2。ecx_configdccontext-slavelist[0].hasdc=FALSE;context-grouplist[0].hasdc=FALSE;初始化标志位为flase.ht=0;ecx_BWR(context-port,0,ECT_REG_DCTIME0,sizeof(ht),ht,EC_TIMEOUTRET);mastertime=osal_current_time();mastertime.sec-=946684800UL;mastertime64=(((uint64)mastertime.sec*1000000)+(uint64)mastertime.usec)*1000;通过广播写的方式写寄存器0x900。各个端口会锁存数据帧第一个前导码到达的时间。0~3总共四个端口锁存的时间分别存储于0x900、0x904、0x908、0x90C四个地址中。获取主站当前的时间,并将时间转换为基于2001-01-01的ns(纳秒)时间for(i=1;i=*(context-slavecount);i++){context-slavelist[i].consumedports=context-slavelist[i].activeports;if

更多文章