Alias/Position selection.
This commit is contained in:
parent
373d8a7475
commit
db277eb34b
5
TODO
5
TODO
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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 << ":"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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!";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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 &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue