Master information, timing.
authorFlorian Pose <fp@igh-essen.com>
Fri, 04 Aug 2006 09:53:14 +0000
changeset 334 2be97e069602
parent 333 2b15335f9f35
child 335 1e37c856b74e
Master information, timing.
master/master.c
master/master.h
--- a/master/master.c	Fri Aug 04 09:35:32 2006 +0000
+++ b/master/master.c	Fri Aug 04 09:53:14 2006 +0000
@@ -65,14 +65,12 @@
 
 /** \cond */
 
-EC_SYSFS_READ_ATTR(slave_count);
-EC_SYSFS_READ_ATTR(mode);
+EC_SYSFS_READ_ATTR(info);
 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable);
 EC_SYSFS_READ_WRITE_ATTR(debug_level);
 
 static struct attribute *ec_def_attrs[] = {
-    &attr_slave_count,
-    &attr_mode,
+    &attr_info,
     &attr_eeprom_write_enable,
     &attr_debug_level,
     NULL,
@@ -122,6 +120,8 @@
     master->internal_lock = SPIN_LOCK_UNLOCKED;
     master->eoe_running = 0;
     master->eoe_checked = 0;
+    master->idle_cycle_time = 0;
+    master->eoe_cycle_time = 0;
 
     // create workqueue
     if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) {
@@ -606,20 +606,25 @@
 void ec_master_idle_run(void *data /**< master pointer */)
 {
     ec_master_t *master = (ec_master_t *) data;
+    cycles_t start, end;
 
     // aquire master lock
     spin_lock_bh(&master->internal_lock);
 
+    start = get_cycles();
     ecrt_master_receive(master);
 
     // execute master state machine
     ec_fsm_execute(&master->fsm);
 
     ecrt_master_send(master);
+    end = get_cycles();
 
     // release master lock
     spin_unlock_bh(&master->internal_lock);
 
+    master->idle_cycle_time = (u32) (end - start) * 1000 / cpu_khz;
+
     if (master->mode == EC_MASTER_MODE_IDLE)
         queue_delayed_work(master->workqueue, &master->idle_work, 1);
 }
@@ -686,6 +691,43 @@
 /*****************************************************************************/
 
 /**
+   Formats master information for SysFS read access.
+   \return number of bytes written
+*/
+
+ssize_t ec_master_info(ec_master_t *master, /**< EtherCAT master */
+                       char *buffer /**< memory to store data */
+                       )
+{
+    off_t off = 0;
+
+    off += sprintf(buffer + off, "\nMode: ");
+    switch (master->mode) {
+        case EC_MASTER_MODE_ORPHANED:
+            off += sprintf(buffer + off, "ORPHANED");
+        case EC_MASTER_MODE_IDLE:
+            off += sprintf(buffer + off, "IDLE");
+        case EC_MASTER_MODE_OPERATION:
+            off += sprintf(buffer + off, "OPERATION");
+    }
+
+    off += sprintf(buffer + off, "\n\nNumber of slaves: %i\n",
+                   master->slave_count);
+
+    off += sprintf(buffer + off, "\nTiming [us]:\n");
+    off += sprintf(buffer + off, "  Idle cycle time: %u\n",
+                   master->idle_cycle_time);
+    off += sprintf(buffer + off, "  EoE cycle time: %u\n",
+                   master->eoe_cycle_time);
+
+    off += sprintf(buffer + off, "\n");
+
+    return off;
+}
+
+/*****************************************************************************/
+
+/**
    Formats attribute data for SysFS read access.
    \return number of bytes to read
 */
@@ -697,18 +739,8 @@
 {
     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
 
-    if (attr == &attr_slave_count) {
-        return sprintf(buffer, "%i\n", master->slave_count);
-    }
-    else if (attr == &attr_mode) {
-        switch (master->mode) {
-            case EC_MASTER_MODE_ORPHANED:
-                return sprintf(buffer, "ORPHANED\n");
-            case EC_MASTER_MODE_IDLE:
-                return sprintf(buffer, "IDLE\n");
-            case EC_MASTER_MODE_OPERATION:
-                return sprintf(buffer, "OPERATION\n");
-        }
+    if (attr == &attr_info) {
+        return ec_master_info(master, buffer);
     }
     else if (attr == &attr_debug_level) {
         return sprintf(buffer, "%i\n", master->debug_level);
@@ -884,6 +916,7 @@
     ec_master_t *master = (ec_master_t *) data;
     ec_eoe_t *eoe;
     unsigned int active = 0;
+    cycles_t start, end;
 
     list_for_each_entry(eoe, &master->eoe_handlers, list) {
         if (ec_eoe_active(eoe)) active++;
@@ -903,11 +936,15 @@
         goto queue_timer;
 
     // actual EoE stuff
+    start = get_cycles();
     ecrt_master_receive(master);
+
     list_for_each_entry(eoe, &master->eoe_handlers, list) {
         ec_eoe_run(eoe);
     }
+
     ecrt_master_send(master);
+    end = get_cycles();
 
     // release lock...
     if (master->mode == EC_MASTER_MODE_OPERATION) {
@@ -917,6 +954,8 @@
         spin_unlock(&master->internal_lock);
     }
 
+    master->eoe_cycle_time = (u32) (end - start) * 1000 / cpu_khz;
+
  queue_timer:
     master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY;
     add_timer(&master->eoe_timer);
--- a/master/master.h	Fri Aug 04 09:35:32 2006 +0000
+++ b/master/master.h	Fri Aug 04 09:53:14 2006 +0000
@@ -97,11 +97,14 @@
 
     struct kobject kobj; /**< kobject */
 
+    ec_device_t *device; /**< EtherCAT device */
+
+    ec_fsm_t fsm; /**< master state machine */
+    ec_master_mode_t mode; /**< master mode */
+
     struct list_head slaves; /**< list of slaves on the bus */
     unsigned int slave_count; /**< number of slaves on the bus */
 
-    ec_device_t *device; /**< EtherCAT device */
-
     struct list_head datagram_queue; /**< datagram queue */
     uint8_t datagram_index; /**< current datagram index */
 
@@ -112,14 +115,15 @@
 
     struct workqueue_struct *workqueue; /**< master workqueue */
     struct work_struct idle_work; /**< free run work object */
-    ec_fsm_t fsm; /**< master state machine */
-    ec_master_mode_t mode; /**< master mode */
+    uint32_t idle_cycle_time; /**< Idle cycle time */
 
     struct timer_list eoe_timer; /**< EoE timer object */
+    uint32_t eoe_cycle_time; /**< EoE cycle time */
     unsigned int eoe_running; /**< non-zero, if EoE processing is active. */
     unsigned int eoe_checked; /**< non-zero, if EoE processing is not
                                  necessary. */
     struct list_head eoe_handlers; /**< Ethernet-over-EtherCAT handlers */
+
     spinlock_t internal_lock; /**< spinlock used in idle mode */
     int (*request_cb)(void *); /**< lock request callback */
     void (*release_cb)(void *); /**< lock release callback */