tool/cmd_sii_read.cpp
changeset 1142 59be91dfcbe1
parent 1141 7ffbca63fc72
child 1143 09ee878d7214
equal deleted inserted replaced
1141:7ffbca63fc72 1142:59be91dfcbe1
     1 /*****************************************************************************
       
     2  *
       
     3  * $Id$
       
     4  *
       
     5  ****************************************************************************/
       
     6 
       
     7 #include <iostream>
       
     8 #include <iomanip>
       
     9 using namespace std;
       
    10 
       
    11 #include "globals.h"
       
    12 
       
    13 /****************************************************************************/
       
    14 
       
    15 const char *help_sii_read =
       
    16     "[OPTIONS]\n"
       
    17     "\n"
       
    18     "Outputs the SII (EEPROM) contents of a slave.\n"
       
    19     "\n"
       
    20     "Without the --verbose option, binary SII contents are output. They can\n"
       
    21     "be piped to a tool like hexdump, for example:\n"
       
    22     "\n"
       
    23     "  ethercat sii_read -s2 | hexdump -C\n"
       
    24     "\n"
       
    25     "With the --verbose option given, a textual representation of the data\n"
       
    26     "is output, that is separated by SII category names.\n"
       
    27     "\n"
       
    28     "Command-specific options:\n"
       
    29     "  --slave   -s <index>  Positive numerical ring position (mandatory).\n"
       
    30     "  --verbose -v          Output textual data with category names.\n"
       
    31     "\n"
       
    32     "Numerical values can be specified either with decimal (no prefix),\n"
       
    33     "octal (prefix '0') or hexadecimal (prefix '0x') base.\n";
       
    34 
       
    35 /****************************************************************************/
       
    36 
       
    37 struct CategoryName {
       
    38     uint16_t type;
       
    39     const char *name;
       
    40 };
       
    41 
       
    42 static const CategoryName categoryNames[] = {
       
    43     {0x000a, "STRINGS"},
       
    44     {0x0014, "DataTypes"},
       
    45     {0x001e, "General"},
       
    46     {0x0028, "FMMU"},
       
    47     {0x0029, "SyncM"},
       
    48     {0x0032, "TXPDO"},
       
    49     {0x0033, "RXPDO"},
       
    50     {0x003c, "DC"},
       
    51     {}
       
    52 };
       
    53 
       
    54 /****************************************************************************/
       
    55 
       
    56 const char *getCategoryName(uint16_t type)
       
    57 {
       
    58     const CategoryName *cn = categoryNames;
       
    59 
       
    60     while (cn->type) {
       
    61         if (cn->type == type) {
       
    62             return cn->name;
       
    63         }
       
    64         cn++;
       
    65     }
       
    66 
       
    67     return "unknown";
       
    68 }
       
    69 
       
    70 /****************************************************************************/
       
    71 
       
    72 void command_sii_read(void)
       
    73 {
       
    74     ec_ioctl_slave_sii_t data;
       
    75     ec_ioctl_slave_t slave;
       
    76     unsigned int i;
       
    77     const uint16_t *categoryHeader;
       
    78     uint16_t categoryType, categorySize;
       
    79     stringstream err;
       
    80 
       
    81     if (slavePosition < 0) {
       
    82         err << "'" << commandName << "' requires a slave! "
       
    83             << "Please specify --slave.";
       
    84         throw InvalidUsageException(err);
       
    85     }
       
    86     data.slave_position = slavePosition;
       
    87 
       
    88     masterDev.open(MasterDevice::Read);
       
    89 
       
    90     masterDev.getSlave(&slave, slavePosition);
       
    91 
       
    92     if (!slave.sii_nwords)
       
    93         return;
       
    94 
       
    95     data.offset = 0;
       
    96     data.nwords = slave.sii_nwords;
       
    97     data.words = new uint16_t[data.nwords];
       
    98 
       
    99 	try {
       
   100 		masterDev.readSii(&data);
       
   101 	} catch (MasterDeviceException &e) {
       
   102         delete [] data.words;
       
   103 		throw e;
       
   104 	}
       
   105 
       
   106     if (verbosity == Verbose) {
       
   107         cout << "SII Area:" << hex << setfill('0');
       
   108         for (i = 0; i < min(data.nwords, 0x0040U) * 2; i++) {
       
   109             if (i % BreakAfterBytes) {
       
   110                 cout << " ";
       
   111             } else {
       
   112                 cout << endl << "  ";
       
   113             }
       
   114             cout << setw(2) << (unsigned int) *((uint8_t *) data.words + i);
       
   115         }
       
   116         cout << endl;
       
   117 
       
   118         if (data.nwords > 0x0040U) {
       
   119             // cycle through categories
       
   120             categoryHeader = data.words + 0x0040U;
       
   121             categoryType = le16tocpu(*categoryHeader);
       
   122             while (categoryType != 0xffff) {
       
   123                 cout << "SII Category 0x" << hex
       
   124                     << setw(4) << categoryType
       
   125                     << " (" << getCategoryName(categoryType) << ")" << flush;
       
   126 
       
   127                 if (categoryHeader + 1 > data.words + data.nwords) {
       
   128                     err << "SII data seem to be corrupted!";
       
   129                     throw CommandException(err);
       
   130                 }
       
   131                 categorySize = le16tocpu(*(categoryHeader + 1));
       
   132                 cout << ", " << dec << categorySize << " words" << flush;
       
   133 
       
   134                 if (categoryHeader + 2 + categorySize
       
   135                         > data.words + data.nwords) {
       
   136                     err << "SII data seem to be corrupted!";
       
   137                     throw CommandException(err);
       
   138                 }
       
   139 
       
   140                 cout << hex;
       
   141                 for (i = 0; i < categorySize * 2U; i++) {
       
   142                     if (i % BreakAfterBytes) {
       
   143                         cout << " ";
       
   144                     } else {
       
   145                         cout << endl << "  ";
       
   146                     }
       
   147                     cout << setw(2) << (unsigned int)
       
   148                         *((uint8_t *) (categoryHeader + 2) + i);
       
   149                 }
       
   150                 cout << endl;
       
   151 
       
   152                 if (categoryHeader + 2 + categorySize + 1
       
   153                         > data.words + data.nwords) {
       
   154                     err << "SII data seem to be corrupted!"; 
       
   155                     throw CommandException(err);
       
   156                 }
       
   157                 categoryHeader += 2 + categorySize;
       
   158                 categoryType = le16tocpu(*categoryHeader);
       
   159             }
       
   160         }
       
   161     } else {
       
   162         for (i = 0; i < data.nwords; i++) {
       
   163             uint16_t *w = data.words + i;
       
   164             cout << *(uint8_t *) w << *((uint8_t *) w + 1);
       
   165         }
       
   166     }
       
   167 
       
   168     delete [] data.words;
       
   169 }
       
   170 
       
   171 /*****************************************************************************/