Improved exceptions and commandName usage.
--- a/TODO Wed Jul 23 07:29:00 2008 +0000
+++ b/TODO Wed Jul 23 08:06:10 2008 +0000
@@ -11,22 +11,22 @@
* Read Pdo mapping for unknown Pdos before configuring them.
* Attach Pdo names from SII or Coe dictioary to Pdos read via CoE.
* Update documentation.
-* Add -a and -p switches for 'ethercat config' command.
-* Add a -n (numeric) switch to ethercat command.
-* Add help pages for every ethercat command.
-* Show Pdos in 'ethercat slave -v'.
-* Allow master requesting when in ORPHANED phase
* Get original driver for r8169.
* Race in jiffies frame timeout?
-* Accept files from stdin.
-* Show attached slave position.
-* Display attached device's MAC address instead of ff's.
-* Use commandName in error messages.
-* Data type abbreviations.
+* ethercat tool:
+ - Add help pages for each command.
+ - Add -a and -p switches for config command.
+ - Show attached slave position.
+ - Show Pdos in 'ethercat slave -v'.
+ - Accept files from stdin.
+ - Display attached device's MAC address instead of ff's.
+ - Data type abbreviations.
+ - Add a -n (numeric) switch.
Future issues:
* Distributed clocks.
+* Allow master requesting when in ORPHANED phase
* Move master threads, slave handlers and state machines into a user
space daemon.
* Implement user space realtime interface via cdev.
@@ -43,7 +43,7 @@
Smaller issues:
-* Stop master thread at ecrt_master_request() to get rid of allow_* flags.
+* Stop master thread at ecrt_master_request() to get rid of allow_* flags?
* Evaluate SII Size field (0x003E) to determine maximum SII memory size.
* Unite fsm_pdo_mapping, fsm_pdo_config and fsm_coe_map.
* Clear sync managers in INIT.
--- a/tool/MasterDevice.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/MasterDevice.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -51,7 +51,7 @@
stringstream err;
err << "Failed to open master device " << deviceName.str() << ": "
<< strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
}
@@ -83,7 +83,7 @@
if (ioctl(fd, EC_IOCTL_MASTER, data) < 0) {
stringstream err;
err << "Failed to get master information: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -96,7 +96,7 @@
if (ioctl(fd, EC_IOCTL_CONFIG, data) < 0) {
stringstream err;
err << "Failed to get slave configuration: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -116,7 +116,7 @@
if (ioctl(fd, EC_IOCTL_CONFIG_PDO, data) < 0) {
stringstream err;
err << "Failed to get slave config Pdo: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -138,7 +138,7 @@
if (ioctl(fd, EC_IOCTL_CONFIG_PDO_ENTRY, data) < 0) {
stringstream err;
err << "Failed to get slave config Pdo entry: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -156,7 +156,7 @@
if (ioctl(fd, EC_IOCTL_CONFIG_SDO, data) < 0) {
stringstream err;
err << "Failed to get slave config Sdo: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -173,7 +173,7 @@
err << "Domain " << index << " does not exist!";
else
err << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -189,7 +189,7 @@
if (ioctl(fd, EC_IOCTL_DOMAIN_DATA, data) < 0) {
stringstream err;
err << "Failed to get domain data: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -206,7 +206,7 @@
err << "Slave " << slaveIndex << " does not exist!";
else
err << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -224,7 +224,7 @@
if (ioctl(fd, EC_IOCTL_DOMAIN_FMMU, fmmu)) {
stringstream err;
err << "Failed to get domain FMMU: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -242,7 +242,7 @@
if (ioctl(fd, EC_IOCTL_SLAVE_SYNC, sync)) {
stringstream err;
err << "Failed to get sync manager: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -262,7 +262,7 @@
if (ioctl(fd, EC_IOCTL_SLAVE_SYNC_PDO, pdo)) {
stringstream err;
err << "Failed to get Pdo: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -284,7 +284,7 @@
if (ioctl(fd, EC_IOCTL_SLAVE_SYNC_PDO_ENTRY, entry)) {
stringstream err;
err << "Failed to get Pdo entry: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -302,7 +302,7 @@
if (ioctl(fd, EC_IOCTL_SLAVE_SDO, sdo)) {
stringstream err;
err << "Failed to get Sdo: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -322,7 +322,7 @@
if (ioctl(fd, EC_IOCTL_SLAVE_SDO_ENTRY, entry)) {
stringstream err;
err << "Failed to get Sdo entry: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -335,7 +335,7 @@
if (ioctl(fd, EC_IOCTL_SLAVE_SII_READ, data) < 0) {
stringstream err;
err << "Failed to read SII: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -348,7 +348,7 @@
if (ioctl(fd, EC_IOCTL_SLAVE_SII_WRITE, data) < 0) {
stringstream err;
err << "Failed to write SII: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -359,7 +359,7 @@
if (ioctl(fd, EC_IOCTL_MASTER_DEBUG, debugLevel) < 0) {
stringstream err;
err << "Failed to set debug level: " << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -376,7 +376,7 @@
} else {
err << strerror(errno);
}
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -393,7 +393,7 @@
} else {
err << strerror(errno);
}
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
@@ -416,7 +416,7 @@
err << "Slave " << slavePosition << " does not exist!";
else
err << strerror(errno);
- throw MasterDeviceException(err.str());
+ throw MasterDeviceException(err);
}
}
--- a/tool/MasterDevice.h Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/MasterDevice.h Wed Jul 23 08:06:10 2008 +0000
@@ -8,6 +8,7 @@
#define __EC_MASTER_H__
#include <stdexcept>
+#include <sstream>
using namespace std;
#include "../include/ecrt.h"
@@ -18,11 +19,13 @@
class MasterDeviceException:
public runtime_error
{
- public:
+ friend class MasterDevice;
+
+ protected:
/** Constructor with std::string parameter. */
MasterDeviceException(
- const string &s /**< Message. */
- ): runtime_error(s) {}
+ const stringstream &s /**< Message. */
+ ): runtime_error(s.str()) {}
};
/****************************************************************************/
--- a/tool/cmd_alias.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_alias.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -66,7 +66,7 @@
if (!force) {
err << "This will write the alias addresses of all slaves to "
<< alias << "! Please specify --force to proceed.";
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
masterDev.open(MasterDevice::ReadWrite);
@@ -100,7 +100,7 @@
if (slave.sii_nwords < 8) {
err << "Current SII contents are too small to set an alias "
<< "(" << slave.sii_nwords << " words)!";
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
// read first 8 SII words
@@ -114,7 +114,7 @@
} catch (MasterDeviceException &e) {
delete [] data.words;
err << "Failed to read SII: " << e.what();
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
// write new alias address in word 4
@@ -132,7 +132,7 @@
} catch (MasterDeviceException &e) {
delete [] data.words;
err << "Failed to read SII: " << e.what();
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
delete [] data.words;
--- a/tool/cmd_debug.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_debug.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -36,8 +36,8 @@
if (commandArgs.size() != 1) {
stringstream err;
- err << "'debug' takes exactly one argument!";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' takes exactly one argument!";
+ throw InvalidUsageException(err);
}
str << commandArgs[0];
@@ -47,7 +47,7 @@
if (str.fail()) {
stringstream err;
err << "Invalid debug level '" << commandArgs[0] << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
masterDev.open(MasterDevice::ReadWrite);
--- a/tool/cmd_domain.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_domain.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -119,9 +119,9 @@
dataOffset = fmmu.logical_address - domain.logical_base_address;
if (dataOffset + fmmu.data_size > domain.data_size) {
stringstream err;
+ delete [] processData;
err << "Fmmu information corrupted!";
- delete [] processData;
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
cout << " " << hex << setfill('0');
--- a/tool/cmd_download.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_download.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -30,14 +30,15 @@
const CoEDataType *dataType = NULL;
if (slavePosition < 0) {
- err << "'sdo_download' requires a slave! Please specify --slave.";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' requires a slave! "
+ << "Please specify --slave.";
+ throw InvalidUsageException(err);
}
data.slave_position = slavePosition;
if (commandArgs.size() != 3) {
- err << "'sdo_download' takes 3 arguments!";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' takes 3 arguments!";
+ throw InvalidUsageException(err);
}
strIndex << commandArgs[0];
@@ -46,7 +47,7 @@
>> data.sdo_index;
if (strIndex.fail()) {
err << "Invalid Sdo index '" << commandArgs[0] << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
strSubIndex << commandArgs[1];
@@ -55,14 +56,14 @@
>> number;
if (strSubIndex.fail() || number > 0xff) {
err << "Invalid Sdo subindex '" << commandArgs[1] << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
data.sdo_entry_subindex = number;
if (dataTypeStr != "") { // data type specified
if (!(dataType = findDataType(dataTypeStr))) {
err << "Invalid data type '" << dataTypeStr << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
} else { // no data type specified: fetch from dictionary
ec_ioctl_slave_sdo_entry_t entry;
@@ -75,13 +76,13 @@
} catch (MasterDeviceException &e) {
err << "Failed to determine Sdo entry data type. "
<< "Please specify --type.";
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
if (!(dataType = findDataType(entry.data_type))) {
err << "Pdo entry has unknown data type 0x"
<< hex << setfill('0') << setw(4) << entry.data_type << "!"
<< " Please specify --type.";
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
}
@@ -148,7 +149,7 @@
case 0x0009: // string
if (strValue.str().size() >= data.data_size) {
err << "String too large";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
data.data_size = strValue.str().size();
strValue >> (char *) data.data;
@@ -157,13 +158,13 @@
default:
delete [] data.data;
err << "Unknown data type 0x" << hex << dataType->coeCode;
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
} catch (ios::failure &e) {
delete [] data.data;
err << "Invalid value argument '" << commandArgs[2]
<< "' for type '" << dataType->name << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
masterDev.open(MasterDevice::ReadWrite);
--- a/tool/cmd_master.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_master.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -36,12 +36,10 @@
<< " Phase: ";
switch (data.phase) {
- case 0: cout << "Waiting for device..."; break;
- case 1: cout << "Idle"; break;
- case 2: cout << "Operation"; break;
- default:
- err << "Invalid master phase " << data.phase;
- throw MasterDeviceException(err.str());
+ case 0: cout << "Waiting for device..."; break;
+ case 1: cout << "Idle"; break;
+ case 2: cout << "Operation"; break;
+ default: cout << "???";
}
cout << endl
--- a/tool/cmd_sii_read.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_sii_read.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -66,9 +66,9 @@
stringstream err;
if (slavePosition < 0) {
- stringstream err;
- err << "'sii_read' requires a slave! Please specify --slave.";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' requires a slave! "
+ << "Please specify --slave.";
+ throw InvalidUsageException(err);
}
data.slave_position = slavePosition;
@@ -113,7 +113,7 @@
if (categoryHeader + 1 > data.words + data.nwords) {
err << "SII data seem to be corrupted!";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
categorySize = le16tocpu(*(categoryHeader + 1));
cout << ", " << dec << categorySize << " words" << flush;
@@ -121,7 +121,7 @@
if (categoryHeader + 2 + categorySize
> data.words + data.nwords) {
err << "SII data seem to be corrupted!";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
cout << hex;
@@ -139,7 +139,7 @@
if (categoryHeader + 2 + categorySize + 1
> data.words + data.nwords) {
err << "SII data seem to be corrupted!";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
categoryHeader += 2 + categorySize;
categoryType = le16tocpu(*categoryHeader);
--- a/tool/cmd_sii_write.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_sii_write.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -34,20 +34,21 @@
uint8_t crc;
if (slavePosition < 0) {
- err << "'sii_write' requires a slave! Please specify --slave.";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' requires a slave! "
+ << "Please specify --slave.";
+ throw InvalidUsageException(err);
}
data.slave_position = slavePosition;
if (commandArgs.size() != 1) {
- err << "'ssi_write' takes exactly one argument!";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' takes exactly one argument!";
+ throw InvalidUsageException(err);
}
file.open(commandArgs[0].c_str(), ifstream::in | ifstream::binary);
if (file.fail()) {
err << "Failed to open '" << commandArgs[0] << "'!";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
// get length of file
@@ -56,16 +57,15 @@
file.seekg(0, ios::beg);
if (!byte_size || byte_size % 2) {
- stringstream err;
err << "Invalid file size! Must be non-zero and even.";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
data.nwords = byte_size / 2;
if (data.nwords < 0x0041 && !force) {
err << "SII data too short (" << data.nwords << " words)! Mimimum is"
" 40 fixed words + 1 delimiter. Use --force to write anyway.";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
// allocate buffer and read file into buffer
@@ -80,7 +80,7 @@
err << "CRC incorrect. Must be 0x"
<< hex << setfill('0') << setw(2) << (unsigned int) crc
<< ". Use --force to write anyway.";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
// cycle through categories to detect corruption
@@ -90,14 +90,14 @@
if (categoryHeader + 1 > data.words + data.nwords) {
err << "SII data seem to be corrupted! "
<< "Use --force to write anyway.";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
categorySize = le16tocpu(*(categoryHeader + 1));
if (categoryHeader + 2 + categorySize + 1
> data.words + data.nwords) {
err << "SII data seem to be corrupted! "
"Use --force to write anyway.";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
categoryHeader += 2 + categorySize;
categoryType = le16tocpu(*categoryHeader);
--- a/tool/cmd_states.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_states.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -22,13 +22,13 @@
void command_states(void)
{
+ stringstream err;
string stateStr;
uint8_t state;
if (commandArgs.size() != 1) {
- stringstream err;
- err << "'state' takes exactly one argument!";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' takes exactly one argument!";
+ throw InvalidUsageException(err);
}
stateStr = commandArgs[0];
@@ -44,9 +44,8 @@
} else if (stateStr == "OP") {
state = 0x08;
} else {
- stringstream err;
err << "Invalid state '" << commandArgs[0] << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
masterDev.open(MasterDevice::ReadWrite);
--- a/tool/cmd_upload.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/cmd_upload.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -24,23 +24,22 @@
void command_upload(void)
{
- stringstream strIndex, strSubIndex;
+ stringstream err, strIndex, strSubIndex;
int sval;
ec_ioctl_slave_sdo_upload_t data;
unsigned int uval;
const CoEDataType *dataType = NULL;
if (slavePosition < 0) {
- stringstream err;
- err << "'sdo_upload' requires a slave! Please specify --slave.";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' requires a slave! "
+ << "Please specify --slave.";
+ throw InvalidUsageException(err);
}
data.slave_position = slavePosition;
if (commandArgs.size() != 2) {
- stringstream err;
- err << "'sdo_upload' takes two arguments!";
- throw MasterDeviceException(err.str());
+ err << "'" << commandName << "' takes two arguments!";
+ throw InvalidUsageException(err);
}
strIndex << commandArgs[0];
@@ -48,9 +47,8 @@
>> resetiosflags(ios::basefield) // guess base from prefix
>> data.sdo_index;
if (strIndex.fail()) {
- stringstream err;
err << "Invalid Sdo index '" << commandArgs[0] << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
strSubIndex << commandArgs[1];
@@ -58,17 +56,15 @@
>> resetiosflags(ios::basefield) // guess base from prefix
>> uval;
if (strSubIndex.fail() || uval > 0xff) {
- stringstream err;
err << "Invalid Sdo subindex '" << commandArgs[1] << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
data.sdo_entry_subindex = uval;
if (dataTypeStr != "") { // data type specified
if (!(dataType = findDataType(dataTypeStr))) {
- stringstream err;
err << "Invalid data type '" << dataTypeStr << "'!";
- throw MasterDeviceException(err.str());
+ throw InvalidUsageException(err);
}
} else { // no data type specified: fetch from dictionary
ec_ioctl_slave_sdo_entry_t entry;
@@ -79,17 +75,15 @@
masterDev.getSdoEntry(&entry, slavePosition,
data.sdo_index, data.sdo_entry_subindex);
} catch (MasterDeviceException &e) {
- stringstream err;
err << "Failed to determine Sdo entry data type. "
<< "Please specify --type.";
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
if (!(dataType = findDataType(entry.data_type))) {
- stringstream err;
err << "Pdo entry has unknown data type 0x"
<< hex << setfill('0') << setw(4) << entry.data_type << "!"
<< " Please specify --type.";
- throw ExecutionFailureException(err);
+ throw CommandException(err);
}
}
@@ -113,11 +107,10 @@
masterDev.close();
if (dataType->byteSize && data.data_size != dataType->byteSize) {
- stringstream err;
err << "Data type mismatch. Expected " << dataType->name
<< " with " << dataType->byteSize << " byte, but got "
<< data.data_size << " byte.";
- throw MasterDeviceException(err.str());
+ throw CommandException(err);
}
cout << setfill('0');
--- a/tool/globals.h Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/globals.h Wed Jul 23 08:06:10 2008 +0000
@@ -46,12 +46,12 @@
/****************************************************************************/
-class ExecutionFailureException:
+class CommandException:
public runtime_error
{
public:
/** Constructor with std::string parameter. */
- ExecutionFailureException(
+ CommandException(
const stringstream &s /**< Message. */
): runtime_error(s.str()) {}
};
--- a/tool/main.cpp Wed Jul 23 07:29:00 2008 +0000
+++ b/tool/main.cpp Wed Jul 23 08:06:10 2008 +0000
@@ -251,7 +251,7 @@
cerr << e.what() << endl << endl;
displayHelp();
return 1;
- } catch (ExecutionFailureException &e) {
+ } catch (CommandException &e) {
cerr << e.what() << endl;
return 1;
} catch (MasterDeviceException &e) {