From 1d48c1d7a5a4fd3153cc7cab2949d51cbabba3d8 Mon Sep 17 00:00:00 2001 From: armar-user <armar6@kit.edu> Date: Mon, 16 Dec 2019 14:25:18 +0100 Subject: [PATCH] fixed several bugs in EtherCAT::readErrorCounters() --- .../libraries/ArmarXEtherCAT/EtherCAT.cpp | 59 ++++++++++++------- .../libraries/ArmarXEtherCAT/EtherCAT.h | 3 +- .../ArmarXEtherCAT/EtherCATRTUnit.cpp | 1 + 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.cpp b/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.cpp index 76552f55e..4e03cce5d 100644 --- a/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.cpp +++ b/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.cpp @@ -705,7 +705,7 @@ void EtherCAT::printALStatusError(uint16_t slave) { std::string name = "Unknown"; - AbstractSlavePtr slavePtr = getSlaveAtId(slave); + AbstractSlavePtr slavePtr = getSlaveAtIndex(slave); if (slavePtr) { name = slavePtr->getSlaveIdentifier().humanName; @@ -717,6 +717,19 @@ void EtherCAT::printALStatusError(uint16_t slave) << ", name: " << ec_slave[slave].name; } +int EtherCAT::ecx_APRD_with_error_handling(uint16_t ADP, uint16_t ADO, uint16_t length, void* data, int timeout, uint16_t slaveIndex, const std::string& name, int port) +{ + int retval = ecx_APRD(ecx_context.port, ADP, ADO, length, data, timeout); + if (retval <= 0) + { + std::stringstream ss; + ss << "0x" << std::hex << std::setw(4) << std::setfill('0') << ADO; + ARMARX_ERROR << "ecx_APRD failed: WC = " << retval << " (-1: EC_NOFRAME) . Slavenumber " << slaveIndex << "\tname: " << name << "\tport:" << port + << "\taddr: " << ss.str(); + } + return retval; +} + void EtherCAT::readErrorCounters() { IceUtil::Time start = IceUtil::Time::now(IceUtil::Time::Monotonic); @@ -724,39 +737,45 @@ void EtherCAT::readErrorCounters() { std::string name = "Unknown"; - AbstractSlavePtr slavePtr = getSlaveAtId(slaveIndex); + AbstractSlavePtr slavePtr = getSlaveAtIndex(slaveIndex); if (slavePtr) { name = slavePtr->getSlaveIdentifier().humanName; } - auto ADPh = (uint16)(1 - slaveIndex); - uint16_t configAddr = ecx_APRDw(ecx_context.port, ADPh, ECT_REG_STADR, 100000); + uint16 ADPh = (uint16)(1 - slaveIndex); + + //not used, only confusing info... + //uint16_t configAddr = ecx_APRDw(ecx_context.port, ADPh, ECT_REG_STADR, 100000); for (int i = 0; i < 4; i++) { // Error handling taken from // https://www.ethercat.org/download/documents/EtherCAT_Diagnosis_For_Users_DE.pdf // or Armar6RT/etc/doc/EtherCAT_Diagnosis_For_Users_DE.pdf - uint8_t rxError; - uint8_t invalidFrameCounter; // or Physical error count - uint8_t previousErrorCounter; // shows the error counter of a predecessor - uint8_t linkLostCounter; - ecx_APRD(ecx_context.port, ADPh, 0x300 + i * 2, 1, &rxError, 100000); - ecx_APRD(ecx_context.port, ADPh, 0x301 + i * 2, 1, &invalidFrameCounter, 100000); - ecx_APRD(ecx_context.port, ADPh, 0x308 + i, 1, &previousErrorCounter, 100000); - ecx_APRD(ecx_context.port, ADPh, 0x310 + i, 1, &linkLostCounter, 100000); - if (rxError > 0 || invalidFrameCounter > 0 || previousErrorCounter > 0 || linkLostCounter > 0) + uint8_t rxErrorCounter = 0; + uint8_t invalidFrameCounter = 0; // or Physical error count + uint8_t forwardedRxErrorCounter = 0; // shows the error counter of a predecessor + uint8_t linkLostCounter = 0; + int ret1 = ecx_APRD_with_error_handling(ADPh, 0x300 + i * 2, 1, &invalidFrameCounter, 100000, slaveIndex, name, i); + int ret2 = ecx_APRD_with_error_handling(ADPh, 0x301 + i * 2, 1, &rxErrorCounter, 100000, slaveIndex, name, i); + int ret3 = ecx_APRD_with_error_handling(ADPh, 0x308 + i, 1, &forwardedRxErrorCounter, 100000, slaveIndex, name, i); + int ret4 = ecx_APRD_with_error_handling(ADPh, 0x310 + i, 1, &linkLostCounter, 100000, slaveIndex, name, i); + + if (rxErrorCounter > 0 || invalidFrameCounter > 0 || forwardedRxErrorCounter > 0 || linkLostCounter > 0) + { + ARMARX_ERROR << "Errors found for Slavenumber " << slaveIndex << "\tname: " << name << "\tport:" << i << ": " + << VAROUT((int)rxErrorCounter) << "\t" << VAROUT((int)invalidFrameCounter) << "\t" << VAROUT((int)forwardedRxErrorCounter) << "\t" << VAROUT((int)linkLostCounter); + } + else if (ret1 > 0 && ret2 > 0 && ret3 > 0 && ret4 > 0) { - ARMARX_ERROR << "non zero frame error counter found: Slavenumber " << slaveIndex << "\tname: " << name - << "\tconfig addr: " << (int)configAddr << ": port " << i << ": " - << VAROUT((int)rxError) << "\t" << VAROUT((int)invalidFrameCounter) << "\t" << VAROUT((int)previousErrorCounter) << "\t" << VAROUT((int)linkLostCounter); + ARMARX_INFO << "no errors for Slavenumber " << slaveIndex << "\tname: " << name << "\tport:" << i; } } if ((IceUtil::Time::now(IceUtil::Time::Monotonic) - start).toMilliSeconds() > 10) { updatePDO(); - ARMARX_RT_LOGF_INFO("Updated BUS to prevent timeout").deactivateSpam(1); + ARMARX_RT_LOGF_INFO("Updated BUS to prevent timeout"); start = IceUtil::Time::now(IceUtil::Time::Monotonic); } } @@ -902,7 +921,7 @@ void EtherCAT::errorHandling() ec_errort error; while (ec_poperror(&error)) { - auto slave = getSlaveAtId(error.Slave); + auto slave = getSlaveAtIndex(error.Slave); if (error.Etype == EC_ERR_TYPE_EMERGENCY) { ARMARX_RT_LOGF_WARN("Found emergency error for slave %s (id: %d) from timestamp %d: error code: %d, error reg: %d, error index: %d, error sub index: %d", @@ -1442,12 +1461,12 @@ int EtherCAT::getMappedSize() return actualMappedSize; } -AbstractSlavePtr EtherCAT::getSlaveAtId(uint16_t slaveId) const +AbstractSlavePtr EtherCAT::getSlaveAtIndex(uint16_t slaveIndex) const { for (AbstractSlavePtr slave : slaves) { // ARMARX_INFO << "Checking slave: " << slave->getSlaveNumber() << " vs " << slaveId; - if (slave->getSlaveNumber() == slaveId) + if (slave->getSlaveNumber() == slaveIndex) { return slave; } diff --git a/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.h b/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.h index 9e283b596..e5c4317bf 100644 --- a/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.h +++ b/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCAT.h @@ -82,7 +82,7 @@ namespace armarx std::array<char, IOmapSize>& getIOMapBuffer(); int getMappedSize(); - AbstractSlavePtr getSlaveAtId(uint16_t slaveId) const; + AbstractSlavePtr getSlaveAtIndex(uint16_t slaveIndex) const; std::vector<AbstractSlavePtr> getSlaves(); bool getProductCode(uint16_t slave, uint32_t& productCode) const; @@ -154,6 +154,7 @@ namespace armarx protected: void readErrorCounters(); + int ecx_APRD_with_error_handling(uint16_t ADP, uint16_t ADO, uint16_t length, void* data, int timeout, uint16_t slaveIndex, const std::string& name, int port); private: //Hiding the constructor to avoid illegal creation of the Bus (singelton pattern) EtherCAT(); diff --git a/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCATRTUnit.cpp b/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCATRTUnit.cpp index 7a2f418f4..fb6c0946d 100644 --- a/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCATRTUnit.cpp +++ b/source/RobotAPI/libraries/ArmarXEtherCAT/EtherCATRTUnit.cpp @@ -126,6 +126,7 @@ void EtherCATRTUnit::onInitRobotUnit() EtherCAT& bus = EtherCAT::getBus(); bus.setMainUnitPtr(this); bus.setDeviceContainerPtr(deviceContainerPtr); + bus.setCheckErrorCountersOnWKCError(getProperty<bool>("checkErrorCountersOnEtherCATError").getValue()); } -- GitLab