'ethercat domain' shows domain contents and process data.
authorFlorian Pose <fp@igh-essen.com>
Wed, 04 Jun 2008 13:17:15 +0000
changeset 950 8b00e63fff90
parent 949 e424c0074c67
child 951 dc84a0af63da
'ethercat domain' shows domain contents and process data.
master/cdev.c
master/domain.c
master/domain.h
master/fmmu_config.c
master/fmmu_config.h
master/ioctl.h
tools/Master.cpp
tools/Master.h
--- a/master/cdev.c	Wed Jun 04 10:41:50 2008 +0000
+++ b/master/cdev.c	Wed Jun 04 13:17:15 2008 +0000
@@ -42,6 +42,7 @@
 
 #include "cdev.h"
 #include "master.h"
+#include "slave_config.h"
 #include "ioctl.h"
 
 /*****************************************************************************/
@@ -371,6 +372,44 @@
                 data.logical_base_address = domain->logical_base_address;
                 data.working_counter = domain->working_counter;
                 data.expected_working_counter = domain->expected_working_counter;
+                data.fmmu_count = ec_domain_fmmu_count(domain);
+
+                if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+                    retval = -EFAULT;
+                    break;
+                }
+                break;
+            }
+
+        case EC_IOCTL_DOMAIN_FMMU:
+            {
+                ec_ioctl_domain_fmmu_t data;
+                const ec_domain_t *domain;
+                const ec_fmmu_config_t *fmmu;
+
+                if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+                    retval = -EFAULT;
+                    break;
+                }
+                
+                if (!(domain = ec_master_find_domain(master, data.domain_index))) {
+                    EC_ERR("Domain %u does not exist!\n", data.domain_index);
+                    retval = -EINVAL;
+                    break;
+                }
+
+                if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
+                    EC_ERR("Domain %u has less than %u fmmu configurations.\n",
+                            data.domain_index, data.fmmu_index + 1);
+                    retval = -EINVAL;
+                    break;
+                }
+
+                data.slave_config_alias = fmmu->sc->alias;
+                data.slave_config_position = fmmu->sc->position;
+                data.fmmu_dir = fmmu->dir;
+                data.logical_address = fmmu->logical_start_address;
+                data.data_size = fmmu->data_size;
 
                 if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
                     retval = -EFAULT;
--- a/master/domain.c	Wed Jun 04 10:41:50 2008 +0000
+++ b/master/domain.c	Wed Jun 04 13:17:15 2008 +0000
@@ -108,6 +108,7 @@
     domain->notify_jiffies = 0;
 
     INIT_LIST_HEAD(&domain->datagrams);
+    INIT_LIST_HEAD(&domain->fmmu_configs);
 
     // init kobject and add it to the hierarchy
     memset(&domain->kobj, 0x00, sizeof(struct kobject));
@@ -202,6 +203,8 @@
     domain->data_size += fmmu->data_size;
     wc_increment = working_counter_increment[fmmu->dir];
     domain->expected_working_counter += wc_increment;
+    
+    list_add_tail(&fmmu->list, &domain->fmmu_configs);
 
     if (domain->master->debug_level)
         EC_DBG("Domain %u: Added %u bytes (now %u) with dir %u -> WC %u"
@@ -373,6 +376,38 @@
     return 0;
 }
 
+/*****************************************************************************/
+
+unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
+{
+    const ec_fmmu_config_t *fmmu;
+    unsigned int num = 0;
+
+    list_for_each_entry(fmmu, &domain->fmmu_configs, list) {
+        num++;
+    }
+
+    return num;
+}
+
+/*****************************************************************************/
+
+const ec_fmmu_config_t *ec_domain_find_fmmu(
+        const ec_domain_t *domain,
+        unsigned int index
+        )
+{
+    const ec_fmmu_config_t *fmmu;
+
+    list_for_each_entry(fmmu, &domain->fmmu_configs, list) {
+        if (index--)
+            continue;
+        return fmmu;
+    }
+
+    return NULL;
+}
+
 /******************************************************************************
  *  Realtime interface
  *****************************************************************************/
--- a/master/domain.h	Wed Jun 04 10:41:50 2008 +0000
+++ b/master/domain.h	Wed Jun 04 13:17:15 2008 +0000
@@ -74,6 +74,7 @@
     unsigned int working_counter_changes; /**< Working counter changes
                                              since last notification. */
     unsigned long notify_jiffies; /**< Time of last notification. */
+    struct list_head fmmu_configs; /**< FMMU configurations contained. */
 };
 
 /*****************************************************************************/
@@ -84,6 +85,9 @@
 void ec_domain_add_fmmu_config(ec_domain_t *, ec_fmmu_config_t *);
 int ec_domain_finish(ec_domain_t *, uint32_t);
 
+unsigned int ec_domain_fmmu_count(const ec_domain_t *);
+const ec_fmmu_config_t *ec_domain_find_fmmu(const ec_domain_t *, unsigned int);
+
 /*****************************************************************************/
 
 #endif
