From eac0acd80907b847ef5f59de5c5f11edbebd9d13 Mon Sep 17 00:00:00 2001 From: Mikael Heden Date: Fri, 18 Dec 2015 14:39:28 +0100 Subject: [PATCH 1/6] Fix potential bug when the number of slaves is too large --- soem/ethercatconfig.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/soem/ethercatconfig.c b/soem/ethercatconfig.c index 12cf7171..0a6eb74b 100644 --- a/soem/ethercatconfig.c +++ b/soem/ethercatconfig.c @@ -176,7 +176,17 @@ int ecx_detect_slaves(ecx_contextt *context) wkc = ecx_BRD(context->port, 0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */ if (wkc > 0) { - *(context->slavecount) = wkc; + /* this is strictly "less than" since the master is "slave 0" */ + if (wkc < EC_MAXSLAVE) + { + *(context->slavecount) = wkc; + } + else + { + EC_PRINT("Error: too many slaves on network: num_slaves=%d, EC_MAXSLAVE=%d\n", + wkc, EC_MAXSLAVE); + return -2; + } } return wkc; } From d5fa11630d0b84fabd9f1ba29dc8f2b9f1ee42d2 Mon Sep 17 00:00:00 2001 From: Mikael Heden Date: Fri, 18 Dec 2015 14:53:16 +0100 Subject: [PATCH 2/6] Lowest state should not contain error flag --- soem/ethercatmain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index 3e8bde0c..8c42aa6a 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -784,9 +784,9 @@ int ecx_readstate(ecx_contextt *context) configadr = context->slavelist[slave].configadr; rval = etohs(sl[slave - fslave].alstatus); context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode); - if (rval < lowest) + if ((rval & 0xf) < lowest) { - lowest = rval; + lowest = (rval & 0xf); } context->slavelist[slave].state = rval; context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode; From 59e216441095e4fb31cf586c58e36b374556a417 Mon Sep 17 00:00:00 2001 From: Mikael Heden Date: Fri, 18 Dec 2015 14:55:30 +0100 Subject: [PATCH 3/6] Fix return value of ecx_writestate --- soem/ethercatmain.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/soem/ethercatmain.c b/soem/ethercatmain.c index 8c42aa6a..d77ba414 100644 --- a/soem/ethercatmain.c +++ b/soem/ethercatmain.c @@ -800,26 +800,29 @@ int ecx_readstate(ecx_contextt *context) /** 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] context = context struct * @param[in] slave = Slave number, 0 = master - * @return 0 + * @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); - ecx_BWR(context->port, 0, ECT_REG_ALCTL, sizeof(slstate), &slstate, EC_TIMEOUTRET3); /* write slave status */ + ret = ecx_BWR(context->port, 0, ECT_REG_ALCTL, sizeof(slstate), + &slstate, EC_TIMEOUTRET3); } else { configadr = context->slavelist[slave].configadr; - ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(context->slavelist[slave].state), EC_TIMEOUTRET3); /* write slave status */ + ret = ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, + htoes(context->slavelist[slave].state), EC_TIMEOUTRET3); } - return 0; + return ret; } /** Check actual slave state. From 82edc9a0332f65906dfc53bf7f925faccc04b718 Mon Sep 17 00:00:00 2001 From: Mikael Heden Date: Fri, 18 Dec 2015 16:03:23 +0100 Subject: [PATCH 4/6] Fix type mismatches --- soem/ethercatcoe.c | 3 ++- soem/ethercatconfig.c | 3 ++- soem/ethercatprint.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/soem/ethercatcoe.c b/soem/ethercatcoe.c index 4bc2ed9c..a5ce2121 100644 --- a/soem/ethercatcoe.c +++ b/soem/ethercatcoe.c @@ -1235,7 +1235,8 @@ int ecx_readODdescription(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlis int ecx_readOEsingle(ecx_contextt *context, uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist) { ec_SDOservicet *SDOp, *aSDOp; - uint16 wkc, Index, Slave; + int wkc; + uint16 Index, Slave; int16 n; ec_mbxbuft MbxIn, MbxOut; uint8 cnt; diff --git a/soem/ethercatconfig.c b/soem/ethercatconfig.c index 0a6eb74b..62f78a8a 100644 --- a/soem/ethercatconfig.c +++ b/soem/ethercatconfig.c @@ -1283,7 +1283,8 @@ int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group) int ecx_recover_slave(ecx_contextt *context, uint16 slave, int timeout) { int rval; - uint16 ADPh, configadr, readadr, wkc; + int wkc; + uint16 ADPh, configadr, readadr; rval = 0; configadr = context->slavelist[slave].configadr; diff --git a/soem/ethercatprint.h b/soem/ethercatprint.h index 3e221130..688012f9 100644 --- a/soem/ethercatprint.h +++ b/soem/ethercatprint.h @@ -52,7 +52,7 @@ extern "C" { #endif -char* ec_sdoerror2string( uint16 sdoerrorcode); +char* ec_sdoerror2string( uint32 sdoerrorcode); char* ec_ALstatuscode2string( uint16 ALstatuscode); char* ec_soeerror2string( uint16 errorcode); char* ecx_elist2string(ecx_contextt *context); From 918a6bad977d20a2abba17485d0b73e7bc75ea90 Mon Sep 17 00:00:00 2001 From: Mikael Heden Date: Fri, 18 Dec 2015 16:04:19 +0100 Subject: [PATCH 5/6] DC: change to EtherCAT epoch --- soem/ethercatdc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soem/ethercatdc.c b/soem/ethercatdc.c index 98ccbf47..f3883d0c 100644 --- a/soem/ethercatdc.c +++ b/soem/ethercatdc.c @@ -292,8 +292,10 @@ boolean ecx_configdc(ecx_contextt *context) context->slavelist[0].hasdc = FALSE; context->grouplist[0].hasdc = FALSE; ht = 0; - mastertime = osal_current_time(); + ecx_BWR(context->port, 0, ECT_REG_DCTIME0, sizeof(ht), &ht, EC_TIMEOUTRET); /* latch DCrecvTimeA of all slaves */ + mastertime = osal_current_time(); + mastertime.sec -= 946684800UL; /* EtherCAT uses 2000-01-01 as epoch start instead of 1970-01-01 */ mastertime64 = (((uint64)mastertime.sec * 1000000) + (uint64)mastertime.usec) * 1000; for (i = 1; i <= *(context->slavecount); i++) { From ec1cc7a4eddc660aa4dcb5a5225ae83088e7d41f Mon Sep 17 00:00:00 2001 From: Mikael Heden Date: Wed, 17 Feb 2016 10:57:48 +0100 Subject: [PATCH 6/6] Fix possible SM overwrite --- soem/ethercatcoe.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/soem/ethercatcoe.c b/soem/ethercatcoe.c index a5ce2121..86667b5c 100644 --- a/soem/ethercatcoe.c +++ b/soem/ethercatcoe.c @@ -856,13 +856,11 @@ int ecx_readPDOmap(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize) /* positive result from slave ? */ if ((wkc > 0) && (nSM > 2)) { - /* make nSM equal to number of defined SM */ - nSM--; /* limit to maximum number of SM defined, if true the slave can't be configured */ if (nSM > EC_MAXSM) nSM = EC_MAXSM; /* iterate for every SM type defined */ - for (iSM = 2 ; iSM <= nSM ; iSM++) + for (iSM = 2 ; iSM < nSM ; iSM++) { rdl = sizeof(tSM); tSM = 0; /* read SyncManager Communication Type */ @@ -958,8 +956,7 @@ int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize /* positive result from slave ? */ if ((wkc > 0) && (context->SMcommtype->n > 2)) { - /* make nSM equal to number of defined SM */ - nSM = context->SMcommtype->n - 1; + nSM = context->SMcommtype->n; /* limit to maximum number of SM defined, if true the slave can't be configured */ if (nSM > EC_MAXSM) { @@ -967,7 +964,7 @@ int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize ecx_packeterror(context, Slave, 0, 0, 10); /* #SM larger than EC_MAXSM */ } /* iterate for every SM type defined */ - for (iSM = 2 ; iSM <= nSM ; iSM++) + for (iSM = 2 ; iSM < nSM ; iSM++) { tSM = context->SMcommtype->SMtype[iSM];