tool/CommandRegWrite.cpp
branchstable-1.5
changeset 2443 2c3ccdde3919
parent 2421 bc2d4bf9cbe5
child 2529 c7e1f2616a9d
equal deleted inserted replaced
2442:86ebf18a029f 2443:2c3ccdde3919
     1 /*****************************************************************************
     1 /*****************************************************************************
     2  *
     2  *
     3  *  $Id$
     3  *  $Id$
     4  *
     4  *
     5  *  Copyright (C) 2006-2009  Florian Pose, Ingenieurgemeinschaft IgH
     5  *  Copyright (C) 2006-2012  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  *
     9  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
     9  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
    10  *  modify it under the terms of the GNU General Public License version 2, as
    10  *  modify it under the terms of the GNU General Public License version 2, as
    55         << getBriefDescription() << endl
    55         << getBriefDescription() << endl
    56         << endl
    56         << endl
    57         << "This command requires a single slave to be selected." << endl
    57         << "This command requires a single slave to be selected." << endl
    58         << endl
    58         << endl
    59         << "Arguments:" << endl
    59         << "Arguments:" << endl
    60         << "  OFFSET  is the register address to write to." << endl
    60         << "  ADDRESS is the register address to write to." << endl
    61         << "  DATA    depends on whether a datatype was specified" << endl
    61         << "  DATA    depends on whether a datatype was specified" << endl
    62         << "          with the --type option: If not, DATA must be" << endl
    62         << "          with the --type option: If not, DATA must be" << endl
    63         << "          either a path to a file with data to write," << endl
    63         << "          either a path to a file with data to write," << endl
    64         << "          or '-', which means, that data are read from" << endl
    64         << "          or '-', which means, that data are read from" << endl
    65         << "          stdin. If a datatype was specified, VALUE is" << endl
    65         << "          stdin. If a datatype was specified, VALUE is" << endl
    81 /****************************************************************************/
    81 /****************************************************************************/
    82 
    82 
    83 void CommandRegWrite::execute(const StringVector &args)
    83 void CommandRegWrite::execute(const StringVector &args)
    84 {
    84 {
    85     stringstream strOffset, err;
    85     stringstream strOffset, err;
    86     ec_ioctl_slave_reg_t data;
    86     ec_ioctl_slave_reg_t io;
    87     ifstream file;
    87     ifstream file;
    88     SlaveList slaves;
    88     SlaveList slaves;
    89 
    89 
    90     if (args.size() != 2) {
    90     if (args.size() != 2) {
    91         err << "'" << getName() << "' takes exactly two arguments!";
    91         err << "'" << getName() << "' takes exactly two arguments!";
    93     }
    93     }
    94 
    94 
    95     strOffset << args[0];
    95     strOffset << args[0];
    96     strOffset
    96     strOffset
    97         >> resetiosflags(ios::basefield) // guess base from prefix
    97         >> resetiosflags(ios::basefield) // guess base from prefix
    98         >> data.offset;
    98         >> io.address;
    99     if (strOffset.fail()) {
    99     if (strOffset.fail()) {
   100         err << "Invalid offset '" << args[0] << "'!";
   100         err << "Invalid address '" << args[0] << "'!";
   101         throwInvalidUsageException(err);
   101         throwInvalidUsageException(err);
   102     }
   102     }
   103 
   103 
   104     if (getDataType().empty()) {
   104     if (getDataType().empty()) {
   105         if (args[1] == "-") {
   105         if (args[1] == "-") {
   106             loadRegData(&data, cin);
   106             loadRegData(&io, cin);
   107         } else {
   107         } else {
   108             file.open(args[1].c_str(), ifstream::in | ifstream::binary);
   108             file.open(args[1].c_str(), ifstream::in | ifstream::binary);
   109             if (file.fail()) {
   109             if (file.fail()) {
   110                 err << "Failed to open '" << args[1] << "'!";
   110                 err << "Failed to open '" << args[1] << "'!";
   111                 throwCommandException(err);
   111                 throwCommandException(err);
   112             }
   112             }
   113             loadRegData(&data, file);
   113             loadRegData(&io, file);
   114             file.close();
   114             file.close();
   115         }
   115         }
   116     } else {
   116     } else {
   117         stringstream strValue;
   117         stringstream strValue;
   118         const DataType *dataType = findDataType(getDataType());
   118         const DataType *dataType = findDataType(getDataType());
   121             err << "Invalid data type '" << getDataType() << "'!";
   121             err << "Invalid data type '" << getDataType() << "'!";
   122             throwInvalidUsageException(err);
   122             throwInvalidUsageException(err);
   123         }
   123         }
   124 
   124 
   125         if (dataType->byteSize) {
   125         if (dataType->byteSize) {
   126             data.length = dataType->byteSize;
   126             io.size = dataType->byteSize;
   127         } else {
   127         } else {
   128             data.length = 1024; // FIXME
   128             io.size = 1024; // FIXME
   129         }
   129         }
   130 
   130 
   131         data.data = new uint8_t[data.length];
   131         io.data = new uint8_t[io.size];
   132 
   132 
   133         try {
   133         try {
   134             data.length = interpretAsType(
   134             io.size = interpretAsType(
   135                     dataType, args[1], data.data, data.length);
   135                     dataType, args[1], io.data, io.size);
   136         } catch (SizeException &e) {
   136         } catch (SizeException &e) {
   137             delete [] data.data;
   137             delete [] io.data;
   138             throwCommandException(e.what());
   138             throwCommandException(e.what());
   139         } catch (ios::failure &e) {
   139         } catch (ios::failure &e) {
   140             delete [] data.data;
   140             delete [] io.data;
   141             err << "Invalid value argument '" << args[1]
   141             err << "Invalid value argument '" << args[1]
   142                 << "' for type '" << dataType->name << "'!";
   142                 << "' for type '" << dataType->name << "'!";
   143             throwInvalidUsageException(err);
   143             throwInvalidUsageException(err);
   144         }
   144         }
   145     }
   145     }
   146 
   146 
   147     if ((uint32_t) data.offset + data.length > 0xffff) {
   147     if ((uint32_t) io.address + io.size > 0xffff) {
   148         err << "Offset and length exceeding 64k!";
   148         err << "Address and size exceeding 64k!";
   149         delete [] data.data;
   149         delete [] io.data;
   150         throwInvalidUsageException(err);
   150         throwInvalidUsageException(err);
   151     }
   151     }
   152 
   152 
   153     MasterDevice m(getSingleMasterIndex());
   153     MasterDevice m(getSingleMasterIndex());
   154     try {
   154     try {
   155         m.open(MasterDevice::ReadWrite);
   155         m.open(MasterDevice::ReadWrite);
   156     } catch (MasterDeviceException &e) {
   156     } catch (MasterDeviceException &e) {
   157         delete [] data.data;
   157         delete [] io.data;
   158         throw e;
   158         throw e;
   159     }
   159     }
   160 
   160 
   161     slaves = selectedSlaves(m);
   161     slaves = selectedSlaves(m);
   162     if (slaves.size() != 1) {
   162     if (slaves.size() != 1) {
   163         delete [] data.data;
   163         delete [] io.data;
   164         throwSingleSlaveRequired(slaves.size());
   164         throwSingleSlaveRequired(slaves.size());
   165     }
   165     }
   166     data.slave_position = slaves.front().position;
   166     io.slave_position = slaves.front().position;
   167 
   167 
   168     // send data to master
   168     // send data to master
   169     try {
   169     try {
   170         m.writeReg(&data);
   170         m.writeReg(&io);
   171     } catch (MasterDeviceException &e) {
   171     } catch (MasterDeviceException &e) {
   172         delete [] data.data;
   172         delete [] io.data;
   173         throw e;
   173         throw e;
   174     }
   174     }
   175 
   175 
   176     if (getVerbosity() == Verbose) {
   176     if (getVerbosity() == Verbose) {
   177         cerr << "Register writing finished." << endl;
   177         cerr << "Register writing finished." << endl;
   178     }
   178     }
   179 
   179 
   180     delete [] data.data;
   180     delete [] io.data;
   181 }
   181 }
   182 
   182 
   183 /*****************************************************************************/
   183 /*****************************************************************************/
   184 
   184 
   185 void CommandRegWrite::loadRegData(
   185 void CommandRegWrite::loadRegData(
   186         ec_ioctl_slave_reg_t *data,
   186         ec_ioctl_slave_reg_t *io,
   187         const istream &in
   187         const istream &in
   188         )
   188         )
   189 {
   189 {
   190     stringstream err;
   190     stringstream err;
   191     ostringstream tmp;
   191     ostringstream tmp;
   199 
   199 
   200     if (contents.size() > 0xffff) {
   200     if (contents.size() > 0xffff) {
   201         err << "Invalid data size " << contents.size() << "!";
   201         err << "Invalid data size " << contents.size() << "!";
   202         throwInvalidUsageException(err);
   202         throwInvalidUsageException(err);
   203     }
   203     }
   204     data->length = contents.size();
   204     io->size = contents.size();
   205 
   205 
   206     // allocate buffer and read file into buffer
   206     // allocate buffer and read file into buffer
   207     data->data = new uint8_t[data->length];
   207     io->data = new uint8_t[io->size];
   208     contents.copy((char *) data->data, contents.size());
   208     contents.copy((char *) io->data, contents.size());
   209 }
   209 }
   210 
   210 
   211 /*****************************************************************************/
   211 /*****************************************************************************/