--- a/master/fmmu_config.c	Wed Jun 04 10:41:50 2008 +0000
+++ b/master/fmmu_config.c	Wed Jun 04 13:17:15 2008 +0000
@@ -58,6 +58,7 @@
         ec_direction_t dir /**< Pdo direction. */
         )
 {
+    INIT_LIST_HEAD(&fmmu->list);
     fmmu->sc = sc;
     fmmu->dir = dir;
 
@@ -80,7 +81,7 @@
         )
 {
     if (fmmu->sc->master->debug_level) {
-        EC_DBG("FMMU: LogAddr 0x%08X, Size %3i, PhysAddr 0x%04X, Dir %s\n",
+        EC_DBG("FMMU: LogAddr 0x%08X, Size %3u, PhysAddr 0x%04X, Dir %s\n",
                fmmu->logical_start_address, fmmu->data_size,
                sync->physical_start_address,
                (sync->control_register & 0x04) ? "out" : "in");
--- a/master/fmmu_config.h	Wed Jun 04 10:41:50 2008 +0000
+++ b/master/fmmu_config.h	Wed Jun 04 13:17:15 2008 +0000
@@ -50,6 +50,7 @@
 /** FMMU configuration.
  */
 typedef struct {
+    struct list_head list; /**< List node used by domain. */
     const ec_slave_config_t *sc; /**< EtherCAT slave config. */
     const ec_domain_t *domain; /**< Domain. */
     ec_direction_t dir; /**< Pdo direction. */
--- a/master/ioctl.h	Wed Jun 04 10:41:50 2008 +0000
+++ b/master/ioctl.h	Wed Jun 04 13:17:15 2008 +0000
@@ -51,6 +51,7 @@
     EC_IOCTL_PDO_ENTRY,
 	EC_IOCTL_DOMAIN_COUNT,
 	EC_IOCTL_DOMAIN,
+	EC_IOCTL_DOMAIN_FMMU,
 	EC_IOCTL_DATA
 };
 
@@ -135,6 +136,7 @@
 	uint32_t logical_base_address;
 	uint16_t working_counter;
 	uint16_t expected_working_counter;
+    unsigned int fmmu_count;
 } ec_ioctl_domain_t;
 
 /*****************************************************************************/
@@ -142,6 +144,21 @@
 typedef struct {
     // inputs
 	unsigned int domain_index;
+	unsigned int fmmu_index;
+
+    // outputs
+    uint16_t slave_config_alias;
+    uint16_t slave_config_position;
+    uint8_t fmmu_dir;
+	uint32_t logical_address;
+    unsigned int data_size;
+} ec_ioctl_domain_fmmu_t;
+
+/*****************************************************************************/
+
+typedef struct {
+    // inputs
+	unsigned int domain_index;
     unsigned int data_size;
     unsigned char *target;
 } ec_ioctl_data_t;
--- a/tools/Master.cpp	Wed Jun 04 10:41:50 2008 +0000
+++ b/tools/Master.cpp	Wed Jun 04 13:17:15 2008 +0000
@@ -166,17 +166,16 @@
     
     getDomain(&domain, domainIndex);
 
+    if (!domain.data_size)
+        return;
+
     processData = new unsigned char[domain.data_size];
 
-    data.domain_index = domainIndex;
-    data.data_size = domain.data_size;
-    data.target = processData;
-
-    if (ioctl(fd, EC_IOCTL_DATA, &data) < 0) {
-        stringstream err;
-        err << "Failed to get domain data: " << strerror(errno);
+    try {
+        getData(&data, domainIndex, domain.data_size, processData);
+    } catch (MasterException &e) {
         delete [] processData;
-        throw MasterException(err.str());
+        throw e;
     }
 
     for (i = 0; i < data.data_size; i++)
@@ -190,18 +189,64 @@
 
 void Master::showDomain(unsigned int domainIndex)
 {
-    ec_ioctl_domain_t data;
+    ec_ioctl_domain_t domain;
+    unsigned char *processData;
+    ec_ioctl_data_t data;
+    unsigned int i, j;
+    ec_ioctl_domain_fmmu_t fmmu;
+    unsigned int dataOffset;
     
-    getDomain(&data, domainIndex);
+    getDomain(&domain, domainIndex);
 
 	cout << "Domain" << domainIndex << ":"
 		<< " LogBaseAddr 0x"
-		<< hex << setfill('0') << setw(8) << data.logical_base_address
-		<< ", Size " << dec << data.data_size
+		<< hex << setfill('0') << setw(8) << domain.logical_base_address
+		<< ", Size " << dec << setfill(' ') << setw(3) << domain.data_size
 		<< ", WorkingCounter "
-		<< dec << data.working_counter
-		<< " of " << data.expected_working_counter
-		<< endl;
+		<< dec << setw(3) << domain.working_counter
+		<< " of " << setw(3) << domain.expected_working_counter << endl;
+
+    if (!domain.data_size)
+        return;
+
+    processData = new unsigned char[domain.data_size];
+
+    try {
+        getData(&data, domainIndex, domain.data_size, processData);
+    } catch (MasterException &e) {
+        delete [] processData;
+        throw e;
+    }
+
+    for (i = 0; i < domain.fmmu_count; i++) {
+        getFmmu(&fmmu, domainIndex, i);
+
+        cout << "  " << (fmmu.fmmu_dir ? "Inputs" : "Outputs")
+            << " from slave config " << fmmu.slave_config_alias
+            << ":" << fmmu.slave_config_position
+            << ", LogAddr 0x" 
+            << hex << setfill('0') << setw(8) << fmmu.logical_address
+            << ", Size "
+            << dec << setfill(' ') << setw(3) << fmmu.data_size
+            << endl;
+
+        dataOffset = fmmu.logical_address - domain.logical_base_address;
+        if (dataOffset + fmmu.data_size > domain.data_size) {
+            stringstream err;
+            err << "Fmmu information corrupted!";
+            delete [] processData;
+            throw MasterException(err.str());
+        }
+
+        cout << "    " << hex << setfill('0');
+        for (j = 0; j < fmmu.data_size; j++) {
+            cout << setw(2)
+                << (unsigned int) *(processData + dataOffset + j) << " ";
+        }
+        cout << endl;
+    }
+
+    delete [] processData;
 }
 
 /****************************************************************************/
@@ -401,6 +446,22 @@
 
 /****************************************************************************/
 
+void Master::getData(ec_ioctl_data_t *data, unsigned int domainIndex,
+        unsigned int dataSize, unsigned char *mem)
+{
+    data->domain_index = domainIndex;
+    data->data_size = dataSize;
+    data->target = mem;
+
+    if (ioctl(fd, EC_IOCTL_DATA, data) < 0) {
+        stringstream err;
+        err << "Failed to get domain data: " << strerror(errno);
+        throw MasterException(err.str());
+    }
+}
+
+/****************************************************************************/
+
 void Master::getSlave(ec_ioctl_slave_t *slave, uint16_t slaveIndex)
 {
     slave->position = slaveIndex;
@@ -418,6 +479,30 @@
 
 /****************************************************************************/
 
+void Master::getFmmu(
+        ec_ioctl_domain_fmmu_t *fmmu,
+        unsigned int domainIndex,
+        unsigned int fmmuIndex
+        )
+{
+    fmmu->domain_index = domainIndex;
+    fmmu->fmmu_index = fmmuIndex;
+
+    if (ioctl(fd, EC_IOCTL_DOMAIN_FMMU, fmmu)) {
+        stringstream err;
+        err << "Failed to get domain FMMU: ";
+        if (errno == EINVAL)
+            err << "Either domain " << domainIndex << " does not exist, "
+                << "or it contains less than " << (unsigned int) fmmuIndex + 1
+                << " FMMus!";
+        else
+            err << strerror(errno);
+        throw MasterException(err.str());
+    }
+}
+
+/****************************************************************************/
+
 void Master::getSync(
         ec_ioctl_sync_t *sync,
         uint16_t slaveIndex,
@@ -432,7 +517,7 @@
         err << "Failed to get sync manager: ";
         if (errno == EINVAL)
             err << "Either slave " << slaveIndex << " does not exist, "
-                << "or contains less than " << (unsigned int) syncIndex + 1
+                << "or it contains less than " << (unsigned int) syncIndex + 1
                 << " sync managers!";
         else
             err << strerror(errno);
@@ -458,7 +543,7 @@
         err << "Failed to get Pdo: ";
         if (errno == EINVAL)
             err << "Either slave " << slaveIndex << " does not exist, "
-                << "or contains less than " << (unsigned int) syncIndex + 1
+                << "or it contains less than " << (unsigned int) syncIndex + 1
                 << " sync managers, or sync manager "
                 << (unsigned int) syncIndex << " contains less than "
                 << pdoPos + 1 << " Pdos!" << endl;
@@ -488,7 +573,7 @@
         err << "Failed to get Pdo entry: ";
         if (errno == EINVAL)
             err << "Either slave " << slaveIndex << " does not exist, "
-                << "or contains less than " << (unsigned int) syncIndex + 1
+                << "or it contains less than " << (unsigned int) syncIndex + 1
                 << " sync managers, or sync manager "
                 << (unsigned int) syncIndex << " contains less than "
                 << pdoPos + 1 << " Pdos, or the Pdo at position " << pdoPos
--- a/tools/Master.h	Wed Jun 04 10:41:50 2008 +0000
+++ b/tools/Master.h	Wed Jun 04 13:17:15 2008 +0000
@@ -55,6 +55,9 @@
         unsigned int slaveCount();
         void slaveSyncs(uint16_t);
         void getDomain(ec_ioctl_domain_t *, unsigned int);
+        void getFmmu(ec_ioctl_domain_fmmu_t *, unsigned int, unsigned int);
+        void getData(ec_ioctl_data_t *, unsigned int, unsigned int,
+                unsigned char *);
         void getSlave(ec_ioctl_slave_t *, uint16_t);
         void getSync(ec_ioctl_sync_t *, uint16_t, uint8_t);
         void getPdo(ec_ioctl_pdo_t *, uint16_t, uint8_t, uint8_t);