# HG changeset patch # User Florian Pose # Date 1292863957 -3600 # Node ID 04fdb4abf12068a968f393dcd1ef645394b6519f # Parent 87de63b19e4c9b5b7da58fcb96658c3bd3b39eec# Parent b5391b329b5d4563fe26db65814eaa218f2ac52b merge. diff -r b5391b329b5d -r 04fdb4abf120 TODO --- a/TODO Tue Nov 30 15:24:21 2010 +0100 +++ b/TODO Mon Dec 20 17:52:37 2010 +0100 @@ -13,17 +13,12 @@ * Ethernet drivers: - Fix link detection in generic driver. - Add native drivers from 2.6.24 up to 2.6.31. -* ethercat tool: - - Implement ranges for slaves and domains. Future issues: * Remove allow_scanning flag. -* Output skipped datagrams again. * Check for Enable SDO Complete Access flag. * Do not output 'SDO does not exist' when querying data type. -* Always write down PDO assignment/mapping in doubt? If not, add an interface - for enforcing this. * Read AL status code on spontaneous state change. * recompile tool/CommandVersion.cpp if revision changes. * Log SoE IDNs with real name ([SP]-x-yyyy). diff -r b5391b329b5d -r 04fdb4abf120 tool/Command.cpp --- a/tool/Command.cpp Tue Nov 30 15:24:21 2010 +0100 +++ b/tool/Command.cpp Mon Dec 20 17:52:37 2010 +0100 @@ -29,6 +29,9 @@ * ****************************************************************************/ +#include +using namespace std; + #include "Command.h" #include "MasterDevice.h" #include "NumberListParser.h" @@ -38,13 +41,89 @@ class MasterIndexParser: public NumberListParser { - unsigned int getMax() - { - MasterDevice dev; - dev.setIndex(0U); - dev.open(MasterDevice::Read); - return dev.getMasterCount() - 1; - }; + protected: + int getMax() { + MasterDevice dev; + dev.setIndex(0U); + dev.open(MasterDevice::Read); + return (int) dev.getMasterCount() - 1; + }; +}; + +/*****************************************************************************/ + +class SlaveAliasParser: + public NumberListParser +{ + public: + SlaveAliasParser(ec_ioctl_master_t &master, MasterDevice &dev): + master(master), dev(dev) {} + + protected: + int getMax() { + unsigned int i; + + uint16_t maxAlias = 0; + for (i = 0; i < master.slave_count; i++) { + ec_ioctl_slave_t slave; + dev.getSlave(&slave, i); + if (slave.alias > maxAlias) { + maxAlias = slave.alias; + } + } + return maxAlias ? maxAlias : -1; + }; + + private: + ec_ioctl_master_t &master; + MasterDevice &dev; +}; + +/*****************************************************************************/ + +class ConfigAliasParser: + public NumberListParser +{ + public: + ConfigAliasParser(ec_ioctl_master_t &master, MasterDevice &dev): + master(master), dev(dev) {} + + protected: + int getMax() { + unsigned int i; + + uint16_t maxAlias = 0; + for (i = 0; i < master.config_count; i++) { + ec_ioctl_config_t config; + dev.getConfig(&config, i); + if (config.alias > maxAlias) { + maxAlias = config.alias; + } + } + return maxAlias ? maxAlias : -1; + }; + + private: + ec_ioctl_master_t &master; + MasterDevice &dev; +}; + +/*****************************************************************************/ + +class PositionParser: + public NumberListParser +{ + public: + PositionParser(unsigned int count): + count(count) {} + + protected: + int getMax() { + return count - 1; + }; + + private: + const unsigned int count; }; /*****************************************************************************/ @@ -78,23 +157,23 @@ /*****************************************************************************/ -void Command::setAlias(int a) -{ - alias = a; -}; - -/*****************************************************************************/ - -void Command::setPosition(int p) -{ - position = p; -}; - -/*****************************************************************************/ - -void Command::setDomain(int d) -{ - domain = d; +void Command::setAliases(const string &a) +{ + aliases = a; +}; + +/*****************************************************************************/ + +void Command::setPositions(const string &p) +{ + positions = p; +}; + +/*****************************************************************************/ + +void Command::setDomains(const string &d) +{ + domains = d; }; /*****************************************************************************/ @@ -227,51 +306,59 @@ Command::SlaveList Command::selectedSlaves(MasterDevice &m) { ec_ioctl_master_t master; - unsigned int i, aliasIndex; - uint16_t lastAlias; + unsigned int i; ec_ioctl_slave_t slave; SlaveList list; m.getMaster(&master); - if (alias == -1) { // no alias given - if (position == -1) { // no alias and position given - // all items - for (i = 0; i < master.slave_count; i++) { - m.getSlave(&slave, i); - list.push_back(slave); - } - } else { // no alias, but position given - // one item by position - m.getSlave(&slave, position); + if (aliases == "-") { // no alias given + PositionParser pp(master.slave_count); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + for (pi = posList.begin(); pi != posList.end(); pi++) { + m.getSlave(&slave, *pi); list.push_back(slave); } - } else { // alias given - if (position == -1) { // alias, but no position given - // take all items with a given alias - lastAlias = 0; + } else { // aliases given + SlaveAliasParser ap(master, m); + NumberListParser::List aliasList = ap.parse(aliases.c_str()); + NumberListParser::List::const_iterator ai; + + for (ai = aliasList.begin(); ai != aliasList.end(); ai++) { + + // gather slaves with that alias (and following) + uint16_t lastAlias = 0; + vector aliasSlaves; + for (i = 0; i < master.slave_count; i++) { m.getSlave(&slave, i); if (slave.alias) { + if (lastAlias && lastAlias == *ai && slave.alias != *ai) { + // ignore multiple ocurrences of the same alias to + // assure consistency for the position argument + break; + } 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 < master.slave_count; i++) { - m.getSlave(&slave, i); - if (slave.alias && slave.alias == (uint16_t) alias) { - lastAlias = slave.alias; - aliasIndex = 0; - } - if (lastAlias && aliasIndex == (unsigned int) position) { - list.push_back(slave); - } - aliasIndex++; + if (lastAlias == *ai) { + aliasSlaves.push_back(slave); + } + } + + PositionParser pp(aliasSlaves.size()); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + + for (pi = posList.begin(); pi != posList.end(); pi++) { + if (*pi < aliasSlaves.size()) { + list.push_back(aliasSlaves[*pi]); + } else { + stringstream err; + err << "Warning: Slave " << *ai << ":" << *pi + << " does not exist on master " << m.getIndex(); + throwCommandException(err); + } } } } @@ -302,37 +389,50 @@ m.getMaster(&master); - if (alias == -1) { // no alias given - if (position == -1) { // no alias and position given - // all items + if (aliases == "-") { // no alias given + PositionParser pp(master.config_count); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + for (pi = posList.begin(); pi != posList.end(); pi++) { + m.getConfig(&config, *pi); // FIXME use sorted list + list.push_back(config); + } + } else { // alias given + ConfigAliasParser ap(master, m); + NumberListParser::List aliasList = ap.parse(aliases.c_str()); + NumberListParser::List::const_iterator ai; + + for (ai = aliasList.begin(); ai != aliasList.end(); ai++) { + + // gather configs with that alias + map aliasConfigs; + + int maxPos = -1; for (i = 0; i < master.config_count; i++) { m.getConfig(&config, i); - list.push_back(config); - } - } else { // no alias, but position given - for (i = 0; i < master.config_count; i++) { - m.getConfig(&config, i); - if (!config.alias && config.position == position) { - list.push_back(config); - break; // there can be at most one matching - } - } - } - } else { // alias given - if (position == -1) { // alias, but no position given - // take all items with a given alias - for (i = 0; i < master.config_count; i++) { - m.getConfig(&config, i); - if (config.alias == alias) { - list.push_back(config); - } - } - } else { // alias and position given - for (i = 0; i < master.config_count; i++) { - m.getConfig(&config, i); - if (config.alias == alias && config.position == position) { - list.push_back(config); - break; // there can be at most one matching + if (config.alias == *ai) { + aliasConfigs[config.position] = config; + if (config.position > maxPos) { + maxPos = config.position; + } + } + } + + PositionParser pp(maxPos + 1); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + + for (pi = posList.begin(); pi != posList.end(); pi++) { + map::const_iterator ci; + ci = aliasConfigs.find(*pi); + + if (ci != aliasConfigs.end()) { + list.push_back(ci->second); + } else { + stringstream err; + err << "Warning: Config " << *ai << ":" << *pi + << " does not exist on master " << m.getIndex(); + throwCommandException(err); } } } @@ -346,21 +446,18 @@ Command::DomainList Command::selectedDomains(MasterDevice &m) { - ec_ioctl_domain_t d; + ec_ioctl_master_t master; DomainList list; - if (domain == -1) { - ec_ioctl_master_t master; - unsigned int i; - - m.getMaster(&master); - - for (i = 0; i < master.domain_count; i++) { - m.getDomain(&d, i); - list.push_back(d); - } - } else { - m.getDomain(&d, domain); + m.getMaster(&master); + + PositionParser pp(master.domain_count); + NumberListParser::List domList = pp.parse(domains.c_str()); + NumberListParser::List::const_iterator di; + + for (di = domList.begin(); di != domList.end(); di++) { + ec_ioctl_domain_t d; + m.getDomain(&d, *di); list.push_back(d); } diff -r b5391b329b5d -r 04fdb4abf120 tool/Command.h --- a/tool/Command.h Tue Nov 30 15:24:21 2010 +0100 +++ b/tool/Command.h Mon Dec 20 17:52:37 2010 +0100 @@ -96,16 +96,20 @@ }; void setVerbosity(Verbosity); Verbosity getVerbosity() const; - void setAlias(int); - int getAlias() const; - void setPosition(int); - int getPosition() const; - void setDomain(int); - int getDomain() const; + + void setAliases(const string &); + void setPositions(const string &); + + void setDomains(const string &); + typedef list DomainIndexList; + DomainIndexList getDomainIndices() const; + void setDataType(const string &); const string &getDataType() const; + void setForce(bool); bool getForce() const; + void setOutputFile(const string &); const string &getOutputFile() const; @@ -141,9 +145,9 @@ string briefDesc; string masters; Verbosity verbosity; - int alias; - int position; - int domain; + string aliases; + string positions; + string domains; string dataType; bool force; string outputFile; @@ -174,27 +178,6 @@ /****************************************************************************/ -inline int Command::getAlias() const -{ - return alias; -} - -/****************************************************************************/ - -inline int Command::getPosition() const -{ - return position; -} - -/****************************************************************************/ - -inline int Command::getDomain() const -{ - return domain; -} - -/****************************************************************************/ - inline const string &Command::getDataType() const { return dataType; diff -r b5391b329b5d -r 04fdb4abf120 tool/NumberListParser.cpp --- a/tool/NumberListParser.cpp Tue Nov 30 15:24:21 2010 +0100 +++ b/tool/NumberListParser.cpp Mon Dec 20 17:52:37 2010 +0100 @@ -50,9 +50,9 @@ /*****************************************************************************/ -NumberListParser::NumberList NumberListParser::parse(const char *data) -{ - NumberList ret; +NumberListParser::List NumberListParser::parse(const char *data) +{ + List ret; unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U; typedef enum { SectionStart, @@ -108,17 +108,40 @@ case Range: if (i >= size) { - secondNum = maximum(); - NumberList r = range(firstNum, secondNum); - ret.splice(ret.end(), r); + int max = maximum(); + if (max >= 0) { + List r = range(firstNum, max); + ret.splice(ret.end(), r); + } state = Finished; } else if (isNumeric(data[i])) { secondNum = parseNumber(data, &i, size); state = SecondNumber; } else if (data[i] == ',') { - i++; - secondNum = maximum(); - NumberList r = range(firstNum, secondNum); + int max = maximum(); + i++; + if (max >= 0) { + List r = range(firstNum, max); + ret.splice(ret.end(), r); + } + state = SectionStart; + } else { + stringstream err; + err << "Invalid character " << data[i] + << " at position " << i << "in state " + << state << "." << endl; + throw runtime_error(err.str()); + } + break; + + case SecondNumber: + if (i >= size) { + List r = range(firstNum, secondNum); + ret.splice(ret.end(), r); + state = Finished; + } else if (data[i] == ',') { + i++; + List r = range(firstNum, secondNum); ret.splice(ret.end(), r); state = SectionStart; } else { @@ -130,25 +153,6 @@ } break; - case SecondNumber: - if (i >= size) { - NumberList r = range(firstNum, secondNum); - ret.splice(ret.end(), r); - state = Finished; - } else if (data[i] == ',') { - i++; - NumberList r = range(firstNum, secondNum); - ret.splice(ret.end(), r); - state = SectionStart; - } else { - stringstream err; - err << "Invalid character " << data[i] - << " at position " << i << "in state " - << state << "." << endl; - throw runtime_error(err.str()); - } - break; - default: { stringstream err; @@ -163,7 +167,7 @@ /*****************************************************************************/ -unsigned int NumberListParser::maximum() +int NumberListParser::maximum() { if (!hasMax) { max = getMax(); @@ -207,12 +211,12 @@ /****************************************************************************/ -NumberListParser::NumberList NumberListParser::range( +NumberListParser::List NumberListParser::range( unsigned int i, unsigned int j ) { - NumberList ret; + List ret; if (i <= j) { for (; i <= j; i++) { diff -r b5391b329b5d -r 04fdb4abf120 tool/NumberListParser.h --- a/tool/NumberListParser.h Tue Nov 30 15:24:21 2010 +0100 +++ b/tool/NumberListParser.h Mon Dec 20 17:52:37 2010 +0100 @@ -38,22 +38,22 @@ NumberListParser(); virtual ~NumberListParser(); - typedef list NumberList; + typedef list List; - NumberList parse(const char *); + List parse(const char *); - virtual unsigned int getMax() = 0; + virtual int getMax() = 0; private: - unsigned int max; + int max; bool hasMax; - unsigned int maximum(); + int maximum(); static bool isNumeric(char); static unsigned int parseNumber(const char *, unsigned int *, unsigned int); - static NumberList range(unsigned int, unsigned int); + static List range(unsigned int, unsigned int); }; /****************************************************************************/ diff -r b5391b329b5d -r 04fdb4abf120 tool/main.cpp --- a/tool/main.cpp Tue Nov 30 15:24:21 2010 +0100 +++ b/tool/main.cpp Mon Dec 20 17:52:37 2010 +0100 @@ -77,9 +77,9 @@ // option variables string masters = "-"; // all masters -int slavePosition = -1; -int slaveAlias = -1; -int domainIndex = -1; +string positions = "-"; // all positions +string aliases = "-"; // all aliases +string domains = "-"; // all domains string dataTypeStr; Command::Verbosity verbosity = Command::Normal; bool force = false; @@ -163,43 +163,15 @@ break; case 'a': - str.clear(); - str.str(""); - str << optarg; - str >> resetiosflags(ios::basefield) // guess base from prefix - >> slaveAlias; - if (str.fail() || slaveAlias < 0 || slaveAlias > 0xFFFF) { - cerr << "Invalid slave alias " << optarg << "!" << endl - << endl << usage(); - exit(1); - } + aliases = optarg; break; case 'p': - str.clear(); - str.str(""); - str << optarg; - str >> resetiosflags(ios::basefield) // guess base from prefix - >> slavePosition; - if (str.fail() - || slavePosition < 0 || slavePosition > 0xFFFF) { - cerr << "Invalid slave position " << optarg << "!" << endl - << endl << usage(); - exit(1); - } + positions = optarg; break; case 'd': - str.clear(); - str.str(""); - str << optarg; - str >> resetiosflags(ios::basefield) // guess base from prefix - >> domainIndex; - if (str.fail() || domainIndex < 0) { - cerr << "Invalid domain index " << optarg << "!" << endl - << endl << usage(); - exit(1); - } + domains = optarg; break; case 't': @@ -331,9 +303,9 @@ try { cmd->setMasters(masters); cmd->setVerbosity(verbosity); - cmd->setAlias(slaveAlias); - cmd->setPosition(slavePosition); - cmd->setDomain(domainIndex); + cmd->setAliases(aliases); + cmd->setPositions(positions); + cmd->setDomains(domains); cmd->setDataType(dataTypeStr); cmd->setOutputFile(outputFile); cmd->setForce(force);