From 4a523846619298d84dc472123e788d88351b0384 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 24 Oct 2012 18:21:52 +0200 Subject: [PATCH] EtherLab skin for 'ethercat pdos' command. --- tool/Command.cpp | 7 ++ tool/Command.h | 11 +++ tool/CommandPdos.cpp | 160 +++++++++++++++++++++++++++++++++++++++---- tool/CommandPdos.h | 1 + tool/main.cpp | 9 ++- 5 files changed, 175 insertions(+), 13 deletions(-) diff --git a/tool/Command.cpp b/tool/Command.cpp index 9bf1225d..65ff67a6 100644 --- a/tool/Command.cpp +++ b/tool/Command.cpp @@ -216,6 +216,13 @@ void Command::setOutputFile(const string &f) outputFile = f; }; +/*****************************************************************************/ + +void Command::setSkin(const string &s) +{ + skin = s; +}; + /****************************************************************************/ bool Command::matchesSubstr(const string &cmd) const diff --git a/tool/Command.h b/tool/Command.h index fcb1700f..254348fe 100644 --- a/tool/Command.h +++ b/tool/Command.h @@ -113,6 +113,9 @@ class Command void setOutputFile(const string &); const string &getOutputFile() const; + void setSkin(const string &); + const string &getSkin() const; + bool matchesSubstr(const string &) const; bool matchesAbbrev(const string &) const; @@ -151,6 +154,7 @@ class Command string dataType; bool force; string outputFile; + string skin; Command(); }; @@ -199,4 +203,11 @@ inline const string &Command::getOutputFile() const /****************************************************************************/ +inline const string &Command::getSkin() const +{ + return skin; +} + +/****************************************************************************/ + #endif diff --git a/tool/CommandPdos.cpp b/tool/CommandPdos.cpp index 32906992..126b76c9 100644 --- a/tool/CommandPdos.cpp +++ b/tool/CommandPdos.cpp @@ -29,6 +29,7 @@ #include #include +#include using namespace std; #include "CommandPdos.h" @@ -51,7 +52,8 @@ string CommandPdos::helpString(const string &binaryBaseName) const << endl << getBriefDescription() << endl << endl - << "The information is displayed in three layers, which are" << endl + << "For the default skin (see --skin option) the information" << endl + << "is displayed in three layers, which are" << endl << "indented accordingly:" << endl << endl << "1) Sync managers - Contains the sync manager information" << endl @@ -77,10 +79,16 @@ string CommandPdos::helpString(const string &binaryBaseName) const << "information can either originate from the SII or from the" << endl << "CoE communication area." << endl << endl + << "The \"etherlab\" skin outputs a template configuration" << endl + << "for EtherLab's generic EtherCAT slave block." << endl + << endl << "Command-specific options:" << endl << " --alias -a " << endl << " --position -p Slave selection. See the help of" << endl << " the 'slaves' command." << endl + << " --skin -s Choose output skin. Possible values are" + << endl + << " \"default\" and \"etherlab\"." << endl << endl << numericInfo(); @@ -102,20 +110,41 @@ void CommandPdos::execute(const StringVector &args) throwInvalidUsageException(err); } - masterIndices = getMasterIndices(); - multiMaster = masterIndices.size() > 1; - MasterIndexList::const_iterator mi; - for (mi = masterIndices.begin(); - mi != masterIndices.end(); mi++) { - MasterDevice m(*mi); - m.open(MasterDevice::Read); - slaves = selectedSlaves(m); - showHeader = multiMaster || slaves.size() > 1; + if (getSkin().empty() || getSkin() == "default") { + masterIndices = getMasterIndices(); + multiMaster = masterIndices.size() > 1; + MasterIndexList::const_iterator mi; + for (mi = masterIndices.begin(); + mi != masterIndices.end(); mi++) { + MasterDevice m(*mi); + m.open(MasterDevice::Read); + slaves = selectedSlaves(m); + showHeader = multiMaster || slaves.size() > 1; - for (si = slaves.begin(); si != slaves.end(); si++) { - listSlavePdos(m, *si, showHeader); + for (si = slaves.begin(); si != slaves.end(); si++) { + listSlavePdos(m, *si, showHeader); + } } } + else if (getSkin() == "etherlab") { + masterIndices = getMasterIndices(); + MasterIndexList::const_iterator mi; + for (mi = masterIndices.begin(); + mi != masterIndices.end(); mi++) { + MasterDevice m(*mi); + m.open(MasterDevice::Read); + slaves = selectedSlaves(m); + + for (si = slaves.begin(); si != slaves.end(); si++) { + etherlabConfig(m, *si); + } + } + } + else { + stringstream err; + err << "Invalid skin '" << getSkin() << "'!"; + throwInvalidUsageException(err); + } } /****************************************************************************/ @@ -177,4 +206,111 @@ void CommandPdos::listSlavePdos( } } +/****************************************************************************/ + +void CommandPdos::etherlabConfig( + MasterDevice &m, + const 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; + + cout << "%" << endl + << "% Master " << m.getIndex() << ", Slave " << slave.position; + if (strlen(slave.order)) { + cout << ", \"" << slave.order << "\""; + } + cout << endl + << "%" << endl + << "function rv = slave" << slave.position << "()" << endl << endl; + + cout << "% Slave configuration" << endl << endl; + + cout << "rv.SlaveConfig.vendor = " << slave.vendor_id << ";" << endl + << "rv.SlaveConfig.product = hex2dec('" + << hex << setfill('0') << setw(8) << slave.product_code << "');" + << endl + << "rv.SlaveConfig.description = '" << slave.order << "';" << endl + << "rv.SlaveConfig.sm = { ..." << endl; + + /* slave configuration */ + for (i = 0; i < slave.sync_count; i++) { + m.getSync(&sync, slave.position, i); + + cout << " {" << dec << i << ", " + << (sync.control_register & 0x04 ? 0 : 1) << ", {" << endl; + + for (j = 0; j < sync.pdo_count; j++) { + m.getPdo(&pdo, slave.position, i, j); + + cout << " {hex2dec('" << + hex << setfill('0') << setw(4) << pdo.index << "'), [" + << endl; + + for (k = 0; k < pdo.entry_count; k++) { + m.getPdoEntry(&entry, slave.position, i, j, k); + + cout << " hex2dec('" + << hex << setfill('0') << setw(4) << entry.index + << "'), hex2dec('" + << setw(2) << (unsigned int) entry.subindex + << "'), " << dec << setfill(' ') << setw(3) + << (unsigned int) entry.bit_length + << "; ..." << endl; + } + + cout << " ]}, ..." << endl; + } + cout << " }}, ..." << endl; + } + + cout << " };" << endl << endl; + + cout << "% Port configuration" << endl << endl; + + unsigned int input = 1, output = 1; + for (i = 0; i < slave.sync_count; i++) { + m.getSync(&sync, slave.position, i); + + for (j = 0; j < sync.pdo_count; j++) { + m.getPdo(&pdo, slave.position, i, j); + + for (k = 0; k < pdo.entry_count; k++) { + m.getPdoEntry(&entry, slave.position, i, j, k); + + if (!entry.index) { + continue; + } + + string dir; + unsigned int port; + + if (sync.control_register & 0x04) { + dir = "input"; + port = input++; + } + else { + dir = "output"; + port = output++; + } + + stringstream var; + var << "rv.PortConfig." << dir << "(" << dec << port + << ")"; + + cout << var.str() << ".pdo = [" + << i << ", " << j << ", " << k << ", 0];" << endl; + cout << var.str() << ".pdo_data_type = " + << 1000 + (unsigned int) entry.bit_length + << ";" << endl << endl; + } + } + } + + cout << "end" << endl; +} + /*****************************************************************************/ diff --git a/tool/CommandPdos.h b/tool/CommandPdos.h index a1c0a54b..b390b81f 100644 --- a/tool/CommandPdos.h +++ b/tool/CommandPdos.h @@ -45,6 +45,7 @@ class CommandPdos: protected: void listSlavePdos(MasterDevice &, const ec_ioctl_slave_t &, bool); + void etherlabConfig(MasterDevice &, const ec_ioctl_slave_t &); }; /****************************************************************************/ diff --git a/tool/main.cpp b/tool/main.cpp index b03851f1..e9520014 100644 --- a/tool/main.cpp +++ b/tool/main.cpp @@ -85,6 +85,7 @@ Command::Verbosity verbosity = Command::Normal; bool force = false; bool helpRequested = false; string outputFile; +string skin; /*****************************************************************************/ @@ -147,6 +148,7 @@ void getOptions(int argc, char **argv) {"domain", required_argument, NULL, 'd'}, {"type", required_argument, NULL, 't'}, {"output-file", required_argument, NULL, 'o'}, + {"skin", required_argument, NULL, 's'}, {"force", no_argument, NULL, 'f'}, {"quiet", no_argument, NULL, 'q'}, {"verbose", no_argument, NULL, 'v'}, @@ -155,7 +157,7 @@ void getOptions(int argc, char **argv) }; do { - c = getopt_long(argc, argv, "m:a:p:d:t:o:fqvh", longOptions, NULL); + c = getopt_long(argc, argv, "m:a:p:d:t:o:s:fqvh", longOptions, NULL); switch (c) { case 'm': @@ -182,6 +184,10 @@ void getOptions(int argc, char **argv) outputFile = optarg; break; + case 's': + skin = optarg; + break; + case 'f': force = true; break; @@ -308,6 +314,7 @@ int main(int argc, char **argv) cmd->setDomains(domains); cmd->setDataType(dataTypeStr); cmd->setOutputFile(outputFile); + cmd->setSkin(skin); cmd->setForce(force); cmd->execute(commandArgs); } catch (InvalidUsageException &e) {