该函数在ethercatmain.h文件中,用于读取从站的状态
/** Read all slave states in ec_slave. * @param[in] context = context struct * @return lowest state found */ int ecx_readstate(ecx_contextt *context);实现代码如下所示:
/** Read all slave states in ec_slave. * @param[in] context = context struct * @return lowest state found */ int ecx_readstate(ecx_contextt *context) { uint16 slave, fslave, lslave, configadr, lowest, rval, bitwisestate; ec_alstatust sl[MAX_FPRD_MULTI]; uint16 slca[MAX_FPRD_MULTI]; boolean noerrorflag, allslavessamestate; boolean allslavespresent = FALSE; int wkc; /* Try to establish the state of all slaves sending only one broadcast datagram. * This way a number of datagrams equal to the number of slaves will be sent only if needed.*/ rval = 0; wkc = ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval, EC_TIMEOUTRET); if(wkc >= *(context->slavecount)) { allslavespresent = TRUE; } rval = etohs(rval); bitwisestate = (rval & 0x0f); if ((rval & EC_STATE_ERROR) == 0) { noerrorflag = TRUE; context->slavelist[0].ALstatuscode = 0; } else { noerrorflag = FALSE; } switch (bitwisestate) { case EC_STATE_INIT: case EC_STATE_PRE_OP: case EC_STATE_BOOT: case EC_STATE_SAFE_OP: case EC_STATE_OPERATIONAL: allslavessamestate = TRUE; context->slavelist[0].state = bitwisestate; break; default: allslavessamestate = FALSE; break; } if (noerrorflag && allslavessamestate && allslavespresent) { /* No slave has toggled the error flag so the alstatuscode * (even if different from 0) should be ignored and * the slaves have reached the same state so the internal state * can be updated without sending any datagram. */ for (slave = 1; slave <= *(context->slavecount); slave++) { context->slavelist[slave].ALstatuscode = 0x0000; context->slavelist[slave].state = bitwisestate; } lowest = bitwisestate; } else { /* Not all slaves have the same state or at least one is in error so one datagram per slave * is needed. */ context->slavelist[0].ALstatuscode = 0; lowest = 0xff; fslave = 1; do { lslave = *(context->slavecount); if ((lslave - fslave) >= MAX_FPRD_MULTI) { lslave = fslave + MAX_FPRD_MULTI - 1; } for (slave = fslave; slave <= lslave; slave++) { const ec_alstatust zero = { 0, 0, 0 }; configadr = context->slavelist[slave].configadr; slca[slave - fslave] = configadr; sl[slave - fslave] = zero; } ecx_FPRD_multi(context, (lslave - fslave) + 1, &(slca[0]), &(sl[0]), EC_TIMEOUTRET3); for (slave = fslave; slave <= lslave; slave++) { configadr = context->slavelist[slave].configadr; rval = etohs(sl[slave - fslave].alstatus); context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode); if ((rval & 0xf) < lowest) { lowest = (rval & 0xf); } context->slavelist[slave].state = rval; context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode; } fslave = lslave + 1; } while (lslave < *(context->slavecount)); context->slavelist[0].state = lowest; } return lowest; }该函数也在ethercatmain.h文件中,用于写入从站的状态。
/** Write slave state, if slave = 0 then write to all slaves. * The function does not check if the actual state is changed. * @param[in] context = context struct * @param[in] slave = Slave number, 0 = master * @return Workcounter or EC_NOFRAME */ int ecx_writestate(ecx_contextt *context, uint16 slave)实现源代码:
/** Write slave state, if slave = 0 then write to all slaves. * The function does not check if the actual state is changed. * @param[in] context = context struct * @param[in] slave = Slave number, 0 = master * @return Workcounter or EC_NOFRAME */ int ecx_writestate(ecx_contextt *context, uint16 slave) { int ret; uint16 configadr, slstate; if (slave == 0) { slstate = htoes(context->slavelist[slave].state); ret = ecx_BWR(context->port, 0, ECT_REG_ALCTL, sizeof(slstate), &slstate, EC_TIMEOUTRET3); } else { configadr = context->slavelist[slave].configadr; ret = ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(context->slavelist[slave].state), EC_TIMEOUTRET3); } return ret; }