Introduced SdoCommand class to replace coe_datatypes.[ch]; added CoE abort codes in user space-

This commit is contained in:
Florian Pose 2008-08-01 10:10:55 +00:00
parent b46070f279
commit 8da5077e9c
14 changed files with 215 additions and 104 deletions

6
TODO
View File

@ -8,11 +8,11 @@ $Id$
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:

View File

@ -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 @@ void CommandDownload::execute(MasterDevice &m, const StringVector &args)
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 @@ void CommandDownload::execute(MasterDevice &m, const StringVector &args)
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;

View File

@ -7,12 +7,12 @@
#ifndef __COMMANDDOWNLOAD_H__
#define __COMMANDDOWNLOAD_H__
#include "Command.h"
#include "SdoCommand.h"
/****************************************************************************/
class CommandDownload:
public Command
public SdoCommand
{
public:
CommandDownload();

View File

@ -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 @@ void CommandSdos::listSlaveSdos(
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;

View File

@ -7,12 +7,12 @@
#ifndef __COMMANDSDOS_H__
#define __COMMANDSDOS_H__
#include "Command.h"
#include "SdoCommand.h"
/****************************************************************************/
class CommandSdos:
public Command
public SdoCommand
{
public:
CommandSdos();

View File

@ -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 @@ void CommandUpload::execute(MasterDevice &m, const StringVector &args)
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 @@ void CommandUpload::execute(MasterDevice &m, const StringVector &args)
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;

View File

@ -7,12 +7,12 @@
#ifndef __COMMANDUPLOAD_H__
#define __COMMANDUPLOAD_H__
#include "Command.h"
#include "SdoCommand.h"
/****************************************************************************/
class CommandUpload:
public Command
public SdoCommand
{
public:
CommandUpload();

View File

@ -54,7 +54,7 @@ ethercat_SOURCES = \
CommandVersion.cpp \
CommandXml.cpp \
MasterDevice.cpp \
coe_datatypes.cpp \
SdoCommand.cpp \
main.cpp \
sii_crc.cpp
@ -77,8 +77,8 @@ noinst_HEADERS = \
CommandVersion.h \
CommandXml.h \
MasterDevice.h \
SdoCommand.h \
byteorder.h \
coe_datatypes.h \
sii_crc.h
REV = `if test -s $(srcdir)/../svnrevision; then \

View File

@ -359,14 +359,12 @@ void MasterDevice::sdoDownload(ec_ioctl_slave_sdo_download_t *data)
{
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 @@ void MasterDevice::sdoUpload(ec_ioctl_slave_sdo_upload_t *data)
{
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);
}
}

View File

@ -22,6 +22,11 @@ class MasterDeviceException:
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 MasterDeviceException:
/****************************************************************************/
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:

116
tool/SdoCommand.cpp Normal file
View File

@ -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"},
{}
};
/****************************************************************************/

41
tool/SdoCommand.h Normal file
View File

@ -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

View File

@ -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;
}
/*****************************************************************************/

View File

@ -1,25 +0,0 @@
/*****************************************************************************
*
* $Id$
*
****************************************************************************/
#include <inttypes.h>
#include <string>
using namespace std;
/****************************************************************************/
struct CoEDataType {
const char *name;
uint16_t coeCode;
unsigned int byteSize;
};
/****************************************************************************/
const CoEDataType *findDataType(const string &);
const CoEDataType *findDataType(uint16_t);
/*****************************************************************************/