总结一下自己对igh的ecrt_slave_config_dc()函数的理解。参考了igh的example里的“dc_user例程”。
例程里有这样一处代码:
// configure SYNC signals for this slave
ecrt_slave_config_dc(sc, 0x0700, PERIOD_NS, 4400000, 0, 0);
在slave_config.c文件里可以查看到函数的定义:
/** Configure distributed clocks.
*
* Sets the AssignActivate word and the cycle and shift times for the sync
* signals.
*
* The AssignActivate word is vendor-specific and can be taken from the XML
* device description file (Device -> Dc -> AssignActivate). Set this to zero,
* if the slave shall be operated without distributed clocks (default).
*
* This method has to be called in non-realtime context before
* ecrt_master_activate().
*
* \attention The \a sync1_shift time is ignored.
*/
void ecrt_slave_config_dc(
ec_slave_config_t *sc, /**< Slave configuration. */
uint16_t assign_activate, /**< AssignActivate word. */
uint32_t sync0_cycle, /**< SYNC0 cycle time [ns]. */
int32_t sync0_shift, /**< SYNC0 shift time [ns]. */
uint32_t sync1_cycle, /**< SYNC1 cycle time [ns]. */
int32_t sync1_shift /**< SYNC1 shift time [ns]. */
);
void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate,
uint32_t sync0_cycle_time, int32_t sync0_shift_time,
uint32_t sync1_cycle_time, int32_t sync1_shift_time)
{
ec_ioctl_config_t data;
int ret;
data.config_index = sc->index;
data.dc_assign_activate = assign_activate;
data.dc_sync[0].cycle_time = sync0_cycle_time;
data.dc_sync[0].shift_time = sync0_shift_time;
data.dc_sync[1].cycle_time = sync1_cycle_time;
data.dc_sync[1].shift_time = sync1_shift_time;
ret = ioctl(sc->master->fd, EC_IOCTL_SC_DC, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to set DC parameters: %s\n",
strerror(EC_IOCTL_ERRNO(ret)));
}
}
按照igh给的说明,assign_activate变量的值可以在从站的xml文件里找到:
打开一个xml文件,按照所给提示确实可以查到相关参数:
可是这里是0x0300,而不是0x0700。我验证过了,大多数从站的xml的AssignActivate值是0x0300。
这两个值有何关系呢?为什么要这么设?
接下来的一节是我和一位小伙伴的推理分析,可能是错的,请大家指正!!!
这节我参考了这位大哥的文章https://blog.csdn.net/ethercat_i7/article/details/77890740,让我受益匪浅。
igh/ethercat-hg/master/fsm_slave_config.c
/** Slave configuration state: DC START.
*/
void ec_fsm_slave_config_state_dc_start(
ec_fsm_slave_config_t *fsm /**< slave state machine */
)
{
ec_datagram_t *datagram = fsm->datagram;
ec_slave_t *slave = fsm->slave;
ec_slave_config_t *config = slave->config;
......
EC_SLAVE_DBG(slave, 1, "Setting DC AssignActivate to 0x%04x.\n",
config->dc_assign_activate);
// assign sync unit to EtherCAT or PDI
ec_datagram_fpwr(datagram, slave->station_address, 0x0980, 2);
EC_WRITE_U16(datagram->data, config->dc_assign_activate);
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_slave_config_state_dc_assign;
}
此处代码可以发现AssignActivate与0x0980关联在了一起,而0x0980正是DC控制相关寄存器,查看lan9252或者ET1100芯片的数据手册即可找到相关设置内容。在这里推荐《工业以太网现场总线EtherCAT驱动程序设计及应用》这本蓝皮书,今年刚出了新版。书中也有相关寄存器的讲解。下图为书中内容。
0x0981和0x0980两个寄存器加起来一共16位。0x0981占用高8位,0x0980占用低8位。0x0700和0x0300即对这两个寄存器的设置。
参考寄存器手册:
0x0981的0、1位置1、其它位置0即表示“激活运行周期,激活SYNC0”,即0x0300;
0x0981的0、1、2位置1、其它位置0即表示“激活运行周期,激活SYNC0,激活SYNC1”,即0x0700;
sync0_cycle_time, sync0_shift_time, sync1_cycle_time, sync1_shift_time这4个参数分别设置SYNC0、1的周期和偏移量。
推荐参考《EtherCAT_Communication_EN-》和《工业以太网现场总线EtherCAT驱动程序设计及应用》。
DC相关的内容我还有很多没搞明白,以后通过不断的学习、实践、问大佬,来完善自己的认知吧。
参考文献
【1】https://blog.csdn.net/ethercat_i7/article/details/77890740
【2】https://blog.csdn.net/GW569453350game/article/details/51612802
【3】http://lists.etherlab.org/pipermail/etherlab-users/2016/003013.html
【4】https://blog.csdn.net/PI_sunyang/article/details/95601486
【5】《EtherCAT_Communication_EN-》
【6】《工业以太网现场总线EtherCAT驱动程序设计及应用》