Implemented Sdo dictionary info via 'ethercat sdos'.
--- a/TODO Fri Jun 06 09:22:57 2008 +0000
+++ b/TODO Fri Jun 06 09:27:24 2008 +0000
@@ -10,8 +10,6 @@
* Slaves as array.
* Replace all Sysfs files via the new ethercat tool.
- - Sdo info
- - Sdo entry info
- Sdo entry value read
- Sdo entry value write
- Slave alias write
--- a/master/cdev.c Fri Jun 06 09:22:57 2008 +0000
+++ b/master/cdev.c Fri Jun 06 09:27:24 2008 +0000
@@ -195,6 +195,7 @@
data.state = slave->current_state;
data.sync_count = slave->sii.sync_count;
+ data.sdo_count = ec_slave_sdo_count(slave);
if (slave->sii.name) {
strncpy(data.name, slave->sii.name,
@@ -499,6 +500,104 @@
break;
}
+ case EC_IOCTL_SDO:
+ {
+ ec_ioctl_sdo_t data;
+ const ec_slave_t *slave;
+ const ec_sdo_t *sdo;
+
+ 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;
+ }
+
+ if (!(sdo = ec_slave_get_sdo_by_pos_const(
+ slave, data.sdo_position))) {
+ EC_ERR("Sdo %u does not exist in slave %u!\n",
+ data.sdo_position, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ data.sdo_index = sdo->index;
+ data.max_subindex = sdo->max_subindex;
+
+ if (sdo->name) {
+ strncpy(data.name, sdo->name, EC_IOCTL_SDO_NAME_SIZE);
+ data.name[EC_IOCTL_SDO_NAME_SIZE - 1] = 0;
+ } else {
+ data.name[0] = 0;
+ }
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+ }
+
+ case EC_IOCTL_SDO_ENTRY:
+ {
+ ec_ioctl_sdo_entry_t data;
+ const ec_slave_t *slave;
+ const ec_sdo_t *sdo;
+ const ec_sdo_entry_t *entry;
+
+ 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;
+ }
+
+ if (!(sdo = ec_slave_get_sdo_by_pos_const(
+ slave, data.sdo_position))) {
+ EC_ERR("Sdo %u does not exist in slave %u!\n",
+ data.sdo_position, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ if (!(entry = ec_sdo_get_entry_const(
+ sdo, data.sdo_entry_subindex))) {
+ EC_ERR("Sdo entry %u does not exist in Sdo %u "
+ "in slave %u!\n", data.sdo_entry_subindex,
+ data.sdo_position, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ data.data_type = entry->data_type;
+ data.bit_length = entry->bit_length;
+
+ if (entry->description) {
+ strncpy(data.description, entry->description,
+ EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE);
+ data.description[EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE - 1]
+ = 0;
+ } else {
+ data.description[0] = 0;
+ }
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+ }
+
default:
retval = -ENOIOCTLCMD;
}
--- a/master/ioctl.h Fri Jun 06 09:22:57 2008 +0000
+++ b/master/ioctl.h Fri Jun 06 09:27:24 2008 +0000
@@ -55,6 +55,8 @@
EC_IOCTL_DATA,
EC_IOCTL_SET_DEBUG,
EC_IOCTL_SLAVE_STATE,
+ EC_IOCTL_SDO,
+ EC_IOCTL_SDO_ENTRY,
};
/*****************************************************************************/
@@ -72,7 +74,7 @@
/*****************************************************************************/
-#define EC_IOCTL_SLAVE_NAME_SIZE 114
+#define EC_IOCTL_SLAVE_NAME_SIZE 104
typedef struct {
// input
@@ -86,6 +88,7 @@
uint16_t alias;
uint8_t state;
uint8_t sync_count;
+ uint16_t sdo_count;
char name[EC_IOCTL_SLAVE_NAME_SIZE];
} ec_ioctl_slave_t;
@@ -188,4 +191,35 @@
/*****************************************************************************/
+#define EC_IOCTL_SDO_NAME_SIZE 121
+
+typedef struct {
+ // inputs
+ uint16_t slave_position;
+ uint16_t sdo_position;
+
+ // outputs
+ uint16_t sdo_index;
+ uint8_t max_subindex;
+ char name[EC_IOCTL_SDO_NAME_SIZE];
+} ec_ioctl_sdo_t;
+
+/*****************************************************************************/
+
+#define EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE 120
+
+typedef struct {
+ // inputs
+ uint16_t slave_position;
+ uint16_t sdo_position;
+ uint8_t sdo_entry_subindex;
+
+ // outputs
+ uint16_t data_type;
+ uint16_t bit_length;
+ char description[EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE];
+} ec_ioctl_sdo_entry_t;
+
+/*****************************************************************************/
+
#endif
--- a/tools/Master.cpp Fri Jun 06 09:22:57 2008 +0000
+++ b/tools/Master.cpp Fri Jun 06 09:27:24 2008 +0000
@@ -224,6 +224,21 @@
/****************************************************************************/
+void Master::listSdos(int slavePosition)
+{
+ if (slavePosition == -1) {
+ unsigned int numSlaves = slaveCount(), i;
+
+ for (i = 0; i < numSlaves; i++) {
+ listSlaveSdos(i, true);
+ }
+ } else {
+ listSlaveSdos(slavePosition, false);
+ }
+}
+
+/****************************************************************************/
+
void Master::requestStates(
int slavePosition,
const vector<string> &commandArgs
@@ -375,7 +390,7 @@
/****************************************************************************/
-void Master::listSlavePdos(uint16_t slavePosition, bool printSlave)
+void Master::listSlavePdos(uint16_t slavePosition, bool withHeader)
{
ec_ioctl_slave_t slave;
ec_ioctl_sync_t sync;
@@ -385,7 +400,7 @@
getSlave(&slave, slavePosition);
- if (printSlave)
+ if (withHeader)
cout << "=== Slave " << slavePosition << " ===" << endl;
for (i = 0; i < slave.sync_count; i++) {
@@ -425,6 +440,40 @@
/****************************************************************************/
+void Master::listSlaveSdos(uint16_t slavePosition, bool withHeader)
+{
+ ec_ioctl_slave_t slave;
+ ec_ioctl_sdo_t sdo;
+ ec_ioctl_sdo_entry_t entry;
+ unsigned int i, j, k;
+
+ getSlave(&slave, slavePosition);
+
+ if (withHeader)
+ cout << "=== Slave " << slavePosition << " ===" << endl;
+
+ for (i = 0; i < slave.sdo_count; i++) {
+ getSdo(&sdo, slavePosition, i);
+
+ cout << "Sdo 0x"
+ << hex << setfill('0') << setw(4) << sdo.sdo_index
+ << ", \"" << sdo.name << "\"" << endl;
+
+ for (j = 0; j <= sdo.max_subindex; j++) {
+ getSdoEntry(&entry, slavePosition, i, j);
+
+ cout << " Entry 0x"
+ << hex << setfill('0') << setw(2)
+ << (unsigned int) entry.sdo_entry_subindex
+ << ", type 0x" << setw(4) << entry.data_type
+ << ", " << dec << entry.bit_length << " bit, \""
+ << entry.description << "\"" << endl;
+ }
+ }
+}
+
+/****************************************************************************/
+
void Master::generateSlaveXml(uint16_t slavePosition)
{
ec_ioctl_slave_t slave;
@@ -717,6 +766,58 @@
/****************************************************************************/
+void Master::getSdo(
+ ec_ioctl_sdo_t *sdo,
+ uint16_t slaveIndex,
+ uint16_t sdoPosition
+ )
+{
+ sdo->slave_position = slaveIndex;
+ sdo->sdo_position = sdoPosition;
+
+ if (ioctl(fd, EC_IOCTL_SDO, sdo)) {
+ stringstream err;
+ err << "Failed to get Sdo: ";
+ if (errno == EINVAL)
+ err << "Either slave " << slaveIndex << " does not exist, "
+ << "or it contains less than " << sdoPosition + 1 << " Sdos!"
+ << endl;
+ else
+ err << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
+void Master::getSdoEntry(
+ ec_ioctl_sdo_entry_t *entry,
+ uint16_t slaveIndex,
+ uint16_t sdoPosition,
+ uint8_t entrySubindex
+ )
+{
+ entry->slave_position = slaveIndex;
+ entry->sdo_position = sdoPosition;
+ entry->sdo_entry_subindex = entrySubindex;
+
+ if (ioctl(fd, EC_IOCTL_SDO_ENTRY, entry)) {
+ stringstream err;
+ err << "Failed to get Sdo entry: ";
+ if (errno == EINVAL)
+ err << "Either slave " << slaveIndex << " does not exist, "
+ << "or it contains less than " << sdoPosition + 1
+ << " Sdos, or the Sdo at position " << sdoPosition
+ << " contains less than " << (unsigned int) entrySubindex + 1
+ << " entries!" << endl;
+ else
+ err << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
void Master::requestState(
uint16_t slavePosition,
uint8_t state
--- a/tools/Master.h Fri Jun 06 09:22:57 2008 +0000
+++ b/tools/Master.h Fri Jun 06 09:27:24 2008 +0000
@@ -48,6 +48,7 @@
void listSlaves();
void showMaster();
void listPdos(int);
+ void listSdos(int);
void requestStates(int, const vector<string> &);
void generateXml(int);
@@ -55,6 +56,7 @@
void outputDomainData(unsigned int);
void showDomain(unsigned int);
void listSlavePdos(uint16_t, bool = false);
+ void listSlaveSdos(uint16_t, bool = false);
void generateSlaveXml(uint16_t);
unsigned int domainCount();
unsigned int slaveCount();
@@ -69,6 +71,8 @@
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 getSdo(ec_ioctl_sdo_t *, uint16_t, uint16_t);
+ void getSdoEntry(ec_ioctl_sdo_entry_t *, uint16_t, uint16_t, uint8_t);
void requestState(uint16_t, uint8_t);
static string slaveState(uint8_t);
--- a/tools/main.cpp Fri Jun 06 09:22:57 2008 +0000
+++ b/tools/main.cpp Fri Jun 06 09:27:24 2008 +0000
@@ -38,9 +38,10 @@
<< " domain Show domain information." << endl
<< " 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
+ << " pdos List Pdo mapping." << endl
+ << " sdos List Sdo dictionaries." << endl
+ << " state Request slave states." << endl
+ << " xml Generate slave information xmls." << endl
<< "Global options:" << endl
<< " --master -m <master> Index of the master to use. Default: "
<< DEFAULT_MASTER << endl
@@ -163,6 +164,8 @@
master.showMaster();
} else if (command == "pdos") {
master.listPdos(slavePosition);
+ } else if (command == "sdos") {
+ master.listSdos(slavePosition);
} else if (command == "state") {
master.requestStates(slavePosition, commandArgs);
} else if (command == "xml") {