diff -r 7ffbca63fc72 -r 59be91dfcbe1 tool/CommandSiiRead.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/CommandSiiRead.cpp Thu Jul 24 13:27:06 2008 +0000 @@ -0,0 +1,180 @@ +/***************************************************************************** + * + * $Id$ + * + ****************************************************************************/ + +#include +#include +using namespace std; + +#include "CommandSiiRead.h" +#include "byteorder.h" + +/*****************************************************************************/ + +CommandSiiRead::CommandSiiRead(): + Command("sii_read", "Output a slave's SII contents.") +{ +} + +/*****************************************************************************/ + +string CommandSiiRead::helpString() const +{ + stringstream str; + + str << getName() << " [OPTIONS]" << endl + << endl + << getBriefDescription() << endl + << endl + << "Without the --verbose option, binary SII contents are" << endl + << "output." << endl + << endl + << "With the --verbose option given, a textual representation" << endl + << "of the data is output, that is separated by SII category" << endl + << "names." << endl + << endl + << "Command-specific options:" << endl + << " --slave -s Positive numerical ring position" << endl + << " (mandatory)." << endl + << " --verbose -v Output textual data with" << endl + << " category names." << endl + << endl + << numericInfo(); + + return str.str(); +} + +/****************************************************************************/ + +void CommandSiiRead::execute(MasterDevice &m, const StringVector &args) +{ + 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."; + throwInvalidUsageException(err); + } + data.slave_position = slavePosition; + + m.open(MasterDevice::Read); + + m.getSlave(&slave, slavePosition); + + if (!slave.sii_nwords) + return; + + data.offset = 0; + data.nwords = slave.sii_nwords; + data.words = new uint16_t[data.nwords]; + + try { + m.readSii(&data); + } catch (MasterDeviceException &e) { + delete [] data.words; + throw e; + } + + if (getVerbosity() == Verbose) { + cout << "SII Area:" << hex << setfill('0'); + for (i = 0; i < min(data.nwords, 0x0040U) * 2; i++) { + if (i % BreakAfterBytes) { + cout << " "; + } else { + cout << endl << " "; + } + cout << setw(2) << (unsigned int) *((uint8_t *) data.words + i); + } + cout << endl; + + if (data.nwords > 0x0040U) { + // cycle through categories + categoryHeader = data.words + 0x0040U; + categoryType = le16tocpu(*categoryHeader); + while (categoryType != 0xffff) { + cout << "SII Category 0x" << hex + << setw(4) << categoryType + << " (" << getCategoryName(categoryType) << ")" << flush; + + if (categoryHeader + 1 > data.words + data.nwords) { + err << "SII data seem to be corrupted!"; + throwCommandException(err); + } + categorySize = le16tocpu(*(categoryHeader + 1)); + cout << ", " << dec << categorySize << " words" << flush; + + if (categoryHeader + 2 + categorySize + > data.words + data.nwords) { + err << "SII data seem to be corrupted!"; + throwCommandException(err); + } + + cout << hex; + for (i = 0; i < categorySize * 2U; i++) { + if (i % BreakAfterBytes) { + cout << " "; + } else { + cout << endl << " "; + } + cout << setw(2) << (unsigned int) + *((uint8_t *) (categoryHeader + 2) + i); + } + cout << endl; + + if (categoryHeader + 2 + categorySize + 1 + > data.words + data.nwords) { + err << "SII data seem to be corrupted!"; + throwCommandException(err); + } + categoryHeader += 2 + categorySize; + categoryType = le16tocpu(*categoryHeader); + } + } + } else { + for (i = 0; i < data.nwords; i++) { + uint16_t *w = data.words + i; + cout << *(uint8_t *) w << *((uint8_t *) w + 1); + } + } + + delete [] data.words; +} + +/****************************************************************************/ + +const CommandSiiRead::CategoryName CommandSiiRead::categoryNames[] = { + {0x000a, "STRINGS"}, + {0x0014, "DataTypes"}, + {0x001e, "General"}, + {0x0028, "FMMU"}, + {0x0029, "SyncM"}, + {0x0032, "TXPDO"}, + {0x0033, "RXPDO"}, + {0x003c, "DC"}, + {} +}; + +/****************************************************************************/ + +const char *CommandSiiRead::getCategoryName(uint16_t type) +{ + const CategoryName *cn = categoryNames; + + while (cn->type) { + if (cn->type == type) { + return cn->name; + } + cn++; + } + + return "unknown"; +} + +/*****************************************************************************/