mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-02-06 03:41:52 +08:00
reg_write with data types.
This commit is contained in:
70
tool/CommandReg.cpp
Normal file
70
tool/CommandReg.cpp
Normal file
@@ -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},
|
||||
{}
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
54
tool/CommandReg.h
Normal file
54
tool/CommandReg.h
Normal file
@@ -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
|
||||
@@ -36,7 +36,7 @@ using namespace std;
|
||||
/*****************************************************************************/
|
||||
|
||||
CommandRegRead::CommandRegRead():
|
||||
Command("reg_read", "Output a slave's register contents.")
|
||||
CommandReg("reg_read", "Output a slave's register contents.")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ string CommandRegRead::helpString() const
|
||||
<< 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 <alias>" << endl
|
||||
@@ -159,13 +159,13 @@ void CommandRegRead::execute(MasterDevice &m, const StringVector &args)
|
||||
}
|
||||
|
||||
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 @@ void CommandRegRead::execute(MasterDevice &m, const StringVector &args)
|
||||
} 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 @@ void CommandRegRead::execute(MasterDevice &m, const StringVector &args)
|
||||
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},
|
||||
{}
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -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 &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -38,7 +38,7 @@ using namespace std;
|
||||
/*****************************************************************************/
|
||||
|
||||
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 @@ string CommandRegWrite::helpString() const
|
||||
{
|
||||
stringstream str;
|
||||
|
||||
str << getName() << " [OPTIONS] <OFFSET> <FILENAME>" << endl
|
||||
str << getName() << " [OPTIONS] <OFFSET> <DATA>" << 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 <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();
|
||||
|
||||
@@ -92,17 +101,85 @@ void CommandRegWrite::execute(MasterDevice &m, const StringVector &args)
|
||||
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!";
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
#ifndef __COMMANDREGWRITE_H__
|
||||
#define __COMMANDREGWRITE_H__
|
||||
|
||||
#include "Command.h"
|
||||
#include "CommandReg.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
class CommandRegWrite:
|
||||
public Command
|
||||
public CommandReg
|
||||
{
|
||||
public:
|
||||
CommandRegWrite();
|
||||
|
||||
@@ -45,6 +45,7 @@ ethercat_SOURCES = \
|
||||
CommandFoeWrite.cpp \
|
||||
CommandMaster.cpp \
|
||||
CommandPdos.cpp \
|
||||
CommandReg.cpp \
|
||||
CommandRegRead.cpp \
|
||||
CommandRegWrite.cpp \
|
||||
CommandSdos.cpp \
|
||||
@@ -73,6 +74,7 @@ noinst_HEADERS = \
|
||||
CommandFoeWrite.h \
|
||||
CommandMaster.h \
|
||||
CommandPdos.h \
|
||||
CommandReg.h \
|
||||
CommandRegRead.h \
|
||||
CommandRegWrite.h \
|
||||
CommandSdos.h \
|
||||
|
||||
Reference in New Issue
Block a user