Merge branch 'master' of gitlab.com:etherlab.org/ethercat

This commit is contained in:
Florian Pose 2022-05-16 09:50:44 +02:00
commit 526370a5a5
8 changed files with 141 additions and 16 deletions

View File

@ -61,6 +61,7 @@ void ec_foe_request_init(
INIT_LIST_HEAD(&req->list);
req->buffer = NULL;
req->file_name = file_name;
req->password = 0;
req->buffer_size = 0;
req->data_size = 0;
req->dir = EC_DIR_INVALID;

View File

@ -65,6 +65,7 @@ typedef struct {
unsigned long jiffies_sent; /**< Jiffies, when the upload/download
request was sent. */
uint8_t *file_name; /**< Pointer to the filename. */
uint32_t password; /**< Password needed for FoE. */
uint32_t result; /**< FoE request abort code. Zero on success. */
uint32_t error_code; /**< Error code from an FoE Error Request. */
} ec_foe_request_t;

View File

@ -297,7 +297,7 @@ int ec_foe_prepare_wrq_send(
}
EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
EC_WRITE_U32( data + 2, fsm->tx_packet_no );
EC_WRITE_U32( data + 2, fsm->request->password );
#ifdef DEBUG_FOE
EC_SLAVE_DBG(fsm->slave, 0, "sending opcode %u packet %u\n",
EC_FOE_OPCODE_WRQ, fsm->tx_packet_no);
@ -589,7 +589,7 @@ int ec_foe_prepare_rrq_send(
}
EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
EC_WRITE_U32(data + 2, 0x00000000); // no passwd
EC_WRITE_U32(data + 2, fsm->request->password);
memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
#ifdef DEBUG_FOE
EC_SLAVE_DBG(fsm->slave, 0, "sending opcode %u\n", EC_FOE_OPCODE_RRQ);

View File

@ -4100,12 +4100,13 @@ static ATTRIBUTES int ec_ioctl_slave_foe_read(
}
ec_foe_request_init(&request, io.file_name);
ret = ec_foe_request_alloc(&request, 10000); // FIXME
ret = ec_foe_request_alloc(&request, io.buffer_size); // FIXME
if (ret) {
ec_foe_request_clear(&request);
return ret;
}
request.password = io.password;
ec_foe_request_read(&request);
if (down_interruptible(&master->master_sem)) {
@ -4210,6 +4211,7 @@ static ATTRIBUTES int ec_ioctl_slave_foe_write(
}
request.data_size = io.buffer_size;
request.password = io.password;
ec_foe_request_write(&request);
if (down_interruptible(&master->master_sem)) {

View File

@ -426,6 +426,7 @@ typedef struct {
typedef struct {
// inputs
uint32_t password;
uint16_t slave_position;
uint16_t offset;
size_t buffer_size;

View File

@ -0,0 +1,86 @@
# Copyright (C) 2022 Bjarne von Horn, Ingenieurgemeinschaft IgH
#
# This file is part of the IgH EtherCAT master userspace library.
#
# The IgH EtherCAT master userspace library is free software; you can
# redistribute it and/or modify it under the terms of the GNU Lesser General
# Public License as published by the Free Software Foundation; version 2.1
# of the License.
#
# The IgH EtherCAT master userspace library 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the IgH EtherCAT master userspace library. If not, see
# <http://www.gnu.org/licenses/>.
#
# ---
#
# 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.
_ethercat_completions()
{
local ethercat_commands="alias confic crc cstruct data debug domains download eoe foe_read foe_write graph master pdos reg_read reg_write rescan sdos sii_read sii_write slaves soe_read soe_write states upload version xml"
local options="--help --force --quiet --verbose --master "
if [ "$COMP_CWORD" -eq 1 ] ; then
COMPREPLY=($(compgen -W "$ethercat_commands --help" -- "${COMP_WORDS[1]}"))
elif [[ "${COMP_WORDS[1]}" != "--help" && ! "${COMP_WORDS[COMP_CWORD-1]}" =~ ^-a|-p|--alias|--position$ ]] ; then
case "${COMP_WORDS[1]}" in
"alias" | "config" | "cstruct" | "slaves" | "sdos" | "sii_read" | "upload" | "xml")
options+="--alias --position"
;;
"crc")
options+="reset"
;;
"debug")
options+="0 1 2"
;;
"domains")
options+="--domain"
;;
"download" | "reg_read" | "soe_read" | "soe_write")
if [[ "${COMP_WORDS[COMP_CWORD-1]}" =~ ^-t|--type$ ]] ; then
options="bool int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double string octet_string unicode_string sm8 sm16 sm32 sm64"
else
options+="--alias --position --type"
fi
;;
"foe_read" | "foe_write")
if [[ "${COMP_WORDS[COMP_CWORD-1]}" =~ ^-o|--output-file$ ]] ; then
COMPREPLY=($(compgen -o filenames -A file -- "${COMP_WORDS[$COMP_CWORD]}"))
else
options+="--alias --position --output-file"
COMPREPLY=($(compgen -o filenames -A file -W "$options" -- "${COMP_WORDS[$COMP_CWORD]}"))
fi
return
;;
"graph")
options+="DC CRC"
;;
"pdos")
if [[ "${COMP_WORDS[COMP_CWORD-1]}" =~ ^-s|--skin$ ]] ; then
options="default etherlab"
else
options+="--alias --position --skin"
fi
;;
"sii_write")
options+="--alias --position"
COMPREPLY=($(compgen -o filenames -A file -W "$options" -- "${COMP_WORDS[$COMP_CWORD]}"))
return
;;
"states")
options+="--alias --position INIT PREOP BOOT SAFEOP OP"
;;
esac
COMPREPLY+=($(compgen -W "$options" -- "${COMP_WORDS[$COMP_CWORD]}"))
fi
}
complete -F _ethercat_completions ethercat

