Alias/Position selection.

This commit is contained in:
Florian Pose 2008-07-25 14:19:29 +00:00
parent 373d8a7475
commit db277eb34b
19 changed files with 360 additions and 246 deletions

5
TODO
View File

@ -14,8 +14,9 @@ Version 1.4.0:
* Get original driver for r8169.
* Race in jiffies frame timeout?
* ethercat tool:
- Replace --slave by --position.
- Add --alias option.
- Single message for unambiguous slave in SiiRead/Write and Up/Download.
- Implement Alias/Position selection for configs.
- Update help for --alias and --position.
- Show Pdos in 'ethercat slave -v'.
- Accept files from stdin.
- Display attached device's MAC address instead of ff's.

View File

@ -28,6 +28,20 @@ void Command::setVerbosity(Verbosity v)
verbosity = v;
};
/*****************************************************************************/
void Command::setAlias(int a)
{
alias = a;
};
/*****************************************************************************/
void Command::setPosition(int p)
{
position = p;
};
/****************************************************************************/
bool Command::matchesSubstr(const string &cmd) const
@ -78,6 +92,61 @@ void Command::throwCommandException(const stringstream &s)
throw CommandException(s);
}
/*****************************************************************************/
Command::SlaveList Command::selectedSlaves(MasterDevice &m)
{
unsigned int numSlaves = m.slaveCount(), i, aliasIndex;
uint16_t lastAlias;
ec_ioctl_slave_t slave;
SlaveList list;
if (alias == -1) { // no alias given
if (position == -1) { // no alias and position given
// all items
for (i = 0; i < numSlaves; i++) {
m.getSlave(&slave, i);
list.push_back(slave);
}
} else { // no alias, but position given
// one item by position
m.getSlave(&slave, position);
list.push_back(slave);
}
} else { // alias given
if (position == -1) { // alias, but no position given
// take all items with a given alias
lastAlias = 0;
for (i = 0; i < numSlaves; i++) {
m.getSlave(&slave, i);
if (slave.alias) {
lastAlias = slave.alias;
}
if (lastAlias == (uint16_t) alias) {
list.push_back(slave);
}
}
} else { // alias and position given
lastAlias = 0;
aliasIndex = 0;
for (i = 0; i < numSlaves; i++) {
m.getSlave(&slave, i);
if (slave.alias) { // FIXME 'lock' first alias
lastAlias = slave.alias;
aliasIndex = 0;
}
if (lastAlias == (uint16_t) alias
&& aliasIndex == (unsigned int) position) {
list.push_back(slave);
}
aliasIndex++;
}
}
}
return list;
}
/****************************************************************************/
string Command::alStateString(uint8_t state)

View File

@ -9,6 +9,7 @@
#include <stdexcept>
#include <vector>
#include <list>
using namespace std;
#include "MasterDevice.h"
@ -16,7 +17,6 @@ using namespace std;
/*****************************************************************************/
extern unsigned int masterIndex;
extern int slavePosition;
extern int domainIndex;
extern string dataTypeStr;
extern bool force;
@ -57,16 +57,20 @@ class Command
Command(const string &, const string &);
virtual ~Command();
const string &getName() const;
const string &getBriefDescription() const;
enum Verbosity {
Quiet,
Normal,
Verbose
};
void setVerbosity(Verbosity);
const string &getName() const;
const string &getBriefDescription() const;
Verbosity getVerbosity() const;
void setAlias(int);
int getAlias() const;
void setPosition(int);
int getPosition() const;
bool matchesSubstr(const string &) const;
bool matchesAbbrev(const string &) const;
@ -79,17 +83,22 @@ class Command
static string numericInfo();
protected:
enum {BreakAfterBytes = 16};
void throwInvalidUsageException(const stringstream &);
void throwCommandException(const stringstream &);
enum {BreakAfterBytes = 16};
typedef list<ec_ioctl_slave_t> SlaveList;
SlaveList selectedSlaves(MasterDevice &);
static string alStateString(uint8_t);
private:
string name;
string briefDesc;
Verbosity verbosity;
int alias;
int position;
Command();
};
@ -117,4 +126,18 @@ inline Command::Verbosity Command::getVerbosity() const
/****************************************************************************/
inline int Command::getAlias() const
{
return alias;
}
/****************************************************************************/
inline int Command::getPosition() const
{
return position;
}
/****************************************************************************/
#endif

