# HG changeset patch # User Florian Pose # Date 1268314183 -3600 # Node ID 489ea0becd7487094be969b473be756851d3ced7 # Parent fec951a0a6543bc6cb505694c599965a943fbcea Implemented SoE IDN parser for strings like 'P-0-0150'; moved data type information string to DataTypeHandler. diff -r fec951a0a654 -r 489ea0becd74 TODO --- a/TODO Tue Mar 09 16:23:30 2010 +0100 +++ b/TODO Thu Mar 11 14:29:43 2010 +0100 @@ -40,8 +40,6 @@ - Implement indent in 'ethercat ma' - Implement 0xXXXX:YY format for specifying SDOs. - Lookup codes for 64bit data types. - - Move data type usage string into DataTypeHandler. - - Implement interpretation of SoE '[SP]-x-yyy' strings. - Implement reading from stream for soe_write. Future issues: diff -r fec951a0a654 -r 489ea0becd74 tool/CommandDownload.cpp --- a/tool/CommandDownload.cpp Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandDownload.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -59,9 +59,7 @@ << "information service or the SDO is not in the dictionary," << endl << "the --type option is mandatory." << endl << endl - << "These are the valid SDO entry data types:" << endl - << " int8, int16, int32, uint8, uint16, uint32, string," << endl - << " octet_string." << endl + << typeInfo() << endl << "Arguments:" << endl << " INDEX is the SDO index and must be an unsigned" << endl diff -r fec951a0a654 -r 489ea0becd74 tool/CommandRegRead.cpp --- a/tool/CommandRegRead.cpp Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandRegRead.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -62,9 +62,7 @@ << " can be omitted), if a selected data type" << endl << " implies a length." << endl << endl - << "These are the valid data types:" << endl - << " int8, int16, int32, int64, uint8, uint16, uint32," << endl - << " uint64, string, raw." << endl + << typeInfo() << endl << "Command-specific options:" << endl << " --alias -a " << endl diff -r fec951a0a654 -r 489ea0becd74 tool/CommandRegWrite.cpp --- a/tool/CommandRegWrite.cpp Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandRegWrite.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -64,9 +64,7 @@ << " 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 + << typeInfo() << endl << "Command-specific options:" << endl << " --alias -a " << endl diff -r fec951a0a654 -r 489ea0becd74 tool/CommandSoeRead.cpp --- a/tool/CommandSoeRead.cpp Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandSoeRead.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -37,7 +37,7 @@ /*****************************************************************************/ CommandSoeRead::CommandSoeRead(): - Command("soe_read", "Read an SoE IDN from a slave.") + SoeCommand("soe_read", "Read an SoE IDN from a slave.") { } @@ -47,20 +47,27 @@ { 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 - << " IDN is the IDN and must be an unsigned" << endl - << " 16 bit number." << endl + << " IDN is the IDN and must be either an unsigned" << endl + << " 16 bit number acc. to IEC 61800-7-204:" << endl + << " Bit 15: (0) Standard data, (1) Product data" << endl + << " Bit 14 - 12: Parameter set (0 - 7)" << endl + << " Bit 11 - 0: Data block number" << endl + << " or a string like 'P-0-150'." << endl + << endl + << typeInfo() << 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(); @@ -72,7 +79,7 @@ void CommandSoeRead::execute(const StringVector &args) { SlaveList slaves; - stringstream err, strIdn; + stringstream err; const DataType *dataType = NULL; ec_ioctl_slave_soe_read_t ioctl; @@ -81,12 +88,10 @@ throwInvalidUsageException(err); } - strIdn << args[0]; - strIdn - >> resetiosflags(ios::basefield) // guess base from prefix - >> ioctl.idn; - if (strIdn.fail()) { - err << "Invalid IDN '" << args[0] << "'!"; + try { + ioctl.idn = parseIdn(args[0]); + } catch (runtime_error &e) { + err << "Invalid IDN '" << args[0] << "': " << e.what(); throwInvalidUsageException(err); } diff -r fec951a0a654 -r 489ea0becd74 tool/CommandSoeRead.h --- a/tool/CommandSoeRead.h Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandSoeRead.h Thu Mar 11 14:29:43 2010 +0100 @@ -30,14 +30,12 @@ #ifndef __COMMANDSOEREAD_H__ #define __COMMANDSOEREAD_H__ -#include "Command.h" -#include "DataTypeHandler.h" +#include "SoeCommand.h" /****************************************************************************/ class CommandSoeRead: - public Command, - public DataTypeHandler + public SoeCommand { public: CommandSoeRead(); diff -r fec951a0a654 -r 489ea0becd74 tool/CommandSoeWrite.cpp --- a/tool/CommandSoeWrite.cpp Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandSoeWrite.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -37,7 +37,7 @@ /*****************************************************************************/ CommandSoeWrite::CommandSoeWrite(): - Command("soe_write", "Write an SoE IDN to a slave.") + SoeCommand("soe_write", "Write an SoE IDN to a slave.") { } @@ -47,17 +47,23 @@ { 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 - << " IDN is the IDN and must be an unsigned" << endl - << " 16 bit number." << endl + << " IDN is the IDN and must be either an unsigned" << endl + << " 16 bit number acc. to IEC 61800-7-204:" << endl + << " Bit 15: (0) Standard data, (1) Product data" << endl + << " Bit 14 - 12: Parameter set (0 - 7)" << endl + << " Bit 11 - 0: Data block number" << endl + << " or a string like 'P-0-150'." << endl << " VALUE is the value to write and is interpreted" << endl << " as the given datatype (see above)." << endl + << endl + << typeInfo() << endl << "Command-specific options:" << endl << " --alias -a " << endl @@ -85,12 +91,10 @@ throwInvalidUsageException(err); } - strIdn << args[0]; - strIdn - >> resetiosflags(ios::basefield) // guess base from prefix - >> ioctl.idn; - if (strIdn.fail()) { - err << "Invalid IDN '" << args[0] << "'!"; + try { + ioctl.idn = parseIdn(args[0]); + } catch (runtime_error &e) { + err << "Invalid IDN '" << args[0] << "': " << e.what(); throwInvalidUsageException(err); } diff -r fec951a0a654 -r 489ea0becd74 tool/CommandSoeWrite.h --- a/tool/CommandSoeWrite.h Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandSoeWrite.h Thu Mar 11 14:29:43 2010 +0100 @@ -30,14 +30,12 @@ #ifndef __COMMANDSOEWRITE_H__ #define __COMMANDSOEWRITE_H__ -#include "Command.h" -#include "DataTypeHandler.h" +#include "SoeCommand.h" /****************************************************************************/ class CommandSoeWrite: - public Command, - public DataTypeHandler + public SoeCommand { public: CommandSoeWrite(); diff -r fec951a0a654 -r 489ea0becd74 tool/CommandUpload.cpp --- a/tool/CommandUpload.cpp Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/CommandUpload.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -59,9 +59,7 @@ << "information service or the SDO is not in the dictionary," << endl << "the --type option is mandatory." << endl << endl - << "These are the valid SDO entry data types:" << endl - << " int8, int16, int32, uint8, uint16, uint32, string," << endl - << " octet_string." << endl + << typeInfo() << endl << "Arguments:" << endl << " INDEX is the SDO index and must be an unsigned" << endl diff -r fec951a0a654 -r 489ea0becd74 tool/DataTypeHandler.cpp --- a/tool/DataTypeHandler.cpp Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/DataTypeHandler.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -64,6 +64,20 @@ /****************************************************************************/ +string DataTypeHandler::typeInfo() +{ + stringstream s; + + s + << "These are valid data types to use with" << endl + << "the --type option:" << endl + << " int8, int16, int32, uint8, uint16, uint32, string," << endl + << " octet_string." << endl; + return s.str(); +} + +/****************************************************************************/ + const DataTypeHandler::DataType *DataTypeHandler::findDataType(uint16_t code) { const DataType *d; diff -r fec951a0a654 -r 489ea0becd74 tool/DataTypeHandler.h --- a/tool/DataTypeHandler.h Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/DataTypeHandler.h Thu Mar 11 14:29:43 2010 +0100 @@ -51,6 +51,8 @@ size_t byteSize; }; + static std::string typeInfo(); + static const DataType *findDataType(const std::string &); static const DataType *findDataType(uint16_t); static size_t interpretAsType(const DataType *, const std::string &, diff -r fec951a0a654 -r 489ea0becd74 tool/Makefile.am --- a/tool/Makefile.am Tue Mar 09 16:23:30 2010 +0100 +++ b/tool/Makefile.am Thu Mar 11 14:29:43 2010 +0100 @@ -66,6 +66,7 @@ MasterDevice.cpp \ NumberListParser.cpp \ SdoCommand.cpp \ + SoeCommand.cpp \ main.cpp \ sii_crc.cpp @@ -106,6 +107,7 @@ MasterDevice.h \ NumberListParser.h \ SdoCommand.h \ + SoeCommand.h \ sii_crc.h if ENABLE_EOE diff -r fec951a0a654 -r 489ea0becd74 tool/SoeCommand.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/SoeCommand.cpp Thu Mar 11 14:29:43 2010 +0100 @@ -0,0 +1,108 @@ +/***************************************************************************** + * + * $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 +using namespace std; + +#include "SoeCommand.h" + +/*****************************************************************************/ + +SoeCommand::SoeCommand(const string &name, const string &briefDesc): + Command(name, briefDesc) +{ +} + +/*****************************************************************************/ + +uint16_t SoeCommand::parseIdn(const string &str) +{ + uint16_t idn = 0x0000; + stringstream s, err; + + if (!str.length()) { + err << "Zero-size string not allowed!"; + throw runtime_error(err.str()); + } + + if (str[0] == 'S' || str[0] == 'P') { + unsigned int num; + unsigned char c; + + s << str; + + s >> c; + if (c == 'P') { + idn |= 0x8000; + } + + s >> c; + if (s.fail() || c != '-') { + err << "'-' expected!"; + throw runtime_error(err.str()); + } + + s >> num; + if (s.fail() || num > 7) { + err << "Invalid parameter set number!"; + throw runtime_error(err.str()); + } + idn |= num << 12; + + s >> c; + if (s.fail() || c != '-') { + err << "'-' expected!"; + throw runtime_error(err.str()); + } + + s >> num; + if (s.fail() || num > 4095) { + err << "Invalid data block number!"; + throw runtime_error(err.str()); + } + idn |= num; + + s.peek(); + if (!s.eof()) { + err << "Additional input!"; + throw runtime_error(err.str()); + } + } else { + s << str; + s >> resetiosflags(ios::basefield) >> idn; + if (s.fail()) { + err << "Invalid number!"; + throw runtime_error(err.str()); + } + } + + return idn; +} + +/****************************************************************************/ diff -r fec951a0a654 -r 489ea0becd74 tool/SoeCommand.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tool/SoeCommand.h Thu Mar 11 14:29:43 2010 +0100 @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * $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 __SOECOMMAND_H__ +#define __SOECOMMAND_H__ + +#include "Command.h" +#include "DataTypeHandler.h" + +/****************************************************************************/ + +class SoeCommand: + public Command, + public DataTypeHandler +{ + public: + SoeCommand(const string &, const string &); + + protected: + static uint16_t parseIdn(const string &); +}; + +/****************************************************************************/ + +#endif