View File

@ -31,6 +31,7 @@
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
#include "CommandFoeRead.h"
@ -51,7 +52,7 @@ string CommandFoeRead::helpString(const string &binaryBaseName) const
stringstream str;
str << binaryBaseName << " " << getName()
<< " [OPTIONS] <SOURCEFILE>" << endl
<< " [OPTIONS] <SOURCEFILE> [<PASSWORD>]" << endl
<< endl
<< getBriefDescription() << endl
<< endl
@ -59,6 +60,7 @@ string CommandFoeRead::helpString(const string &binaryBaseName) const
<< endl
<< "Arguments:" << endl
<< " SOURCEFILE is the name of the source file on the slave." << endl
<< " PASSWORD is the numeric password defined by the vendor." << endl
<< endl
<< "Command-specific options:" << endl
<< " --output-file -o <file> Local target filename. If" << endl
@ -80,11 +82,12 @@ void CommandFoeRead::execute(const StringVector &args)
SlaveList slaves;
ec_ioctl_slave_t *slave;
ec_ioctl_slave_foe_t data;
unsigned int i;
stringstream err;
fstream out_file;
ostream* out = &cout;
if (args.size() != 1) {
err << "'" << getName() << "' takes exactly one argument!";
if (args.size() < 1 || args.size() > 2) {
err << "'" << getName() << "' takes one or two arguments!";
throwInvalidUsageException(err);
}
@ -98,14 +101,36 @@ void CommandFoeRead::execute(const StringVector &args)
slave = &slaves.front();
data.slave_position = slave->position;
if (!getOutputFile().empty() && getOutputFile() != "-") {
out_file.open(getOutputFile().c_str(), ios::out | ios::trunc | ios::binary);
if (!out_file.good()) {
err << "Failed to open '" << getOutputFile() << "'";
throwCommandException(err);
}
out = &out_file;
}
/* FIXME: No good idea to have a fixed buffer size.
* Read in chunks and fill a buffer instead.
*/
data.password = 0;
data.offset = 0;
data.buffer_size = 0x8800;
data.buffer = new uint8_t[data.buffer_size];
strncpy(data.file_name, args[0].c_str(), sizeof(data.file_name) - 1);
data.file_name[sizeof(data.file_name)-1] = 0;
if (args.size() >= 2) {
stringstream strPassword;
strPassword << args[1];
strPassword
>> resetiosflags(ios::basefield) // guess base from prefix
>> data.password;
if (strPassword.fail()) {
err << "Invalid password '" << args[1] << "'!";
throwInvalidUsageException(err);
}
}
try {
m.readFoe(&data);
@ -126,12 +151,7 @@ void CommandFoeRead::execute(const StringVector &args)
}
}
// TODO --output-file
for (i = 0; i < data.data_size; i++) {
uint8_t *w = data.buffer + i;
cout << *(uint8_t *) w ;
}
out->write((const char*) data.buffer, data.data_size);
delete [] data.buffer;
}

View File

@ -53,7 +53,7 @@ string CommandFoeWrite::helpString(const string &binaryBaseName) const
stringstream str;
str << binaryBaseName << " " << getName()
<< " [OPTIONS] <FILENAME>" << endl
<< " [OPTIONS] <FILENAME> [<PASSWORD>]" << endl
<< endl
<< getBriefDescription() << endl
<< endl
@ -63,6 +63,7 @@ string CommandFoeWrite::helpString(const string &binaryBaseName) const
<< " FILENAME can either be a path to a file, or '-'. In" << endl
<< " the latter case, data are read from stdin and" << endl
<< " the --output-file option has to be specified." << endl
<< " PASSWORD is the numeric password defined by the vendor." << endl
<< endl
<< "Command-specific options:" << endl
<< " --output-file -o <file> Target filename on the slave." << endl
@ -89,8 +90,8 @@ void CommandFoeWrite::execute(const StringVector &args)
SlaveList slaves;
string storeFileName;
if (args.size() != 1) {
err << "'" << getName() << "' takes exactly one argument!";
if (args.size() < 1 || args.size() > 2) {
err << "'" << getName() << "' takes one or two arguments!";
throwInvalidUsageException(err);
}
@ -140,8 +141,21 @@ void CommandFoeWrite::execute(const StringVector &args)
// write data via foe to the slave
data.offset = 0;
data.password = 0;
strncpy(data.file_name, storeFileName.c_str(),
sizeof(data.file_name) - 1);
data.file_name[sizeof(data.file_name)-1] = 0;
if (args.size() >= 2) {
stringstream strPassword;
strPassword << args[1];
strPassword
>> resetiosflags(ios::basefield) // guess base from prefix
>> data.password;
if (strPassword.fail()) {
err << "Invalid password '" << args[1] << "'!";
throwInvalidUsageException(err);
}
}
try {
m.writeFoe(&data);