tool/CommandDownload.cpp
changeset 2150 5144a4bc6184
parent 1968 4f682084c643
child 2411 01370d59233d
equal deleted inserted replaced
2149:98e1e773bed0 2150:5144a4bc6184
     1 /*****************************************************************************
     1 /*****************************************************************************
     2  *
     2  *
     3  *  $Id$
     3  *  $Id: CommandDownload.cpp,v 4f682084c643 2010/10/25 08:12:26 fp $
     4  *
     4  *
     5  *  Copyright (C) 2006-2009  Florian Pose, Ingenieurgemeinschaft IgH
     5  *  Copyright (C) 2006-2009  Florian Pose, Ingenieurgemeinschaft IgH
     6  *
     6  *
     7  *  This file is part of the IgH EtherCAT Master.
     7  *  This file is part of the IgH EtherCAT Master.
     8  *
     8  *
    47 {
    47 {
    48     stringstream str;
    48     stringstream str;
    49 
    49 
    50     str << binaryBaseName << " " << getName()
    50     str << binaryBaseName << " " << getName()
    51         << " [OPTIONS] <INDEX> <SUBINDEX> <VALUE>" << endl
    51         << " [OPTIONS] <INDEX> <SUBINDEX> <VALUE>" << endl
       
    52         << " [OPTIONS] <INDEX> <VALUE>" << endl
    52         << endl
    53         << endl
    53         << getBriefDescription() << endl
    54         << getBriefDescription() << endl
    54         << endl
    55         << endl
    55         << "This command requires a single slave to be selected." << endl
    56         << "This command requires a single slave to be selected." << endl
    56         << endl
    57         << endl
    57         << "The data type of the SDO entry is taken from the SDO" << endl
    58         << "The data type of the SDO entry is taken from the SDO" << endl
    58         << "dictionary by default. It can be overridden with the" << endl
    59         << "dictionary by default. It can be overridden with the" << endl
    59         << "--type option. If the slave does not support the SDO" << endl
    60         << "--type option. If the slave does not support the SDO" << endl
    60         << "information service or the SDO is not in the dictionary," << endl
    61         << "information service or the SDO is not in the dictionary," << endl
    61         << "the --type option is mandatory." << endl
    62         << "the --type option is mandatory." << endl
       
    63         << endl
       
    64         << "The second call (without <SUBINDEX>) uses the complete" << endl
       
    65         << "access method." << endl
    62         << endl
    66         << endl
    63         << typeInfo()
    67         << typeInfo()
    64         << endl
    68         << endl
    65         << "Arguments:" << endl
    69         << "Arguments:" << endl
    66         << "  INDEX    is the SDO index and must be an unsigned" << endl
    70         << "  INDEX    is the SDO index and must be an unsigned" << endl
    67         << "           16 bit number." << endl
    71         << "           16 bit number." << endl
    68         << "  SUBINDEX is the SDO entry subindex and must be an" << endl
    72         << "  SUBINDEX is the SDO entry subindex and must be an" << endl
    69         << "           unsigned 8 bit number." << endl
    73         << "           unsigned 8 bit number." << endl
    70         << "  VALUE    is the value to download and must correspond" << endl
    74         << "  VALUE    is the value to download and must correspond" << endl
    71         << "           to the SDO entry datatype (see above)." << endl
    75         << "           to the SDO entry datatype (see above). Use" << endl
       
    76         << "           '-' to read from standard input." << endl
    72         << endl
    77         << endl
    73         << "Command-specific options:" << endl
    78         << "Command-specific options:" << endl
    74         << "  --alias    -a <alias>" << endl
    79         << "  --alias    -a <alias>" << endl
    75         << "  --position -p <pos>    Slave selection. See the help of" << endl
    80         << "  --position -p <pos>    Slave selection. See the help of" << endl
    76         << "                         the 'slaves' command." << endl
    81         << "                         the 'slaves' command." << endl
    83 
    88 
    84 /****************************************************************************/
    89 /****************************************************************************/
    85 
    90 
    86 void CommandDownload::execute(const StringVector &args)
    91 void CommandDownload::execute(const StringVector &args)
    87 {
    92 {
    88     stringstream strIndex, strSubIndex, err;
    93     stringstream strIndex, err;
    89     ec_ioctl_slave_sdo_download_t data;
    94     ec_ioctl_slave_sdo_download_t data;
    90     unsigned int number;
    95     unsigned int valueIndex;
    91     const DataType *dataType = NULL;
    96     const DataType *dataType = NULL;
    92     SlaveList slaves;
    97     SlaveList slaves;
    93 
    98 
    94     if (args.size() != 3) {
    99     if (args.size() != 2 && args.size() != 3) {
    95         err << "'" << getName() << "' takes 3 arguments!";
   100         err << "'" << getName() << "' takes 2 or 3 arguments!";
    96         throwInvalidUsageException(err);
   101         throwInvalidUsageException(err);
    97     }
   102     }
       
   103     data.complete_access = args.size() == 2;
       
   104     valueIndex = data.complete_access ? 1 : 2;
    98 
   105 
    99     strIndex << args[0];
   106     strIndex << args[0];
   100     strIndex
   107     strIndex
   101         >> resetiosflags(ios::basefield) // guess base from prefix
   108         >> resetiosflags(ios::basefield) // guess base from prefix
   102         >> data.sdo_index;
   109         >> data.sdo_index;
   103     if (strIndex.fail()) {
   110     if (strIndex.fail()) {
   104         err << "Invalid SDO index '" << args[0] << "'!";
   111         err << "Invalid SDO index '" << args[0] << "'!";
   105         throwInvalidUsageException(err);
   112         throwInvalidUsageException(err);
   106     }
   113     }
   107 
   114 
   108     strSubIndex << args[1];
   115     if (data.complete_access) {
   109     strSubIndex
   116         data.sdo_entry_subindex = 0;
   110         >> resetiosflags(ios::basefield) // guess base from prefix
   117     } else {
   111         >> number;
   118         stringstream strSubIndex;
   112     if (strSubIndex.fail() || number > 0xff) {
   119         unsigned int number;
   113         err << "Invalid SDO subindex '" << args[1] << "'!";
   120 
   114         throwInvalidUsageException(err);
   121         strSubIndex << args[1];
   115     }
   122         strSubIndex
   116     data.sdo_entry_subindex = number;
   123             >> resetiosflags(ios::basefield) // guess base from prefix
       
   124             >> number;
       
   125         if (strSubIndex.fail() || number > 0xff) {
       
   126             err << "Invalid SDO subindex '" << args[1] << "'!";
       
   127             throwInvalidUsageException(err);
       
   128         }
       
   129         data.sdo_entry_subindex = number;
       
   130     }
   117 
   131 
   118     MasterDevice m(getSingleMasterIndex());
   132     MasterDevice m(getSingleMasterIndex());
   119     m.open(MasterDevice::ReadWrite);
   133     m.open(MasterDevice::ReadWrite);
   120     slaves = selectedSlaves(m);
   134     slaves = selectedSlaves(m);
   121     if (slaves.size() != 1) {
   135     if (slaves.size() != 1) {
   145                 << " Please specify --type.";
   159                 << " Please specify --type.";
   146             throwCommandException(err);
   160             throwCommandException(err);
   147         }
   161         }
   148     }
   162     }
   149 
   163 
   150     if (dataType->byteSize) {
   164     if (args[valueIndex] == "-") {
   151         data.data_size = dataType->byteSize;
   165         ostringstream tmp;
       
   166 
       
   167         tmp << cin.rdbuf();
       
   168         string const &contents = tmp.str();
       
   169 
       
   170         if (!contents.size()) {
       
   171             err << "Invalid data size " << contents.size() << "! "
       
   172                 << "Must be non-zero.";
       
   173             throwCommandException(err);
       
   174         }
       
   175         data.data_size = contents.size();
       
   176         data.data = new uint8_t[data.data_size + 1];
       
   177 
       
   178         try {
       
   179             data.data_size = interpretAsType(
       
   180                     dataType, contents, data.data, data.data_size);
       
   181         } catch (SizeException &e) {
       
   182             delete [] data.data;
       
   183             throwCommandException(e.what());
       
   184         } catch (ios::failure &e) {
       
   185             delete [] data.data;
       
   186             err << "Invalid value argument '" << args[2]
       
   187                 << "' for type '" << dataType->name << "'!";
       
   188             throwInvalidUsageException(err);
       
   189         }
       
   190 
   152     } else {
   191     } else {
   153         data.data_size = DefaultBufferSize;
   192         if (dataType->byteSize) {
   154     }
   193             data.data_size = dataType->byteSize;
   155 
   194         } else {
   156     data.data = new uint8_t[data.data_size + 1];
   195             data.data_size = DefaultBufferSize;
       
   196         }
       
   197 
       
   198         data.data = new uint8_t[data.data_size + 1];
       
   199 
       
   200         try {
       
   201             data.data_size = interpretAsType(
       
   202                     dataType, args[valueIndex], data.data, data.data_size);
       
   203         } catch (SizeException &e) {
       
   204             delete [] data.data;
       
   205             throwCommandException(e.what());
       
   206         } catch (ios::failure &e) {
       
   207             delete [] data.data;
       
   208             err << "Invalid value argument '" << args[2]
       
   209                 << "' for type '" << dataType->name << "'!";
       
   210             throwInvalidUsageException(err);
       
   211         }
       
   212     }
   157 
   213 
   158     try {
   214     try {
   159         data.data_size = interpretAsType(
   215         data.data_size = interpretAsType(
   160                 dataType, args[2], data.data, data.data_size);
   216                 dataType, args[valueIndex], data.data, data.data_size);
   161     } catch (SizeException &e) {
   217     } catch (SizeException &e) {
   162         delete [] data.data;
   218         delete [] data.data;
   163         throwCommandException(e.what());
   219         throwCommandException(e.what());
   164     } catch (ios::failure &e) {
   220     } catch (ios::failure &e) {
   165         delete [] data.data;
   221         delete [] data.data;