Implemented SoE IDN parser for strings like 'P-0-0150'; moved data type
authorFlorian Pose <fp@igh-essen.com>
Thu, 11 Mar 2010 14:29:43 +0100
changeset 1868 489ea0becd74
parent 1867 fec951a0a654
child 1869 14f634f5b613
Implemented SoE IDN parser for strings like 'P-0-0150'; moved data type
information string to DataTypeHandler.
TODO
tool/CommandDownload.cpp
tool/CommandRegRead.cpp
tool/CommandRegWrite.cpp
tool/CommandSoeRead.cpp
tool/CommandSoeRead.h
tool/CommandSoeWrite.cpp
tool/CommandSoeWrite.h
tool/CommandUpload.cpp
tool/DataTypeHandler.cpp
tool/DataTypeHandler.h
tool/Makefile.am
tool/SoeCommand.cpp
tool/SoeCommand.h
--- 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:
--- 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
--- 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 <alias>" << endl
--- 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 <alias>" << endl
--- 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] <INDEX> <SUBINDEX>" << endl
+    str << getName() << " [OPTIONS] <IDN>" << 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 <alias>" << endl
         << "  --position -p <pos>    Slave selection. See the help of" << endl
         << "                         the 'slaves' command." << endl
+        << "  --type     -t <type>   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);
     }
 
--- 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();
--- 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] <INDEX> <SUBINDEX> <VALUE>" << endl
+    str << getName() << " [OPTIONS] <IDN> <VALUE>" << 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 <alias>" << 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);
     }
 
--- 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();
--- 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
--- 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;
--- 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 &,
--- 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
--- /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 <iomanip>
+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;
+}
+
+/****************************************************************************/
--- /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