mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-09-21 09:33:47 +08:00
Implemented SoE write state machine and soe_write command.
This commit is contained in:
+12
-12
@@ -74,7 +74,7 @@ void CommandSoeRead::execute(const StringVector &args)
|
||||
SlaveList slaves;
|
||||
stringstream err, strIdn;
|
||||
const DataType *dataType = NULL;
|
||||
ec_ioctl_slave_soe_t data;
|
||||
ec_ioctl_slave_soe_read_t ioctl;
|
||||
|
||||
if (args.size() != 1) {
|
||||
err << "'" << getName() << "' takes one argument!";
|
||||
@@ -84,7 +84,7 @@ void CommandSoeRead::execute(const StringVector &args)
|
||||
strIdn << args[0];
|
||||
strIdn
|
||||
>> resetiosflags(ios::basefield) // guess base from prefix
|
||||
>> data.idn;
|
||||
>> ioctl.idn;
|
||||
if (strIdn.fail()) {
|
||||
err << "Invalid IDN '" << args[0] << "'!";
|
||||
throwInvalidUsageException(err);
|
||||
@@ -100,7 +100,7 @@ void CommandSoeRead::execute(const StringVector &args)
|
||||
if (slaves.size() != 1) {
|
||||
throwSingleSlaveRequired(slaves.size());
|
||||
}
|
||||
data.slave_position = slaves.front().position;
|
||||
ioctl.slave_position = slaves.front().position;
|
||||
|
||||
if (getDataType().empty()) {
|
||||
dataType = findDataType("raw"); // FIXME
|
||||
@@ -112,35 +112,35 @@ void CommandSoeRead::execute(const StringVector &args)
|
||||
}
|
||||
|
||||
if (dataType->byteSize) {
|
||||
data.mem_size = dataType->byteSize;
|
||||
ioctl.mem_size = dataType->byteSize;
|
||||
} else {
|
||||
data.mem_size = 1024;
|
||||
ioctl.mem_size = 1024;
|
||||
}
|
||||
|
||||
data.data = new uint8_t[data.mem_size + 1];
|
||||
ioctl.data = new uint8_t[ioctl.mem_size + 1];
|
||||
|
||||
try {
|
||||
m.readSoe(&data);
|
||||
m.readSoe(&ioctl);
|
||||
} catch (MasterDeviceSoeException &e) {
|
||||
delete [] data.data;
|
||||
delete [] ioctl.data;
|
||||
err << "SoE read command aborted with code 0x"
|
||||
<< setfill('0') << hex << setw(4) << e.errorCode;
|
||||
throwCommandException(err);
|
||||
} catch (MasterDeviceException &e) {
|
||||
delete [] data.data;
|
||||
delete [] ioctl.data;
|
||||
throw e;
|
||||
}
|
||||
|
||||
m.close();
|
||||
|
||||
try {
|
||||
outputData(cout, dataType, data.data, data.data_size);
|
||||
outputData(cout, dataType, ioctl.data, ioctl.data_size);
|
||||
} catch (SizeException &e) {
|
||||
delete [] data.data;
|
||||
delete [] ioctl.data;
|
||||
throwCommandException(e.what());
|
||||
}
|
||||
|
||||
delete [] data.data;
|
||||
delete [] ioctl.data;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $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 <iostream>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
#include "CommandSoeWrite.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
CommandSoeWrite::CommandSoeWrite():
|
||||
Command("soe_write", "Write an SoE IDN to a slave.")
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
string CommandSoeWrite::helpString() const
|
||||
{
|
||||
stringstream str;
|
||||
|
||||
str << getName() << " [OPTIONS] <INDEX> <SUBINDEX> <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
|
||||
<< " VALUE is the value to write and is interpreted" << endl
|
||||
<< " as the given datatype (see above)." << 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();
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandSoeWrite::execute(const StringVector &args)
|
||||
{
|
||||
stringstream strIdn, err;
|
||||
const DataType *dataType = NULL;
|
||||
ec_ioctl_slave_soe_write_t ioctl;
|
||||
SlaveList slaves;
|
||||
size_t memSize;
|
||||
|
||||
if (args.size() != 2) {
|
||||
err << "'" << getName() << "' takes 2 arguments!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
strIdn << args[0];
|
||||
strIdn
|
||||
>> resetiosflags(ios::basefield) // guess base from prefix
|
||||
>> ioctl.idn;
|
||||
if (strIdn.fail()) {
|
||||
err << "Invalid IDN '" << args[0] << "'!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::ReadWrite);
|
||||
slaves = selectedSlaves(m);
|
||||
if (slaves.size() != 1) {
|
||||
throwSingleSlaveRequired(slaves.size());
|
||||
}
|
||||
ioctl.slave_position = slaves.front().position;
|
||||
|
||||
if (!getDataType().empty()) { // data type specified
|
||||
if (!(dataType = findDataType(getDataType()))) {
|
||||
err << "Invalid data type '" << getDataType() << "'!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
} else { // no data type specified
|
||||
err << "Please specify a data type.";
|
||||
throwInvalidUsageException(err); // FIXME read from stream
|
||||
}
|
||||
|
||||
if (dataType->byteSize) {
|
||||
memSize = dataType->byteSize;
|
||||
} else {
|
||||
// guess string type size
|
||||
memSize = args[1].size();
|
||||
if (!memSize) {
|
||||
err << "Empty argument not allowed.";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
}
|
||||
|
||||
ioctl.data = new uint8_t[memSize + 1];
|
||||
|
||||
try {
|
||||
ioctl.data_size = interpretAsType(
|
||||
dataType, args[1], ioctl.data, memSize);
|
||||
} catch (SizeException &e) {
|
||||
delete [] ioctl.data;
|
||||
throwCommandException(e.what());
|
||||
} catch (ios::failure &e) {
|
||||
delete [] ioctl.data;
|
||||
err << "Invalid value argument '" << args[1]
|
||||
<< "' for type '" << dataType->name << "'!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
try {
|
||||
m.writeSoe(&ioctl);
|
||||
} catch (MasterDeviceSoeException &e) {
|
||||
delete [] ioctl.data;
|
||||
err << "SoE write command aborted with code 0x"
|
||||
<< setfill('0') << hex << setw(4) << e.errorCode << ".";
|
||||
throwCommandException(err);
|
||||
} catch (MasterDeviceException &e) {
|
||||
delete [] ioctl.data;
|
||||
throw e;
|
||||
}
|
||||
|
||||
delete [] ioctl.data;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -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 __COMMANDSOEWRITE_H__
|
||||
#define __COMMANDSOEWRITE_H__
|
||||
|
||||
#include "Command.h"
|
||||
#include "DataTypeHandler.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
class CommandSoeWrite:
|
||||
public Command,
|
||||
public DataTypeHandler
|
||||
{
|
||||
public:
|
||||
CommandSoeWrite();
|
||||
|
||||
string helpString() const;
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif
|
||||
@@ -27,6 +27,12 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
@@ -81,10 +87,18 @@ size_t DataTypeHandler::interpretAsType(
|
||||
stringstream str;
|
||||
size_t dataSize = type->byteSize;
|
||||
|
||||
#if DEBUG
|
||||
cerr << __func__ << "(targetSize=" << targetSize << ")" << endl;
|
||||
#endif
|
||||
|
||||
str << source;
|
||||
str >> resetiosflags(ios::basefield); // guess base from prefix
|
||||
str.exceptions(ios::failbit);
|
||||
|
||||
#if DEBUG
|
||||
cerr << "code=" << type->code << endl;
|
||||
#endif
|
||||
|
||||
switch (type->code) {
|
||||
case 0x0002: // int8
|
||||
{
|
||||
@@ -151,6 +165,10 @@ size_t DataTypeHandler::interpretAsType(
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
printRawData(cerr, (const uint8_t *) target, dataSize);
|
||||
#endif
|
||||
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ ethercat_SOURCES = \
|
||||
CommandSiiWrite.cpp \
|
||||
CommandSlaves.cpp \
|
||||
CommandSoeRead.cpp \
|
||||
CommandSoeWrite.cpp \
|
||||
CommandStates.cpp \
|
||||
CommandUpload.cpp \
|
||||
CommandVersion.cpp \
|
||||
@@ -95,6 +96,7 @@ noinst_HEADERS = \
|
||||
CommandSiiWrite.h \
|
||||
CommandSlaves.h \
|
||||
CommandSoeRead.h \
|
||||
CommandSoeWrite.h \
|
||||
CommandStates.h \
|
||||
CommandUpload.h \
|
||||
CommandVersion.h \
|
||||
|
||||
+16
-1
@@ -528,7 +528,7 @@ void MasterDevice::getEoeHandler(
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void MasterDevice::readSoe(ec_ioctl_slave_soe_t *data)
|
||||
void MasterDevice::readSoe(ec_ioctl_slave_soe_read_t *data)
|
||||
{
|
||||
if (ioctl(fd, EC_IOCTL_SLAVE_SOE_READ, data) < 0) {
|
||||
if (errno == EIO && data->error_code) {
|
||||
@@ -541,4 +541,19 @@ void MasterDevice::readSoe(ec_ioctl_slave_soe_t *data)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void MasterDevice::writeSoe(ec_ioctl_slave_soe_write_t *data)
|
||||
{
|
||||
if (ioctl(fd, EC_IOCTL_SLAVE_SOE_WRITE, data) < 0) {
|
||||
if (errno == EIO && data->error_code) {
|
||||
throw MasterDeviceSoeException(data->error_code);
|
||||
} else {
|
||||
stringstream err;
|
||||
err << "Failed to write IDN: " << strerror(errno);
|
||||
throw MasterDeviceException(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
+2
-1
@@ -140,7 +140,8 @@ class MasterDevice
|
||||
#ifdef EC_EOE
|
||||
void getEoeHandler(ec_ioctl_eoe_handler_t *, uint16_t);
|
||||
#endif
|
||||
void readSoe(ec_ioctl_slave_soe_t *);
|
||||
void readSoe(ec_ioctl_slave_soe_read_t *);
|
||||
void writeSoe(ec_ioctl_slave_soe_write_t *);
|
||||
|
||||
unsigned int getMasterCount() const {return masterCount;}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ using namespace std;
|
||||
#include "CommandSiiWrite.h"
|
||||
#include "CommandSlaves.h"
|
||||
#include "CommandSoeRead.h"
|
||||
#include "CommandSoeWrite.h"
|
||||
#include "CommandStates.h"
|
||||
#include "CommandUpload.h"
|
||||
#include "CommandVersion.h"
|
||||
@@ -337,6 +338,7 @@ int main(int argc, char **argv)
|
||||
commandList.push_back(new CommandSiiWrite());
|
||||
commandList.push_back(new CommandSlaves());
|
||||
commandList.push_back(new CommandSoeRead());
|
||||
commandList.push_back(new CommandSoeWrite());
|
||||
commandList.push_back(new CommandStates());
|
||||
commandList.push_back(new CommandUpload());
|
||||
commandList.push_back(new CommandVersion());
|
||||
|
||||
Reference in New Issue
Block a user