Skip to content
Snippets Groups Projects
Commit 7a341066 authored by Florian Pose's avatar Florian Pose
Browse files

Request slave state(s) with 'ethercat state'; removed sysfs state file.

parent 26814163
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@ $Id$
Version 1.4.0:
* Slaves as array.
* Replace all Sysfs files via the new ethercat tool.
- Sdo info
- Sdo entry info
......@@ -15,7 +16,6 @@ Version 1.4.0:
- Sdo entry value write
- Slave alias write
- Slave SII write
- Slave state request
- Slave info (flags, mailbox, general)
- Config info (alias, position, type, Pdos, Sdos)
* Remove the end state of the master state machine.
......
......@@ -478,6 +478,27 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
break;
case EC_IOCTL_SLAVE_STATE:
{
ec_ioctl_slave_state_t data;
ec_slave_t *slave;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
retval = -EFAULT;
break;
}
if (!(slave = ec_master_find_slave(
master, 0, data.slave_position))) {
EC_ERR("Slave %u does not exist!\n", data.slave_position);
retval = -EINVAL;
break;
}
ec_slave_request_state(slave, data.requested_state);
break;
}
default:
retval = -ENOIOCTLCMD;
}
......
......@@ -54,6 +54,7 @@ enum {
EC_IOCTL_DOMAIN_FMMU,
EC_IOCTL_DATA,
EC_IOCTL_SET_DEBUG,
EC_IOCTL_SLAVE_STATE,
};
/*****************************************************************************/
......@@ -179,4 +180,12 @@ typedef struct {
/*****************************************************************************/
typedef struct {
// inputs
uint16_t slave_position;
uint8_t requested_state;
} ec_ioctl_slave_state_t;
/*****************************************************************************/
#endif
......@@ -66,13 +66,11 @@ char *ec_slave_sii_string(ec_slave_t *, unsigned int);
/** \cond */
EC_SYSFS_READ_ATTR(info);
EC_SYSFS_READ_WRITE_ATTR(state);
EC_SYSFS_READ_WRITE_ATTR(sii);
EC_SYSFS_READ_WRITE_ATTR(alias);
static struct attribute *def_attrs[] = {
&attr_info,
&attr_state,
&attr_sii,
&attr_alias,
NULL,
......@@ -1082,22 +1080,7 @@ ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
if (attr == &attr_info) {
return ec_slave_info(slave, buffer);
}
else if (attr == &attr_state) {
switch (slave->current_state) {
case EC_SLAVE_STATE_INIT:
return sprintf(buffer, "INIT\n");
case EC_SLAVE_STATE_PREOP:
return sprintf(buffer, "PREOP\n");
case EC_SLAVE_STATE_SAFEOP:
return sprintf(buffer, "SAFEOP\n");
case EC_SLAVE_STATE_OP:
return sprintf(buffer, "OP\n");
default:
return sprintf(buffer, "UNKNOWN\n");
}
}
else if (attr == &attr_sii) {
} else if (attr == &attr_sii) {
if (slave->sii_data) {
if (slave->sii_size > PAGE_SIZE) {
EC_ERR("SII contents of slave %u exceed 1 page (%u/%u).\n",
......@@ -1109,8 +1092,7 @@ ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
return slave->sii_size;
}
}
}
else if (attr == &attr_alias) {
} else if (attr == &attr_alias) {
return sprintf(buffer, "%u\n", slave->sii.alias);
}
......@@ -1132,30 +1114,9 @@ ssize_t ec_store_slave_attribute(struct kobject *kobj, /**< slave's kobject */
{
ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
if (attr == &attr_state) {
char state[EC_STATE_STRING_SIZE];
if (!strcmp(buffer, "INIT\n"))
ec_slave_request_state(slave, EC_SLAVE_STATE_INIT);
else if (!strcmp(buffer, "PREOP\n"))
ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
else if (!strcmp(buffer, "SAFEOP\n"))
ec_slave_request_state(slave, EC_SLAVE_STATE_SAFEOP);
else if (!strcmp(buffer, "OP\n"))
ec_slave_request_state(slave, EC_SLAVE_STATE_OP);
else {
EC_ERR("Invalid slave state \"%s\"!\n", buffer);
return -EINVAL;
}
ec_state_string(slave->requested_state, state);
EC_INFO("Accepted new state %s for slave %u.\n",
state, slave->ring_position);
return size;
}
else if (attr == &attr_sii) {
if (attr == &attr_sii) {
return ec_slave_write_sii(slave, buffer, size);
}
else if (attr == &attr_alias) {
} else if (attr == &attr_alias) {
return ec_slave_write_alias(slave, buffer, size);
}
......
......@@ -13,6 +13,7 @@
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cctype> // toupper()
using namespace std;
#include "Master.h"
......@@ -223,6 +224,49 @@ void Master::listPdos(int slavePosition)
/****************************************************************************/
void Master::requestStates(
int slavePosition,
const vector<string> &commandArgs
)
{
string stateStr;
uint8_t state;
if (commandArgs.size() != 1) {
stringstream err;
err << "'state' takes exactly one argument!";
throw MasterException(err.str());
}
stateStr = commandArgs[0];
transform(stateStr.begin(), stateStr.end(),
stateStr.begin(), (int (*) (int)) std::toupper);
if (stateStr == "INIT") {
state = 0x01;
} else if (stateStr == "PREOP") {
state = 0x02;
} else if (stateStr == "SAFEOP") {
state = 0x04;
} else if (stateStr == "OP") {
state = 0x08;
} else {
stringstream err;
err << "Invalid state '" << commandArgs[0] << "'!";
throw MasterException(err.str());
}
if (slavePosition == -1) {
unsigned int i, numSlaves = slaveCount();
for (i = 0; i < numSlaves; i++)
requestState(i, state);
} else {
requestState(slavePosition, state);
}
}
/****************************************************************************/
void Master::generateXml(int slavePosition)
{
if (slavePosition == -1) {
......@@ -673,6 +717,29 @@ void Master::getPdoEntry(
/****************************************************************************/
void Master::requestState(
uint16_t slavePosition,
uint8_t state
)
{
ec_ioctl_slave_state_t data;
data.slave_position = slavePosition;
data.requested_state = state;
if (ioctl(fd, EC_IOCTL_SLAVE_STATE, &data)) {
stringstream err;
err << "Failed to request slave state: ";
if (errno == EINVAL)
err << "Slave " << slavePosition << " does not exist!";
else
err << strerror(errno);
throw MasterException(err.str());
}
}
/****************************************************************************/
string Master::slaveState(uint8_t state)
{
switch (state) {
......
......@@ -48,6 +48,7 @@ class Master
void listSlaves();
void showMaster();
void listPdos(int);
void requestStates(int, const vector<string> &);
void generateXml(int);
protected:
......@@ -68,6 +69,7 @@ class Master
void getPdo(ec_ioctl_pdo_t *, uint16_t, uint8_t, uint8_t);
void getPdoEntry(ec_ioctl_pdo_entry_t *, uint16_t, uint8_t, uint8_t,
uint8_t);
void requestState(uint16_t, uint8_t);
static string slaveState(uint8_t);
......
......@@ -39,6 +39,7 @@ void printUsage()
<< " list (ls, slaves) List all slaves (former 'lsec')." << endl
<< " master Show master information." << endl
<< " pdos List Pdo mapping of given slaves." << endl
<< " state Request slave state(s)." << endl
<< " xml Generate slave information xml." << endl
<< "Global options:" << endl
<< " --master -m <master> Index of the master to use. Default: "
......@@ -162,6 +163,8 @@ int main(int argc, char **argv)
master.showMaster();
} else if (command == "pdos") {
master.listPdos(slavePosition);
} else if (command == "state") {
master.requestStates(slavePosition, commandArgs);
} else if (command == "xml") {
master.generateXml(slavePosition);
} else {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment