# HG changeset patch # User Florian Pose # Date 1217585455 0 # Node ID 75cd6681eb08fe8ae48d5f2af9cc5ca03e609ddb # Parent d77f634ab0b5fbac5fdba675441200e7a518e1de Introduced SdoCommand class to replace coe_datatypes.[ch]; added CoE abort codes in user space- diff -r d77f634ab0b5 -r 75cd6681eb08 TODO --- a/TODO Fri Aug 01 09:32:35 2008 +0000 +++ b/TODO Fri Aug 01 10:10:55 2008 +0000 @@ -8,11 +8,11 @@ Version 1.4.0: +* Abort code messages in userspace. +* Repair rcethercat status. * Attach Pdo names from SII or Coe dictionary to Pdos read via CoE. * Update documentation. -* Race in jiffies frame timeout? -* Repair rcethercat status. -* Abort code messages in userspace. +* Check for possible race condition in jiffy-based frame timeout calculation. Future issues: diff -r d77f634ab0b5 -r 75cd6681eb08 tool/CommandDownload.cpp --- a/tool/CommandDownload.cpp Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/CommandDownload.cpp Fri Aug 01 10:10:55 2008 +0000 @@ -9,13 +9,12 @@ using namespace std; #include "CommandDownload.h" -#include "coe_datatypes.h" #include "byteorder.h" /*****************************************************************************/ CommandDownload::CommandDownload(): - Command("download", "Write an Sdo entry to a slave.") + SdoCommand("download", "Write an Sdo entry to a slave.") { } @@ -66,7 +65,7 @@ stringstream strIndex, strSubIndex, strValue, err; ec_ioctl_slave_sdo_download_t data; unsigned int number; - const CoEDataType *dataType = NULL; + const DataType *dataType = NULL; SlaveList slaves; if (args.size() != 3) { @@ -207,6 +206,12 @@ try { m.sdoDownload(&data); + } catch (MasterDeviceSdoAbortException &e) { + delete [] data.data; + err << "Sdo transfer aborted with code 0x" + << setfill('0') << hex << setw(8) << e.abortCode + << ": " << abortText(e.abortCode); + throwCommandException(err); } catch(MasterDeviceException &e) { delete [] data.data; throw e; diff -r d77f634ab0b5 -r 75cd6681eb08 tool/CommandDownload.h --- a/tool/CommandDownload.h Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/CommandDownload.h Fri Aug 01 10:10:55 2008 +0000 @@ -7,12 +7,12 @@ #ifndef __COMMANDDOWNLOAD_H__ #define __COMMANDDOWNLOAD_H__ -#include "Command.h" +#include "SdoCommand.h" /****************************************************************************/ class CommandDownload: - public Command + public SdoCommand { public: CommandDownload(); diff -r d77f634ab0b5 -r 75cd6681eb08 tool/CommandSdos.cpp --- a/tool/CommandSdos.cpp Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/CommandSdos.cpp Fri Aug 01 10:10:55 2008 +0000 @@ -9,12 +9,11 @@ using namespace std; #include "CommandSdos.h" -#include "coe_datatypes.h" /*****************************************************************************/ CommandSdos::CommandSdos(): - Command("sdos", "List Sdo dictionaries.") + SdoCommand("sdos", "List Sdo dictionaries.") { } @@ -83,7 +82,7 @@ ec_ioctl_slave_sdo_t sdo; ec_ioctl_slave_sdo_entry_t entry; unsigned int i, j; - const CoEDataType *d; + const DataType *d; if (showHeader) cout << "=== Slave " << slave.position << " ===" << endl; diff -r d77f634ab0b5 -r 75cd6681eb08 tool/CommandSdos.h --- a/tool/CommandSdos.h Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/CommandSdos.h Fri Aug 01 10:10:55 2008 +0000 @@ -7,12 +7,12 @@ #ifndef __COMMANDSDOS_H__ #define __COMMANDSDOS_H__ -#include "Command.h" +#include "SdoCommand.h" /****************************************************************************/ class CommandSdos: - public Command + public SdoCommand { public: CommandSdos(); diff -r d77f634ab0b5 -r 75cd6681eb08 tool/CommandUpload.cpp --- a/tool/CommandUpload.cpp Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/CommandUpload.cpp Fri Aug 01 10:10:55 2008 +0000 @@ -9,13 +9,12 @@ using namespace std; #include "CommandUpload.h" -#include "coe_datatypes.h" #include "byteorder.h" /*****************************************************************************/ CommandUpload::CommandUpload(): - Command("upload", "Read an Sdo entry from a slave.") + SdoCommand("upload", "Read an Sdo entry from a slave.") { } @@ -66,7 +65,7 @@ int sval; ec_ioctl_slave_sdo_upload_t data; unsigned int uval; - const CoEDataType *dataType = NULL; + const DataType *dataType = NULL; if (args.size() != 2) { err << "'" << getName() << "' takes two arguments!"; @@ -133,6 +132,12 @@ try { m.sdoUpload(&data); + } catch (MasterDeviceSdoAbortException &e) { + delete [] data.target; + err << "Sdo transfer aborted with code 0x" + << setfill('0') << hex << setw(8) << e.abortCode + << ": " << abortText(e.abortCode); + throwCommandException(err); } catch (MasterDeviceException &e) { delete [] data.target; throw e; diff -r d77f634ab0b5 -r 75cd6681eb08 tool/CommandUpload.h --- a/tool/CommandUpload.h Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/CommandUpload.h Fri Aug 01 10:10:55 2008 +0000 @@ -7,12 +7,12 @@ #ifndef __COMMANDUPLOAD_H__ #define __COMMANDUPLOAD_H__ -#include "Command.h" +#include "SdoCommand.h" /****************************************************************************/ class CommandUpload: - public Command + public SdoCommand { public: CommandUpload(); diff -r d77f634ab0b5 -r 75cd6681eb08 tool/Makefile.am --- a/tool/Makefile.am Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/Makefile.am Fri Aug 01 10:10:55 2008 +0000 @@ -54,7 +54,7 @@ CommandVersion.cpp \ CommandXml.cpp \ MasterDevice.cpp \ - coe_datatypes.cpp \ + SdoCommand.cpp \ main.cpp \ sii_crc.cpp @@ -77,8 +77,8 @@ CommandVersion.h \ CommandXml.h \ MasterDevice.h \ + SdoCommand.h \ byteorder.h \ - coe_datatypes.h \ sii_crc.h REV = `if test -s $(srcdir)/../svnrevision; then \ diff -r d77f634ab0b5 -r 75cd6681eb08 tool/MasterDevice.cpp --- a/tool/MasterDevice.cpp Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/MasterDevice.cpp Fri Aug 01 10:10:55 2008 +0000 @@ -359,14 +359,12 @@ { if (ioctl(fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, data) < 0) { stringstream err; - err << "Failed to download Sdo: "; if (errno == EIO && data->abort_code) { - err << "Abort code 0x" << hex << setfill('0') - << setw(8) << data->abort_code; + throw MasterDeviceSdoAbortException(data->abort_code); } else { - err << strerror(errno); + err << "Failed to download Sdo: " << strerror(errno); + throw MasterDeviceException(err); } - throw MasterDeviceException(err); } } @@ -376,14 +374,12 @@ { if (ioctl(fd, EC_IOCTL_SLAVE_SDO_UPLOAD, data) < 0) { stringstream err; - err << "Failed to upload Sdo: "; if (errno == EIO && data->abort_code) { - err << "Abort code 0x" << hex << setfill('0') - << setw(8) << data->abort_code; + throw MasterDeviceSdoAbortException(data->abort_code); } else { - err << strerror(errno); + err << "Failed to upload Sdo: " << strerror(errno); + throw MasterDeviceException(err); } - throw MasterDeviceException(err); } } diff -r d77f634ab0b5 -r 75cd6681eb08 tool/MasterDevice.h --- a/tool/MasterDevice.h Fri Aug 01 09:32:35 2008 +0000 +++ b/tool/MasterDevice.h Fri Aug 01 10:10:55 2008 +0000 @@ -22,6 +22,11 @@ friend class MasterDevice; protected: + /** Constructor with string parameter. */ + MasterDeviceException( + const string &s /**< Message. */ + ): runtime_error(s) {} + /** Constructor with stringstream parameter. */ MasterDeviceException( const stringstream &s /**< Message. */ @@ -30,6 +35,24 @@ /****************************************************************************/ +class MasterDeviceSdoAbortException: + public MasterDeviceException +{ + friend class MasterDevice; + + public: + uint32_t abortCode; + + protected: + /** Constructor with stringstream parameter. */ + MasterDeviceSdoAbortException(uint32_t code): + MasterDeviceException("Sdo transfer aborted.") { + abortCode = code; + }; +}; + +/****************************************************************************/ + class MasterDevice { public: diff -r d77f634ab0b5 -r 75cd6681eb08 tool/SdoCommand.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/SdoCommand.cpp Fri Aug 01 10:10:55 2008 +0000 @@ -0,0 +1,116 @@ +/***************************************************************************** + * + * $Id$ + * + ****************************************************************************/ + +#include "SdoCommand.h" + +/*****************************************************************************/ + +SdoCommand::SdoCommand(const string &name, const string &briefDesc): + Command(name, briefDesc) +{ +} + +/****************************************************************************/ + +const SdoCommand::DataType *SdoCommand::findDataType(const string &str) +{ + const DataType *d; + + for (d = dataTypes; d->name; d++) + if (str == d->name) + return d; + + return NULL; +} + +/****************************************************************************/ + +const SdoCommand::DataType *SdoCommand::findDataType(uint16_t code) +{ + const DataType *d; + + for (d = dataTypes; d->name; d++) + if (code == d->coeCode) + return d; + + return NULL; +} + +/****************************************************************************/ + +const char *SdoCommand::abortText(uint32_t abortCode) +{ + const AbortMessage *abortMsg; + + for (abortMsg = abortMessages; abortMsg->code; abortMsg++) { + if (abortMsg->code == abortCode) { + return abortMsg->message; + } + } + + return "???"; +} + +/****************************************************************************/ + +const SdoCommand::DataType SdoCommand::dataTypes[] = { + {"int8", 0x0002, 1}, + {"int16", 0x0003, 2}, + {"int32", 0x0004, 4}, + {"uint8", 0x0005, 1}, + {"uint16", 0x0006, 2}, + {"uint32", 0x0007, 4}, + {"string", 0x0009, 0}, + {"raw", 0xffff, 0}, + {} +}; + +/*****************************************************************************/ + +/** Sdo abort messages. + * + * The "Abort Sdo transfer request" supplies an abort code, which can be + * translated to clear text. This table does the mapping of the codes and + * messages. + */ +const SdoCommand::AbortMessage SdoCommand::abortMessages[] = { + {0x05030000, "Toggle bit not changed"}, + {0x05040000, "Sdo protocol timeout"}, + {0x05040001, "Client/Server command specifier not valid or unknown"}, + {0x05040005, "Out of memory"}, + {0x06010000, "Unsupported access to an object"}, + {0x06010001, "Attempt to read a write-only object"}, + {0x06010002, "Attempt to write a read-only object"}, + {0x06020000, "This object does not exist in the object directory"}, + {0x06040041, "The object cannot be mapped into the Pdo"}, + {0x06040042, "The number and length of the objects to be mapped would" + " exceed the Pdo length"}, + {0x06040043, "General parameter incompatibility reason"}, + {0x06040047, "Gerneral internal incompatibility in device"}, + {0x06060000, "Access failure due to a hardware error"}, + {0x06070010, "Data type does not match, length of service parameter does" + " not match"}, + {0x06070012, "Data type does not match, length of service parameter too" + " high"}, + {0x06070013, "Data type does not match, length of service parameter too" + " low"}, + {0x06090011, "Subindex does not exist"}, + {0x06090030, "Value range of parameter exceeded"}, + {0x06090031, "Value of parameter written too high"}, + {0x06090032, "Value of parameter written too low"}, + {0x06090036, "Maximum value is less than minimum value"}, + {0x08000000, "General error"}, + {0x08000020, "Data cannot be transferred or stored to the application"}, + {0x08000021, "Data cannot be transferred or stored to the application" + " because of local control"}, + {0x08000022, "Data cannot be transferred or stored to the application" + " because of the present device state"}, + {0x08000023, "Object dictionary dynamic generation fails or no object" + " dictionary is present"}, + {} +}; + +/****************************************************************************/ diff -r d77f634ab0b5 -r 75cd6681eb08 tool/SdoCommand.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/SdoCommand.h Fri Aug 01 10:10:55 2008 +0000 @@ -0,0 +1,41 @@ +/***************************************************************************** + * + * $Id$ + * + ****************************************************************************/ + +#ifndef __SDOCOMMAND_H__ +#define __SDOCOMMAND_H__ + +#include "Command.h" + +/****************************************************************************/ + +class SdoCommand: + public Command +{ + public: + SdoCommand(const string &, const string &); + + struct DataType { + const char *name; + uint16_t coeCode; + unsigned int byteSize; + }; + static const DataType *findDataType(const string &); + static const DataType *findDataType(uint16_t); + static const char *abortText(uint32_t); + + private: + struct AbortMessage { + uint32_t code; + const char *message; + }; + + static const DataType dataTypes[]; + static const AbortMessage abortMessages[]; +}; + +/****************************************************************************/ + +#endif diff -r d77f634ab0b5 -r 75cd6681eb08 tool/coe_datatypes.cpp --- a/tool/coe_datatypes.cpp Fri Aug 01 09:32:35 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/***************************************************************************** - * - * $Id$ - * - ****************************************************************************/ - -#include "coe_datatypes.h" - -/****************************************************************************/ - -static const CoEDataType dataTypes[] = { - {"int8", 0x0002, 1}, - {"int16", 0x0003, 2}, - {"int32", 0x0004, 4}, - {"uint8", 0x0005, 1}, - {"uint16", 0x0006, 2}, - {"uint32", 0x0007, 4}, - {"string", 0x0009, 0}, - {"raw", 0xffff, 0}, - {} -}; - -/****************************************************************************/ - -const CoEDataType *findDataType(const string &str) -{ - const CoEDataType *d; - - for (d = dataTypes; d->name; d++) - if (str == d->name) - return d; - - return NULL; -} - -/****************************************************************************/ - -const CoEDataType *findDataType(uint16_t code) -{ - const CoEDataType *d; - - for (d = dataTypes; d->name; d++) - if (code == d->coeCode) - return d; - - return NULL; -} - -/*****************************************************************************/ diff -r d77f634ab0b5 -r 75cd6681eb08 tool/coe_datatypes.h --- a/tool/coe_datatypes.h Fri Aug 01 09:32:35 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/***************************************************************************** - * - * $Id$ - * - ****************************************************************************/ - -#include - -#include -using namespace std; - -/****************************************************************************/ - -struct CoEDataType { - const char *name; - uint16_t coeCode; - unsigned int byteSize; -}; - -/****************************************************************************/ - -const CoEDataType *findDataType(const string &); -const CoEDataType *findDataType(uint16_t); - -/*****************************************************************************/