Implemented Sdo dictionary info via 'ethercat sdos'.
authorFlorian Pose <fp@igh-essen.com>
Fri, 06 Jun 2008 09:27:24 +0000
changeset 965 1aee4aa1def3
parent 964 957f21465052
child 966 f1a7ea8a550a
Implemented Sdo dictionary info via 'ethercat sdos'.
TODO
master/cdev.c
master/ioctl.h
tools/Master.cpp
tools/Master.h
tools/main.cpp
--- 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") {