View File

@ -57,7 +57,8 @@ void CommandAlias::execute(MasterDevice &m, const StringVector &args)
uint16_t alias;
stringstream err, strAlias;
int number;
unsigned int numSlaves, i;
SlaveList slaves;
SlaveList::const_iterator si;
if (args.size() != 1) {
err << "'" << getName() << "' takes exactly one argument!";
@ -74,22 +75,18 @@ void CommandAlias::execute(MasterDevice &m, const StringVector &args)
}
alias = number;
if (slavePosition == -1) {
if (!force) {
err << "This will write the alias addresses of all slaves to "
<< alias << "! Please specify --force to proceed.";
throwCommandException(err);
}
m.open(MasterDevice::ReadWrite);
slaves = selectedSlaves(m);
if (slaves.size() > 1 && !force) {
err << "This will write the alias addresses of "
<< slaves.size() << " slaves to " << alias
<< "! Please specify --force to proceed.";
throwCommandException(err);
}
m.open(MasterDevice::ReadWrite);
numSlaves = m.slaveCount();
for (i = 0; i < numSlaves; i++) {
writeSlaveAlias(m, i, alias);
}
} else {
m.open(MasterDevice::ReadWrite);
writeSlaveAlias(m, slavePosition, alias);
for (si = slaves.begin(); si != slaves.end(); si++) {
writeSlaveAlias(m, *si, alias);
}
}
@ -99,17 +96,14 @@ void CommandAlias::execute(MasterDevice &m, const StringVector &args)
*/
void CommandAlias::writeSlaveAlias(
MasterDevice &m,
uint16_t slavePosition,
const ec_ioctl_slave_t &slave,
uint16_t alias
)
{
ec_ioctl_slave_sii_t data;
ec_ioctl_slave_t slave;
stringstream err;
uint8_t crc;
m.getSlave(&slave, slavePosition);
if (slave.sii_nwords < 8) {
err << "Current SII contents are too small to set an alias "
<< "(" << slave.sii_nwords << " words)!";
@ -117,7 +111,7 @@ void CommandAlias::writeSlaveAlias(
}
// read first 8 SII words
data.slave_position = slavePosition;
data.slave_position = slave.position;
data.offset = 0;
data.nwords = 8;
data.words = new uint16_t[data.nwords];

View File

@ -21,7 +21,8 @@ class CommandAlias:
void execute(MasterDevice &, const StringVector &);
protected:
void writeSlaveAlias(MasterDevice &, uint16_t, uint16_t);
void writeSlaveAlias(MasterDevice &, const ec_ioctl_slave_t &,
uint16_t);
};
/****************************************************************************/

View File

@ -64,13 +64,7 @@ void CommandDownload::execute(MasterDevice &m, const StringVector &args)
ec_ioctl_slave_sdo_download_t data;
unsigned int number;
const CoEDataType *dataType = NULL;
if (slavePosition < 0) {
err << "'" << getName() << "' requires a slave! "
<< "Please specify --slave.";
throwInvalidUsageException(err);
}
data.slave_position = slavePosition;
SlaveList slaves;
if (args.size() != 3) {
err << "'" << getName() << "' takes 3 arguments!";
@ -96,6 +90,14 @@ void CommandDownload::execute(MasterDevice &m, const StringVector &args)
}
data.sdo_entry_subindex = number;
m.open(MasterDevice::ReadWrite);
slaves = selectedSlaves(m);
if (slaves.size() != 1) {
err << slaves.size() << " slaves selected, single slave required!";
throwInvalidUsageException(err);
}
data.slave_position = slaves.front().position;
if (dataTypeStr != "") { // data type specified
if (!(dataType = findDataType(dataTypeStr))) {
err << "Invalid data type '" << dataTypeStr << "'!";
@ -104,10 +106,8 @@ void CommandDownload::execute(MasterDevice &m, const StringVector &args)
} else { // no data type specified: fetch from dictionary
ec_ioctl_slave_sdo_entry_t entry;
m.open(MasterDevice::ReadWrite);
try {
m.getSdoEntry(&entry, slavePosition,
m.getSdoEntry(&entry, data.slave_position,
data.sdo_index, data.sdo_entry_subindex);
} catch (MasterDeviceException &e) {
err << "Failed to determine Sdo entry data type. "
@ -203,10 +203,8 @@ void CommandDownload::execute(MasterDevice &m, const StringVector &args)
throwInvalidUsageException(err);
}
m.open(MasterDevice::ReadWrite);
try {
m.sdoDownload(&data);
m.sdoDownload(&data);
} catch(MasterDeviceException &e) {
delete [] data.data;
throw e;

View File

@ -67,16 +67,16 @@ string CommandPdos::helpString() const
void CommandPdos::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
SlaveList::const_iterator si;
bool showHeader;
m.open(MasterDevice::Read);
slaves = selectedSlaves(m);
showHeader = slaves.size() > 1;
if (slavePosition == -1) {
unsigned int numSlaves = m.slaveCount(), i;
for (i = 0; i < numSlaves; i++) {
listSlavePdos(m, i, true);
}
} else {
listSlavePdos(m, slavePosition, false);
for (si = slaves.begin(); si != slaves.end(); si++) {
listSlavePdos(m, *si, showHeader);
}
}
@ -84,23 +84,20 @@ void CommandPdos::execute(MasterDevice &m, const StringVector &args)
void CommandPdos::listSlavePdos(
MasterDevice &m,
uint16_t slavePosition,
bool withHeader
const ec_ioctl_slave_t &slave,
bool showHeader
)
{
ec_ioctl_slave_t slave;
ec_ioctl_slave_sync_t sync;
ec_ioctl_slave_sync_pdo_t pdo;
ec_ioctl_slave_sync_pdo_entry_t entry;
unsigned int i, j, k;
m.getSlave(&slave, slavePosition);
if (withHeader)
cout << "=== Slave " << slavePosition << " ===" << endl;
if (showHeader)
cout << "=== Slave " << slave.position << " ===" << endl;
for (i = 0; i < slave.sync_count; i++) {
m.getSync(&sync, slavePosition, i);
m.getSync(&sync, slave.position, i);
cout << "SM" << i << ":"
<< " PhysAddr 0x"
@ -115,7 +112,7 @@ void CommandPdos::listSlavePdos(
<< endl;
for (j = 0; j < sync.pdo_count; j++) {
m.getPdo(&pdo, slavePosition, i, j);
m.getPdo(&pdo, slave.position, i, j);
cout << " " << (sync.control_register & 0x04 ? "R" : "T")
<< "xPdo 0x"
@ -127,7 +124,7 @@ void CommandPdos::listSlavePdos(
continue;
for (k = 0; k < pdo.entry_count; k++) {
m.getPdoEntry(&entry, slavePosition, i, j, k);
m.getPdoEntry(&entry, slave.position, i, j, k);
cout << " Pdo entry 0x"
<< hex << setfill('0')

View File

@ -21,7 +21,7 @@ class CommandPdos:
void execute(MasterDevice &, const StringVector &);
protected:
void listSlavePdos(MasterDevice &, uint16_t, bool);
void listSlavePdos(MasterDevice &, const ec_ioctl_slave_t &, bool);
};
/****************************************************************************/

View File

@ -58,16 +58,16 @@ string CommandSdos::helpString() const
void CommandSdos::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
SlaveList::const_iterator si;
bool showHeader;
m.open(MasterDevice::Read);
slaves = selectedSlaves(m);
showHeader = slaves.size() > 1;
if (slavePosition == -1) {
unsigned int numSlaves = m.slaveCount(), i;
for (i = 0; i < numSlaves; i++) {
listSlaveSdos(m, i, true);
}
} else {
listSlaveSdos(m, slavePosition, false);
for (si = slaves.begin(); si != slaves.end(); si++) {
listSlaveSdos(m, *si, showHeader);
}
}
@ -75,23 +75,20 @@ void CommandSdos::execute(MasterDevice &m, const StringVector &args)
void CommandSdos::listSlaveSdos(
MasterDevice &m,
uint16_t slavePosition,
bool withHeader
const ec_ioctl_slave_t &slave,
bool showHeader
)
{
ec_ioctl_slave_t slave;
ec_ioctl_slave_sdo_t sdo;
ec_ioctl_slave_sdo_entry_t entry;
unsigned int i, j;
const CoEDataType *d;
m.getSlave(&slave, slavePosition);
if (withHeader)
cout << "=== Slave " << slavePosition << " ===" << endl;
if (showHeader)
cout << "=== Slave " << slave.position << " ===" << endl;
for (i = 0; i < slave.sdo_count; i++) {
m.getSdo(&sdo, slavePosition, i);
m.getSdo(&sdo, slave.position, i);
cout << "Sdo 0x"
<< hex << setfill('0')
@ -102,7 +99,7 @@ void CommandSdos::listSlaveSdos(
continue;
for (j = 0; j <= sdo.max_subindex; j++) {
m.getSdoEntry(&entry, slavePosition, -i, j);
m.getSdoEntry(&entry, slave.position, -i, j);
cout << " 0x" << hex << setfill('0')
<< setw(4) << sdo.sdo_index << ":"

View File

@ -21,7 +21,7 @@ class CommandSdos:
void execute(MasterDevice &, const StringVector &);
protected:
void listSlaveSdos(MasterDevice &, uint16_t, bool);
void listSlaveSdos(MasterDevice &, const ec_ioctl_slave_t &, bool);
};
/****************************************************************************/

View File

@ -50,29 +50,30 @@ string CommandSiiRead::helpString() const
void CommandSiiRead::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
ec_ioctl_slave_t *slave;
ec_ioctl_slave_sii_t data;
ec_ioctl_slave_t slave;
unsigned int i;
const uint16_t *categoryHeader;
uint16_t categoryType, categorySize;
stringstream err;
if (slavePosition < 0) {
err << "'" << getName() << "' requires a slave! "
<< "Please specify --slave.";
m.open(MasterDevice::Read);
slaves = selectedSlaves(m);
if (slaves.size() != 1) {
err << "'" << getName() << "' requires a single slave ("
<< slaves.size() << " selected).";
throwInvalidUsageException(err);
}
data.slave_position = slavePosition;
slave = &slaves.front();
data.slave_position = slave->position;
m.open(MasterDevice::Read);
m.getSlave(&slave, slavePosition);
if (!slave.sii_nwords)
if (!slave->sii_nwords)
return;
data.offset = 0;
data.nwords = slave.sii_nwords;
data.nwords = slave->sii_nwords;
data.words = new uint16_t[data.nwords];
try {

View File

@ -51,6 +51,7 @@ string CommandSiiWrite::helpString() const
void CommandSiiWrite::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
stringstream err;
ec_ioctl_slave_sii_t data;
ifstream file;
@ -59,12 +60,14 @@ void CommandSiiWrite::execute(MasterDevice &m, const StringVector &args)
uint16_t categoryType, categorySize;
uint8_t crc;
if (slavePosition < 0) {
err << "'" << getName() << "' requires a slave! "
<< "Please specify --slave.";
slaves = selectedSlaves(m);
if (slaves.size() != 1) {
err << "'" << getName() << "' requires a single slave ("
<< slaves.size() << " selected).";
throwInvalidUsageException(err);
}
data.slave_position = slavePosition;
data.slave_position = slaves.front().position;
if (args.size() != 1) {
err << "'" << getName() << "' takes exactly one argument!";

View File

@ -65,20 +65,15 @@ string CommandSlaves::helpString() const
void CommandSlaves::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
m.open(MasterDevice::Read);
slaves = selectedSlaves(m);
if (getVerbosity() == Verbose) {
if (slavePosition == -1) {
unsigned int numSlaves = m.slaveCount(), i;
for (i = 0; i < numSlaves; i++) {
showSlave(m, i);
}
} else {
showSlave(m, slavePosition);
}
showSlaves(m, slaves);
} else {
listSlaves(m, slavePosition);
listSlaves(m, slaves);
}
}
@ -86,7 +81,7 @@ void CommandSlaves::execute(MasterDevice &m, const StringVector &args)
void CommandSlaves::listSlaves(
MasterDevice &m,
int slavePosition
const SlaveList &slaves
)
{
unsigned int numSlaves, i;
@ -112,7 +107,7 @@ void CommandSlaves::listSlaves(
aliasIndex = 0;
}
if (slavePosition == -1 || i == (unsigned int) slavePosition) {
if (slaveInList(slave, slaves)) {
str << dec << i;
info.pos = str.str();
str.clear();
@ -169,109 +164,127 @@ void CommandSlaves::listSlaves(
/****************************************************************************/
void CommandSlaves::showSlave(
void CommandSlaves::showSlaves(
MasterDevice &m,
uint16_t slavePosition
const SlaveList &slaves
)
{
ec_ioctl_slave_t slave;
SlaveList::const_iterator si;
list<string> protoList;
list<string>::const_iterator protoIter;
m.getSlave(&slave, slavePosition);
cout << "=== Slave " << dec << slavePosition << " ===" << endl;
if (slave.alias)
cout << "Alias: " << slave.alias << endl;
cout
<< "State: " << alStateString(slave.al_state) << endl
<< "Flag: " << (slave.error_flag ? 'E' : '+') << endl
<< "Identity:" << endl
<< " Vendor Id: 0x"
<< hex << setfill('0')
<< setw(8) << slave.vendor_id << endl
<< " Product code: 0x"
<< setw(8) << slave.product_code << endl
<< " Revision number: 0x"
<< setw(8) << slave.revision_number << endl
<< " Serial number: 0x"
<< setw(8) << slave.serial_number << endl;
for (si = slaves.begin(); si != slaves.end(); si++) {
cout << "=== Slave " << dec << si->position << " ===" << endl;
if (slave.mailbox_protocols) {
cout << "Mailboxes:" << endl
<< " RX: 0x"
<< hex << setw(4) << slave.rx_mailbox_offset << "/"
<< dec << slave.rx_mailbox_size
<< ", TX: 0x"
<< hex << setw(4) << slave.tx_mailbox_offset << "/"
<< dec << slave.tx_mailbox_size << endl
<< " Supported protocols: ";
if (si->alias)
cout << "Alias: " << si->alias << endl;
if (slave.mailbox_protocols & EC_MBOX_AOE) {
protoList.push_back("AoE");
}
if (slave.mailbox_protocols & EC_MBOX_EOE) {
protoList.push_back("EoE");
}
if (slave.mailbox_protocols & EC_MBOX_COE) {
protoList.push_back("CoE");
}
if (slave.mailbox_protocols & EC_MBOX_FOE) {
protoList.push_back("FoE");
}
if (slave.mailbox_protocols & EC_MBOX_SOE) {
protoList.push_back("SoE");
}
if (slave.mailbox_protocols & EC_MBOX_VOE) {
protoList.push_back("VoE");
cout
<< "State: " << alStateString(si->al_state) << endl
<< "Flag: " << (si->error_flag ? 'E' : '+') << endl
<< "Identity:" << endl
<< " Vendor Id: 0x"
<< hex << setfill('0')
<< setw(8) << si->vendor_id << endl
<< " Product code: 0x"
<< setw(8) << si->product_code << endl
<< " Revision number: 0x"
<< setw(8) << si->revision_number << endl
<< " Serial number: 0x"
<< setw(8) << si->serial_number << endl;
if (si->mailbox_protocols) {
cout << "Mailboxes:" << endl
<< " RX: 0x"
<< hex << setw(4) << si->rx_mailbox_offset << "/"
<< dec << si->rx_mailbox_size
<< ", TX: 0x"
<< hex << setw(4) << si->tx_mailbox_offset << "/"
<< dec << si->tx_mailbox_size << endl
<< " Supported protocols: ";
if (si->mailbox_protocols & EC_MBOX_AOE) {
protoList.push_back("AoE");
}
if (si->mailbox_protocols & EC_MBOX_EOE) {
protoList.push_back("EoE");
}
if (si->mailbox_protocols & EC_MBOX_COE) {
protoList.push_back("CoE");
}
if (si->mailbox_protocols & EC_MBOX_FOE) {
protoList.push_back("FoE");
}
if (si->mailbox_protocols & EC_MBOX_SOE) {
protoList.push_back("SoE");
}
if (si->mailbox_protocols & EC_MBOX_VOE) {
protoList.push_back("VoE");
}
for (protoIter = protoList.begin(); protoIter != protoList.end();
protoIter++) {
if (protoIter != protoList.begin())
cout << ", ";
cout << *protoIter;
}
cout << endl;
}
for (protoIter = protoList.begin(); protoIter != protoList.end();
protoIter++) {
if (protoIter != protoList.begin())
cout << ", ";
cout << *protoIter;
if (si->has_general_category) {
cout << "General:" << endl
<< " Group: " << si->group << endl
<< " Image name: " << si->image << endl
<< " Order number: " << si->order << endl
<< " Device name: " << si->name << endl;
if (si->mailbox_protocols & EC_MBOX_COE) {
cout << " CoE details:" << endl
<< " Enable Sdo: "
<< (si->coe_details.enable_sdo ? "yes" : "no") << endl
<< " Enable Sdo Info: "
<< (si->coe_details.enable_sdo_info ? "yes" : "no") << endl
<< " Enable Pdo Assign: "
<< (si->coe_details.enable_pdo_assign
? "yes" : "no") << endl
<< " Enable Pdo Configuration: "
<< (si->coe_details.enable_pdo_configuration
? "yes" : "no") << endl
<< " Enable Upload at startup: "
<< (si->coe_details.enable_upload_at_startup
? "yes" : "no") << endl
<< " Enable Sdo complete access: "
<< (si->coe_details.enable_sdo_complete_access
? "yes" : "no") << endl;
}
cout << " Flags:" << endl
<< " Enable SafeOp: "
<< (si->general_flags.enable_safeop ? "yes" : "no") << endl
<< " Enable notLRW: "
<< (si->general_flags.enable_not_lrw ? "yes" : "no") << endl
<< " Current consumption: "
<< dec << si->current_on_ebus << " mA" << endl;
}
cout << endl;
}
if (slave.has_general_category) {
cout << "General:" << endl
<< " Group: " << slave.group << endl
<< " Image name: " << slave.image << endl
<< " Order number: " << slave.order << endl
<< " Device name: " << slave.name << endl;
if (slave.mailbox_protocols & EC_MBOX_COE) {
cout << " CoE details:" << endl
<< " Enable Sdo: "
<< (slave.coe_details.enable_sdo ? "yes" : "no") << endl
<< " Enable Sdo Info: "
<< (slave.coe_details.enable_sdo_info ? "yes" : "no") << endl
<< " Enable Pdo Assign: "
<< (slave.coe_details.enable_pdo_assign
? "yes" : "no") << endl
<< " Enable Pdo Configuration: "
<< (slave.coe_details.enable_pdo_configuration
? "yes" : "no") << endl
<< " Enable Upload at startup: "
<< (slave.coe_details.enable_upload_at_startup
? "yes" : "no") << endl
<< " Enable Sdo complete access: "
<< (slave.coe_details.enable_sdo_complete_access
? "yes" : "no") << endl;
}
cout << " Flags:" << endl
<< " Enable SafeOp: "
<< (slave.general_flags.enable_safeop ? "yes" : "no") << endl
<< " Enable notLRW: "
<< (slave.general_flags.enable_not_lrw ? "yes" : "no") << endl
<< " Current consumption: "
<< dec << slave.current_on_ebus << " mA" << endl;
}
}
/****************************************************************************/
bool CommandSlaves::slaveInList(
const ec_ioctl_slave_t &slave,
const SlaveList &slaves
)
{
SlaveList::const_iterator si;
for (si = slaves.begin(); si != slaves.end(); si++) {
if (si->position == slave.position) {
return true;
}
}
return false;
}
/*****************************************************************************/

View File

@ -30,8 +30,10 @@ class CommandSlaves:
string name;
};
void listSlaves(MasterDevice &, int);
void showSlave(MasterDevice &, uint16_t);
void listSlaves(MasterDevice &, const SlaveList &);
void showSlaves(MasterDevice &, const SlaveList &);
static bool slaveInList( const ec_ioctl_slave_t &, const SlaveList &);
};
/****************************************************************************/

View File

@ -42,6 +42,8 @@ string CommandStates::helpString() const
void CommandStates::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
SlaveList::const_iterator si;
stringstream err;
string stateStr;
uint8_t state = 0x00;
@ -69,13 +71,10 @@ void CommandStates::execute(MasterDevice &m, const StringVector &args)
}
m.open(MasterDevice::ReadWrite);
slaves = selectedSlaves(m);
if (slavePosition == -1) {
unsigned int i, numSlaves = m.slaveCount();
for (i = 0; i < numSlaves; i++)
m.requestState(i, state);
} else {
m.requestState(slavePosition, state);
for (si = slaves.begin(); si != slaves.end(); si++) {
m.requestState(si->position, state);
}
}

View File

@ -58,19 +58,13 @@ string CommandUpload::helpString() const
void CommandUpload::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
stringstream err, strIndex, strSubIndex;
int sval;
ec_ioctl_slave_sdo_upload_t data;
unsigned int uval;
const CoEDataType *dataType = NULL;
if (slavePosition < 0) {
err << "'" << getName() << "' requires a slave! "
<< "Please specify --slave.";
throwInvalidUsageException(err);
}
data.slave_position = slavePosition;
if (args.size() != 2) {
err << "'" << getName() << "' takes two arguments!";
throwInvalidUsageException(err);
@ -95,6 +89,14 @@ void CommandUpload::execute(MasterDevice &m, const StringVector &args)
}
data.sdo_entry_subindex = uval;
m.open(MasterDevice::Read);
slaves = selectedSlaves(m);
if (slaves.size() != 1) {
err << slaves.size() << " slaves selected, single slave required!";
throwInvalidUsageException(err);
}
data.slave_position = slaves.front().position;
if (dataTypeStr != "") { // data type specified
if (!(dataType = findDataType(dataTypeStr))) {
err << "Invalid data type '" << dataTypeStr << "'!";
@ -103,10 +105,8 @@ void CommandUpload::execute(MasterDevice &m, const StringVector &args)
} else { // no data type specified: fetch from dictionary
ec_ioctl_slave_sdo_entry_t entry;
m.open(MasterDevice::Read);
try {
m.getSdoEntry(&entry, slavePosition,
m.getSdoEntry(&entry, data.slave_position,
data.sdo_index, data.sdo_entry_subindex);
} catch (MasterDeviceException &e) {
err << "Failed to determine Sdo entry data type. "
@ -129,8 +129,6 @@ void CommandUpload::execute(MasterDevice &m, const StringVector &args)
data.target = new uint8_t[data.target_size + 1];
m.open(MasterDevice::Read);
try {
m.sdoUpload(&data);
} catch (MasterDeviceException &e) {

View File

@ -45,32 +45,30 @@ string CommandXml::helpString() const
void CommandXml::execute(MasterDevice &m, const StringVector &args)
{
SlaveList slaves;
SlaveList::const_iterator si;
m.open(MasterDevice::Read);
slaves = selectedSlaves(m);
if (slavePosition == -1) {
unsigned int numSlaves = m.slaveCount(), i;
for (i = 0; i < numSlaves; i++) {
generateSlaveXml(m, i);
}
} else {
generateSlaveXml(m, slavePosition);
for (si = slaves.begin(); si != slaves.end(); si++) {
generateSlaveXml(m, *si);
}
}
/****************************************************************************/
void CommandXml::generateSlaveXml(MasterDevice &m, uint16_t slavePosition)
void CommandXml::generateSlaveXml(
MasterDevice &m,
const ec_ioctl_slave_t &slave
)
{
ec_ioctl_slave_t slave;
ec_ioctl_slave_sync_t sync;
ec_ioctl_slave_sync_pdo_t pdo;
string pdoType;
ec_ioctl_slave_sync_pdo_entry_t entry;
unsigned int i, j, k;
m.getSlave(&slave, slavePosition);
cout
<< "<?xml version=\"1.0\" ?>" << endl
<< " <EtherCATInfo>" << endl
@ -95,7 +93,7 @@ void CommandXml::generateSlaveXml(MasterDevice &m, uint16_t slavePosition)
}
for (i = 0; i < slave.sync_count; i++) {
m.getSync(&sync, slavePosition, i);
m.getSync(&sync, slave.position, i);
cout
<< " <Sm Enable=\"" << dec << (unsigned int) sync.enable
@ -106,10 +104,10 @@ void CommandXml::generateSlaveXml(MasterDevice &m, uint16_t slavePosition)
}
for (i = 0; i < slave.sync_count; i++) {
m.getSync(&sync, slavePosition, i);
m.getSync(&sync, slave.position, i);
for (j = 0; j < sync.pdo_count; j++) {
m.getPdo(&pdo, slavePosition, i, j);
m.getPdo(&pdo, slave.position, i, j);
pdoType = (sync.control_register & 0x04 ? "R" : "T");
pdoType += "xPdo";
@ -122,7 +120,7 @@ void CommandXml::generateSlaveXml(MasterDevice &m, uint16_t slavePosition)
<< " <Name>" << pdo.name << "</Name>" << endl;
for (k = 0; k < pdo.entry_count; k++) {
m.getPdoEntry(&entry, slavePosition, i, j, k);
m.getPdoEntry(&entry, slave.position, i, j, k);
cout
<< " <Entry>" << endl

View File

@ -21,7 +21,7 @@ class CommandXml:
void execute(MasterDevice &, const StringVector &);
protected:
void generateSlaveXml(MasterDevice &, uint16_t);
void generateSlaveXml(MasterDevice &, const ec_ioctl_slave_t &);
};
/****************************************************************************/

View File

@ -41,6 +41,7 @@ Command::StringVector commandArgs;
// option variables
unsigned int masterIndex = 0;
int slavePosition = -1;
int slaveAlias = -1;
int domainIndex = -1;
string dataTypeStr;
Command::Verbosity verbosity = Command::Normal;
@ -98,20 +99,22 @@ void getOptions(int argc, char **argv)
char *remainder;
static struct option longOptions[] = {
//name, has_arg, flag, val
{"master", required_argument, NULL, 'm'},
{"slave", required_argument, NULL, 's'},
{"domain", required_argument, NULL, 'd'},
{"type", required_argument, NULL, 't'},
{"force", no_argument, NULL, 'f'},
{"quiet", no_argument, NULL, 'q'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
//name, has_arg, flag, val
{"master", required_argument, NULL, 'm'},
{"alias", required_argument, NULL, 'a'},
{"position", required_argument, NULL, 'p'},
{"domain", required_argument, NULL, 'd'},
{"type", required_argument, NULL, 't'},
{"force", no_argument, NULL, 'f'},
{"quiet", no_argument, NULL, 'q'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{}
};
do {
c = getopt_long(argc, argv, "m:s:d:t:fqvh", longOptions, &optionIndex);
c = getopt_long(argc, argv, "m:a:p:d:t:fqvh",
longOptions, &optionIndex);
switch (c) {
case 'm':
@ -124,7 +127,22 @@ void getOptions(int argc, char **argv)
masterIndex = number;
break;
case 's':
case 'a':
if (!strcmp(optarg, "all")) {
slaveAlias = -1;
} else {
number = strtoul(optarg, &remainder, 0);
if (remainder == optarg || *remainder
|| number < 0 || number > 0xFFFF) {
cerr << "Invalid slave alias " << optarg << "!"
<< endl << endl << usage();
exit(1);
}
slaveAlias = number;
}
break;
case 'p':
if (!strcmp(optarg, "all")) {
slavePosition = -1;
} else {
@ -265,6 +283,8 @@ int main(int argc, char **argv)
if (!helpRequested) {
try {
cmd->setVerbosity(verbosity);
cmd->setAlias(slaveAlias);
cmd->setPosition(slavePosition);
cmd->execute(masterDev, commandArgs);
} catch (InvalidUsageException &e) {
cerr << e.what() << endl << endl;