# HG changeset patch # User Florian Pose # Date 1212739954 0 # Node ID 36e460ffbb5e0df68adcd1b92d4339a2ba787a8a # Parent 676e15bc5f27cf996c32001b3cdd0197a972d895 Request slave state(s) with 'ethercat state'; removed sysfs state file. diff -r 676e15bc5f27 -r 36e460ffbb5e TODO --- 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. diff -r 676e15bc5f27 -r 36e460ffbb5e master/cdev.c --- 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; } diff -r 676e15bc5f27 -r 36e460ffbb5e master/ioctl.h --- 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 diff -r 676e15bc5f27 -r 36e460ffbb5e master/slave.c --- 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); } diff -r 676e15bc5f27 -r 36e460ffbb5e tools/Master.cpp --- 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 #include #include +#include // toupper() using namespace std; #include "Master.h" @@ -223,6 +224,49 @@ /****************************************************************************/ +void Master::requestStates( + int slavePosition, + const vector &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) { diff -r 676e15bc5f27 -r 36e460ffbb5e tools/Master.h --- 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 &); 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); diff -r 676e15bc5f27 -r 36e460ffbb5e tools/main.cpp --- 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 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 {