# HG changeset patch # User Florian Pose # Date 1239199834 0 # Node ID 5b392b22a2dade8fd3df0462792ea35803e2b5cd # Parent 3c886ec376f505d258d29710e65ec06d9c147ed7 reg_write with data types. diff -r 3c886ec376f5 -r 5b392b22a2da tool/CommandReg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/CommandReg.cpp Wed Apr 08 14:10:34 2009 +0000 @@ -0,0 +1,70 @@ +/***************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * The IgH EtherCAT Master is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * --- + * + * The license mentioned above concerns the source code only. Using the + * EtherCAT technology and brand is only permitted in compliance with the + * industrial property and similar rights of Beckhoff Automation GmbH. + * + ****************************************************************************/ + +#include "CommandReg.h" + +/*****************************************************************************/ + +CommandReg::CommandReg(const string &name, const string &briefDesc): + Command(name, briefDesc) +{ +} + +/****************************************************************************/ + +const CommandReg::DataType *CommandReg::findDataType( + const string &str + ) +{ + const DataType *d; + + for (d = dataTypes; d->name; d++) + if (str == d->name) + return d; + + return NULL; +} + +/****************************************************************************/ + +const CommandReg::DataType CommandReg::dataTypes[] = { + {"int8", 1}, + {"int16", 2}, + {"int32", 4}, + {"int64", 8}, + {"uint8", 1}, + {"uint16", 2}, + {"uint32", 4}, + {"uint64", 8}, + {"string", 0}, + {"raw", 0}, + {} +}; + +/*****************************************************************************/ diff -r 3c886ec376f5 -r 5b392b22a2da tool/CommandReg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/CommandReg.h Wed Apr 08 14:10:34 2009 +0000 @@ -0,0 +1,54 @@ +/***************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * The IgH EtherCAT Master is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * --- + * + * The license mentioned above concerns the source code only. Using the + * EtherCAT technology and brand is only permitted in compliance with the + * industrial property and similar rights of Beckhoff Automation GmbH. + * + ****************************************************************************/ + +#ifndef __COMMANDREG_H__ +#define __COMMANDREG_H__ + +#include "Command.h" + +/****************************************************************************/ + +class CommandReg: + public Command +{ + public: + CommandReg(const string &, const string &); + + protected: + struct DataType { + const char *name; + unsigned int byteSize; + }; + static const DataType dataTypes[]; + static const DataType *findDataType(const string &); +}; + +/****************************************************************************/ + +#endif diff -r 3c886ec376f5 -r 5b392b22a2da tool/CommandRegRead.cpp --- a/tool/CommandRegRead.cpp Wed Apr 08 12:48:59 2009 +0000 +++ b/tool/CommandRegRead.cpp Wed Apr 08 14:10:34 2009 +0000 @@ -36,7 +36,7 @@ /*****************************************************************************/ CommandRegRead::CommandRegRead(): - Command("reg_read", "Output a slave's register contents.") + CommandReg("reg_read", "Output a slave's register contents.") { } @@ -63,7 +63,7 @@ << endl << "These are the valid data types:" << endl << " int8, int16, int32, int64, uint8, uint16, uint32," << endl - << " uint64, string, octet_string, raw." << endl + << " uint64, string, raw." << endl << endl << "Command-specific options:" << endl << " --alias -a " << endl @@ -159,13 +159,13 @@ } cout << setfill('0'); - if (!dataType || - dataType->name == "string" || - dataType->name == "octet_string") { + if (!dataType || dataType->name == "string") { uint16_t i; for (i = 0; i < data.length; i++) { cout << data.data[i]; } + if (dataType) + cout << endl; } else if (dataType->name == "int8") { int sval = *(int8_t *) data.data; cout << sval << " 0x" << hex << setw(2) << sval << endl; @@ -190,7 +190,7 @@ } else if (dataType->name == "uint64") { long long unsigned int uval = le32_to_cpup(data.data); cout << uval << " 0x" << hex << setw(8) << uval << endl; - } else { + } else { // raw uint8_t *d = data.data; unsigned int size = data.length; @@ -206,36 +206,4 @@ delete [] data.data; } -/****************************************************************************/ - -const CommandRegRead::DataType *CommandRegRead::findDataType( - const string &str - ) -{ - const DataType *d; - - for (d = dataTypes; d->name; d++) - if (str == d->name) - return d; - - return NULL; -} - -/****************************************************************************/ - -const CommandRegRead::DataType CommandRegRead::dataTypes[] = { - {"int8", 1}, - {"int16", 2}, - {"int32", 4}, - {"int64", 8}, - {"uint8", 1}, - {"uint16", 2}, - {"uint32", 4}, - {"uint64", 8}, - {"string", 0}, - {"octet_string", 0}, - {"raw", 0}, - {} -}; - /*****************************************************************************/ diff -r 3c886ec376f5 -r 5b392b22a2da tool/CommandRegRead.h --- a/tool/CommandRegRead.h Wed Apr 08 12:48:59 2009 +0000 +++ b/tool/CommandRegRead.h Wed Apr 08 14:10:34 2009 +0000 @@ -30,26 +30,18 @@ #ifndef __COMMANDREGREAD_H__ #define __COMMANDREGREAD_H__ -#include "Command.h" +#include "CommandReg.h" /****************************************************************************/ class CommandRegRead: - public Command + public CommandReg { public: CommandRegRead(); string helpString() const; void execute(MasterDevice &, const StringVector &); - - private: - struct DataType { - const char *name; - unsigned int byteSize; - }; - static const DataType dataTypes[]; - static const DataType *findDataType(const string &); }; /****************************************************************************/ diff -r 3c886ec376f5 -r 5b392b22a2da tool/CommandRegWrite.cpp --- a/tool/CommandRegWrite.cpp Wed Apr 08 12:48:59 2009 +0000 +++ b/tool/CommandRegWrite.cpp Wed Apr 08 14:10:34 2009 +0000 @@ -38,7 +38,7 @@ /*****************************************************************************/ CommandRegWrite::CommandRegWrite(): - Command("reg_write", "Write data to a slave's registers.") + CommandReg("reg_write", "Write data to a slave's registers.") { } @@ -48,21 +48,30 @@ { stringstream str; - str << getName() << " [OPTIONS] " << endl + str << getName() << " [OPTIONS] " << endl << endl << getBriefDescription() << endl << endl << "This command requires a single slave to be selected." << endl << endl << "Arguments:" << endl - << " OFFSET must be the register address." << endl - << " FILENAME must be a path to a file with data to write." << endl - << " If it is '-', data are read from stdin." << endl + << " OFFSET is the register address to write to." << endl + << " DATA depends on whether a datatype was specified" << endl + << " with the --type option: If not, DATA must be" << endl + << " either a path to a file with data to write," << endl + << " or '-', which means, that data are read from" << endl + << " stdin. If a datatype was specified, VALUE is" << endl + << " interpreted respective to the given type." << endl << endl + << "These are the valid data types:" << endl + << " int8, int16, int32, int64, uint8, uint16, uint32," << endl + << " uint64, string." << endl + << endl << "Command-specific options:" << endl << " --alias -a " << endl << " --position -p Slave selection. See the help of" << endl << " the 'slaves' command." << endl + << " --type -t Data type (see above)." << endl << endl << numericInfo(); @@ -92,17 +101,85 @@ throwInvalidUsageException(err); } - if (args[1] == "-") { - loadRegData(&data, cin); - } else { - file.open(args[1].c_str(), ifstream::in | ifstream::binary); - if (file.fail()) { - err << "Failed to open '" << args[0] << "'!"; - throwCommandException(err); + if (getDataType().empty()) { + if (args[1] == "-") { + loadRegData(&data, cin); + } else { + file.open(args[1].c_str(), ifstream::in | ifstream::binary); + if (file.fail()) { + err << "Failed to open '" << args[1] << "'!"; + throwCommandException(err); + } + loadRegData(&data, file); + file.close(); + } + } else { + stringstream strValue; + const DataType *dataType = findDataType(getDataType()); + + if (!dataType) { + err << "Invalid data type '" << getDataType() << "'!"; + throwInvalidUsageException(err); } - loadRegData(&data, file); - file.close(); - } + + if (dataType->byteSize) { + data.length = dataType->byteSize; + data.data = new uint8_t[data.length]; + } + + strValue << args[1]; + strValue >> resetiosflags(ios::basefield); // guess base from prefix + strValue.exceptions(ios::failbit); + + try { + if (dataType->name == "int8") { + int16_t val; // uint8_t is interpreted as char + strValue >> val; + if (val > 127 || val < -128) + throw ios::failure("Value out of range"); + *data.data = (int8_t) val; + } else if (dataType->name == "int16") { + int16_t val; + strValue >> val; + *(int16_t *) data.data = cpu_to_le16(val); + } else if (dataType->name == "int32") { + int32_t val; + strValue >> val; + *(int32_t *) data.data = cpu_to_le32(val); + } else if (dataType->name == "uint8") { + uint16_t val; // uint8_t is interpreted as char + strValue >> val; + if (val > 0xff) + throw ios::failure("Value out of range"); + *data.data = (uint8_t) val; + } else if (dataType->name == "uint16") { + uint16_t val; + strValue >> val; + *(uint16_t *) data.data = cpu_to_le16(val); + } else if (dataType->name == "uint32") { + uint32_t val; + strValue >> val; + *(uint32_t *) data.data = cpu_to_le32(val); + } else if (dataType->name == "string" || + dataType->name == "octet_string") { + data.length = strValue.str().size(); + if (!data.length) { + err << "Zero-size string now allowed!"; + throwCommandException(err); + } + data.data = new uint8_t[data.length]; + strValue >> (char *) data.data; + } else { + err << "Invalid data type " << dataType->name; + throwCommandException(err); + } + } catch (ios::failure &e) { + delete [] data.data; + err << "Invalid value argument '" << args[1] + << "' for type '" << dataType->name << "'!"; + throwInvalidUsageException(err); + } + } if ((uint32_t) data.offset + data.length > 0xffff) { err << "Offset and length exceeding 64k!"; diff -r 3c886ec376f5 -r 5b392b22a2da tool/CommandRegWrite.h --- a/tool/CommandRegWrite.h Wed Apr 08 12:48:59 2009 +0000 +++ b/tool/CommandRegWrite.h Wed Apr 08 14:10:34 2009 +0000 @@ -30,12 +30,12 @@ #ifndef __COMMANDREGWRITE_H__ #define __COMMANDREGWRITE_H__ -#include "Command.h" +#include "CommandReg.h" /****************************************************************************/ class CommandRegWrite: - public Command + public CommandReg { public: CommandRegWrite(); diff -r 3c886ec376f5 -r 5b392b22a2da tool/Makefile.am --- a/tool/Makefile.am Wed Apr 08 12:48:59 2009 +0000 +++ b/tool/Makefile.am Wed Apr 08 14:10:34 2009 +0000 @@ -45,6 +45,7 @@ CommandFoeWrite.cpp \ CommandMaster.cpp \ CommandPdos.cpp \ + CommandReg.cpp \ CommandRegRead.cpp \ CommandRegWrite.cpp \ CommandSdos.cpp \ @@ -73,6 +74,7 @@ CommandFoeWrite.h \ CommandMaster.h \ CommandPdos.h \ + CommandReg.h \ CommandRegRead.h \ CommandRegWrite.h \ CommandSdos.h \