From ba40d2ad62d9f6eed77fb5e28d9468529f44284b Mon Sep 17 00:00:00 2001
From: Florian Pose <fp@igh-essen.com>
Date: Mon, 2 Jun 2008 14:40:19 +0000
Subject: [PATCH] Added 'xml' command to generate a slave description file from
 a real slave.

---
 master/cdev.c    |   2 +
 master/ioctl.h   |   2 +
 tools/Master.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/Master.h   |   2 +
 tools/main.cpp   |   4 +-
 5 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/master/cdev.c b/master/cdev.c
index 9f522989..f5e38245 100644
--- a/master/cdev.c
+++ b/master/cdev.c
@@ -165,6 +165,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
                 data.vendor_id = slave->sii.vendor_id;
                 data.product_code = slave->sii.product_code;
+                data.revision_number = slave->sii.revision_number;
+                data.serial_number = slave->sii.serial_number;
                 data.alias = slave->sii.alias;
                 data.state = slave->current_state;
 
diff --git a/master/ioctl.h b/master/ioctl.h
index e21d5069..3eb3209d 100644
--- a/master/ioctl.h
+++ b/master/ioctl.h
@@ -62,6 +62,8 @@ typedef struct {
     // outputs
     uint32_t vendor_id;
     uint32_t product_code;
+    uint32_t revision_number;
+    uint32_t serial_number;
     uint16_t alias;
     uint8_t state;
     uint8_t sync_count;
diff --git a/tools/Master.cpp b/tools/Master.cpp
index 3e3a71dd..b857ddb8 100644
--- a/tools/Master.cpp
+++ b/tools/Master.cpp
@@ -112,6 +112,21 @@ void Master::listPdos(int slavePosition)
 
 /****************************************************************************/
 
+void Master::generateXml(int slavePosition)
+{
+    if (slavePosition == -1) {
+        unsigned int numSlaves = slaveCount(), i;
+
+        for (i = 0; i < numSlaves; i++) {
+            generateSlaveXml(i);
+        }
+    } else {
+        generateSlaveXml(slavePosition);
+    }
+}
+
+/****************************************************************************/
+
 void Master::listSlavePdos(uint16_t slavePosition, bool printSlave)
 {
     ec_ioctl_slave_t slave;
@@ -162,6 +177,104 @@ void Master::listSlavePdos(uint16_t slavePosition, bool printSlave)
 
 /****************************************************************************/
 
+void Master::generateSlaveXml(uint16_t slavePosition)
+{
+    ec_ioctl_slave_t slave;
+    ec_ioctl_sync_t sync;
+    ec_ioctl_pdo_t pdo;
+    ec_ioctl_pdo_entry_t entry;
+    unsigned int i, j, k;
+    
+    getSlave(&slave, slavePosition);
+
+    cout
+        << "<?xml version=\"1.0\" ?>" << endl
+        << "  <EtherCATInfo>" << endl
+        << "    <!-- Slave " << slave.position << " -->" << endl
+        << "    <Vendor>" << endl
+        << "      <Id>" << slave.vendor_id << "</Id>" << endl
+        << "    </Vendor>" << endl
+        << "    <Descriptions>" << endl
+        << "      <Devices>" << endl
+        << "        <Device>" << endl
+        << "          <Type ProductCode=\"#x"
+        << hex << setfill('0') << setw(8) << slave.product_code
+        << "\" RevisionNo=\"#x"
+        << hex << setfill('0') << setw(8) << slave.revision_number
+        << "\"/>" << endl;
+
+    for (i = 0; i < slave.sync_count; i++) {
+        getSync(&sync, slavePosition, i);
+
+        for (j = 0; j < sync.pdo_count; j++) {
+            getPdo(&pdo, slavePosition, i, j);
+
+            cout
+                << "          <" << (pdo.dir ? "T" : "R") << "xPdo>" << endl
+                << "            <Index>#x"
+                << hex << setfill('0') << setw(4) << pdo.index
+                << "</Index>" << endl
+                << "            <Name>" << pdo.name << "</Name>" << endl;
+
+            for (k = 0; k < pdo.entry_count; k++) {
+                getPdoEntry(&entry, slavePosition, i, j, k);
+
+                cout
+                    << "            <Entry>" << endl
+                    << "              <Index>#x"
+                    << hex << setfill('0') << setw(4) << entry.index
+                    << "</Index>" << endl;
+                if (entry.index)
+                    cout
+                        << "              <SubIndex>"
+                        << dec << (unsigned int) entry.subindex
+                        << "</SubIndex>" << endl;
+                
+                cout
+                    << "              <BitLen>"
+                    << (unsigned int) entry.bit_length
+                    << "</BitLen>" << endl;
+
+                if (entry.index) {
+                    cout
+                        << "              <Name>" << entry.name
+                        << "</Name>" << endl
+                        << "              <DataType>";
+
+                    if (entry.bit_length == 1) {
+                        cout << "BOOL";
+                    } else if (!(entry.bit_length % 8)) {
+                        if (entry.bit_length <= 64)
+                            cout << "UINT" << (unsigned int) entry.bit_length;
+                        else
+                            cout << "STRING("
+                                << (unsigned int) (entry.bit_length / 8)
+                                << ")";
+                    } else {
+                        cerr << "Invalid bit length "
+                            << (unsigned int) entry.bit_length << endl;
+                    }
+
+                        cout << "</DataType>" << endl;
+                }
+
+                cout << "            </Entry>" << endl;
+            }
+
+            cout
+                << "          </" << (pdo.dir ? "T" : "R") << "xPdo>" << endl;
+        }
+    }
+
+    cout
+        << "        </Device>" << endl
+        << "     </Devices>" << endl
+        << "  </Descriptions>" << endl
+        << "</EtherCATInfo>" << endl;
+}
+
+/****************************************************************************/
+
 unsigned int Master::slaveCount()
 {
     int ret;
diff --git a/tools/Master.h b/tools/Master.h
index 6a589f4c..8060fd0d 100644
--- a/tools/Master.h
+++ b/tools/Master.h
@@ -42,9 +42,11 @@ class Master
 
         void listSlaves();
         void listPdos(int);
+        void generateXml(int);
 
     protected:
         void listSlavePdos(uint16_t, bool = false);
+        void generateSlaveXml(uint16_t);
         unsigned int slaveCount();
         void slaveSyncs(uint16_t);
         void getSlave(ec_ioctl_slave_t *, uint16_t);
diff --git a/tools/main.cpp b/tools/main.cpp
index 7267ace6..983ae49a 100644
--- a/tools/main.cpp
+++ b/tools/main.cpp
@@ -31,6 +31,7 @@ void printUsage()
 		<< "Commands:" << endl
         << "  list (ls, slaves)  List all slaves (former 'lsec')." << endl
         << "  pdos               List Pdo mapping of given slaves." << endl
+        << "  xml                Generate slave information xml." << endl
 		<< "Global options:" << endl
         << "  --master  -m <master>  Index of the master to use. Default: "
 		<< DEFAULT_MASTER	<< endl
@@ -121,9 +122,10 @@ int main(int argc, char **argv)
 
         if (command == "list" || command == "ls" || command == "slaves") {
             master.listSlaves();
-
         } else if (command == "pdos") {
             master.listPdos(slavePosition);
+        } else if (command == "xml") {
+            master.generateXml(slavePosition);
         } else {
             cerr << "Unknown command " << command << "!" << endl;
             printUsage();
-- 
GitLab