Request slave state(s) with 'ethercat state'; removed sysfs state file.
--- a/TODO Thu Jun 05 15:58:25 2008 +0000
+++ b/TODO Fri Jun 06 08:12:34 2008 +0000
@@ -8,6 +8,7 @@
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 @@
- 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.
--- a/master/cdev.c Thu Jun 05 15:58:25 2008 +0000
+++ b/master/cdev.c Fri Jun 06 08:12:34 2008 +0000
@@ -478,6 +478,27 @@
}
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;
}
--- a/master/ioctl.h Thu Jun 05 15:58:25 2008 +0000
+++ b/master/ioctl.h Fri Jun 06 08:12:34 2008 +0000
@@ -54,6 +54,7 @@
EC_IOCTL_DOMAIN_FMMU,
EC_IOCTL_DATA,
EC_IOCTL_SET_DEBUG,
+ EC_IOCTL_SLAVE_STATE,
};
/*****************************************************************************/
@@ -179,4 +180,12 @@
/*****************************************************************************/
+typedef struct {
+ // inputs
+ uint16_t slave_position;
+ uint8_t requested_state;
+} ec_ioctl_slave_state_t;
+
+/*****************************************************************************/
+
#endif
--- a/master/slave.c Thu Jun 05 15:58:25 2008 +0000
+++ b/master/slave.c Fri Jun 06 08:12:34 2008 +0000
@@ -66,13 +66,11 @@
/** \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 @@
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 @@
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 @@
{
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);
}
--- a/tools/Master.cpp Thu Jun 05 15:58:25 2008 +0000
+++ b/tools/Master.cpp Fri Jun 06 08:12:34 2008 +0000
@@ -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::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::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) {
--- a/tools/Master.h Thu Jun 05 15:58:25 2008 +0000
+++ b/tools/Master.h Fri Jun 06 08:12:34 2008 +0000
@@ -48,6 +48,7 @@
void listSlaves();
void showMaster();
void listPdos(int);
+ void requestStates(int, const vector<string> &);
void generateXml(int);
protected:
@@ -68,6 +69,7 @@
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);
--- a/tools/main.cpp Thu Jun 05 15:58:25 2008 +0000
+++ b/tools/main.cpp Fri Jun 06 08:12:34 2008 +0000
@@ -39,6 +39,7 @@
<< " 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 @@
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 {