master/master.c
branchstable-1.3
changeset 1745 07fd94c5119d
parent 1744 7bc131b92039
child 1746 72e7507b3f1b
--- a/master/master.c	Fri Aug 10 15:27:08 2007 +0000
+++ b/master/master.c	Thu Sep 13 11:08:46 2007 +0000
@@ -50,7 +50,9 @@
 #include "slave.h"
 #include "device.h"
 #include "datagram.h"
+#ifdef EC_EOE
 #include "ethernet.h"
+#endif
 
 /*****************************************************************************/
 
@@ -58,9 +60,10 @@
 void ec_master_sync_io(ec_master_t *);
 static int ec_master_idle_thread(ec_master_t *);
 static int ec_master_operation_thread(ec_master_t *);
+#ifdef EC_EOE
 void ec_master_eoe_run(unsigned long);
+#endif
 void ec_master_check_sdo(unsigned long);
-int ec_master_measure_bus_time(ec_master_t *);
 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *,
                                   const char *, size_t);
@@ -139,15 +142,17 @@
 
     master->stats.timeouts = 0;
     master->stats.corrupted = 0;
-    master->stats.skipped = 0;
     master->stats.unmatched = 0;
     master->stats.output_jiffies = 0;
 
     for (i = 0; i < HZ; i++) {
         master->idle_cycle_times[i] = 0;
+#ifdef EC_EOE
         master->eoe_cycle_times[i] = 0;
+#endif
     }
     master->idle_cycle_time_pos = 0;
+#ifdef EC_EOE
     master->eoe_cycle_time_pos = 0;
 
     init_timer(&master->eoe_timer);
@@ -155,6 +160,7 @@
     master->eoe_timer.data = (unsigned long) master;
     master->eoe_running = 0;
     INIT_LIST_HEAD(&master->eoe_handlers);
+#endif
 
     master->internal_lock = SPIN_LOCK_UNLOCKED;
     master->request_cb = NULL;
@@ -178,6 +184,7 @@
 
     // init state machine datagram
     ec_datagram_init(&master->fsm_datagram);
+    snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
     if (ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE)) {
         EC_ERR("Failed to allocate FSM datagram.\n");
         goto out_clear_backup;
@@ -228,7 +235,9 @@
         ec_master_t *master /**< EtherCAT master */
         )
 {
+#ifdef EC_EOE
     ec_master_clear_eoe_handlers(master);
+#endif
     ec_master_destroy_slaves(master);
     ec_master_destroy_domains(master);
     ec_fsm_master_clear(&master->fsm);
@@ -243,6 +252,7 @@
 
 /*****************************************************************************/
 
+#ifdef EC_EOE
 /**
  * Clear and free all EoE handlers.
  */
@@ -259,6 +269,7 @@
         kfree(eoe);
     }
 }
+#endif
 
 /*****************************************************************************/
 
@@ -394,7 +405,9 @@
 {
     master->mode = EC_MASTER_MODE_ORPHANED;
     
+#ifdef EC_EOE
     ec_master_eoe_stop(master);
+#endif
     ec_master_thread_stop(master);
     ec_master_destroy_slaves(master);
 }
@@ -408,7 +421,9 @@
 int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */)
 {
     ec_slave_t *slave;
+#ifdef EC_EOE
     ec_eoe_t *eoe;
+#endif
 
     down(&master->config_sem);
     master->allow_config = 0; // temporarily disable slave configuration
@@ -442,11 +457,13 @@
     list_for_each_entry(slave, &master->slaves, list) {
         ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
     }
+#ifdef EC_EOE
     // ... but set EoE slaves to OP
     list_for_each_entry(eoe, &master->eoe_handlers, list) {
         if (ec_eoe_is_open(eoe))
             ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
     }
+#endif
 
     if (master->debug_level)
         EC_DBG("Switching to operation mode.\n");
@@ -475,11 +492,15 @@
                                     /**< EtherCAT master */)
 {
     ec_slave_t *slave;
+#ifdef EC_EOE
     ec_eoe_t *eoe;
+#endif
 
     master->mode = EC_MASTER_MODE_IDLE;
 
+#ifdef EC_EOE
     ec_master_eoe_stop(master);
+#endif
     ec_master_thread_stop(master);
     
     master->request_cb = ec_master_request_cb;
@@ -491,17 +512,21 @@
         ec_slave_reset(slave);
         ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
     }
+#ifdef EC_EOE
     // ... but leave EoE slaves in OP
     list_for_each_entry(eoe, &master->eoe_handlers, list) {
         if (ec_eoe_is_open(eoe))
             ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
     }
+#endif
 
     ec_master_destroy_domains(master);
     
     if (ec_master_thread_start(master, ec_master_idle_thread))
         EC_WARN("Failed to restart master thread!\n");
+#ifdef EC_EOE
     ec_master_eoe_start(master);
+#endif
 
     master->allow_scan = 1;
     master->allow_config = 1;
@@ -522,10 +547,9 @@
     // check, if the datagram is already queued
     list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
         if (queued_datagram == datagram) {
-            master->stats.skipped++;
+            datagram->skip_count++;
             if (master->debug_level)
                 EC_DBG("skipping datagram %x.\n", (unsigned int) datagram);
-            ec_master_output_stats(master);
             datagram->state = EC_DATAGRAM_QUEUED;
             return;
         }
@@ -592,7 +616,7 @@
             // EtherCAT datagram header
             EC_WRITE_U8 (cur_data,     datagram->type);
             EC_WRITE_U8 (cur_data + 1, datagram->index);
-            EC_WRITE_U32(cur_data + 2, datagram->address.logical);
+            memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN);
             EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
             EC_WRITE_U16(cur_data + 8, 0x0000);
             follows_word = cur_data + 6;
@@ -772,11 +796,6 @@
                     master->stats.corrupted == 1 ? "" : "s");
             master->stats.corrupted = 0;
         }
-        if (master->stats.skipped) {
-            EC_WARN("%i datagram%s SKIPPED!\n", master->stats.skipped,
-                    master->stats.skipped == 1 ? "" : "s");
-            master->stats.skipped = 0;
-        }
         if (master->stats.unmatched) {
             EC_WARN("%i datagram%s UNMATCHED!\n", master->stats.unmatched,
                     master->stats.unmatched == 1 ? "" : "s");
@@ -800,6 +819,7 @@
 
     while (!signal_pending(current)) {
         cycles_start = get_cycles();
+        ec_datagram_output_stats(&master->fsm_datagram);
 
         if (ec_fsm_master_running(&master->fsm)) { // datagram on the way
             // receive
@@ -856,6 +876,7 @@
     allow_signal(SIGTERM);
 
     while (!signal_pending(current)) {
+        ec_datagram_output_stats(&master->fsm_datagram);
         if (master->injection_seq_rt != master->injection_seq_fsm ||
                 master->fsm_datagram.state == EC_DATAGRAM_SENT ||
                 master->fsm_datagram.state == EC_DATAGRAM_QUEUED)
@@ -941,7 +962,9 @@
                        )
 {
     off_t off = 0;
+#ifdef EC_EOE
     ec_eoe_t *eoe;
+#endif
     uint32_t cur, sum, min, max, pos, i;
 
     off += sprintf(buffer + off, "\nMode: ");
@@ -959,6 +982,10 @@
 
     off += sprintf(buffer + off, "\nSlaves: %i\n",
                    master->slave_count);
+    off += sprintf(buffer + off, "Status: %s\n",
+                   master->fsm.tainted ? "TAINTED" : "sane");
+    off += sprintf(buffer + off, "PDO slaves: %s\n",
+                   master->pdo_slaves_offline ? "INCOMPLETE" : "online");
 
     off += sprintf(buffer + off, "\nDevices:\n");
     
@@ -986,6 +1013,7 @@
     off += sprintf(buffer + off, "  Idle cycle: %u / %u.%u / %u\n",
                    min, sum / HZ, (sum * 100 / HZ) % 100, max);
 
+#ifdef EC_EOE
     sum = 0;
     min = 0xFFFFFFFF;
     max = 0;
@@ -1006,6 +1034,7 @@
                        eoe->dev->name, eoe->rx_rate, eoe->tx_rate,
                        ((eoe->rx_rate + eoe->tx_rate) / 8 + 512) / 1024);
     }
+#endif
 
     off += sprintf(buffer + off, "\n");
 
@@ -1075,6 +1104,7 @@
 
 /*****************************************************************************/
 
+#ifdef EC_EOE
 /**
    Starts Ethernet-over-EtherCAT processing on demand.
 */
@@ -1141,11 +1171,11 @@
     if (none_open)
         goto queue_timer;
 
+    // receive datagrams
     if (master->request_cb(master->cb_data)) goto queue_timer;
-
-    // receive datagrams
     cycles_start = get_cycles();
     ecrt_master_receive(master);
+    master->release_cb(master->cb_data);
 
     // actual EoE processing
     list_for_each_entry(eoe, &master->eoe_handlers, list) {
@@ -1153,11 +1183,16 @@
     }
 
     // send datagrams
+    if (master->request_cb(master->cb_data)) {
+        goto queue_timer;
+    }
+    list_for_each_entry(eoe, &master->eoe_handlers, list) {
+        ec_eoe_queue(eoe);
+    }
     ecrt_master_send(master);
+    master->release_cb(master->cb_data);
     cycles_end = get_cycles();
 
-    master->release_cb(master->cb_data);
-
     master->eoe_cycle_times[master->eoe_cycle_time_pos]
         = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;
     master->eoe_cycle_time_pos++;
@@ -1166,72 +1201,10 @@
  queue_timer:
     restart_jiffies = HZ / EC_EOE_FREQUENCY;
     if (!restart_jiffies) restart_jiffies = 1;
-    master->eoe_timer.expires += restart_jiffies;
+    master->eoe_timer.expires = jiffies + restart_jiffies;
     add_timer(&master->eoe_timer);
 }
-
-/*****************************************************************************/
-
-/**
-   Measures the time, a frame is on the bus.
-   \return 0 in case of success, else < 0
-*/
-
-int ec_master_measure_bus_time(ec_master_t *master)
-{
-    ec_datagram_t datagram;
-    uint32_t cur, sum, min, max, i;
-
-    ec_datagram_init(&datagram);
-
-    if (ec_datagram_brd(&datagram, 0x0130, 2)) {
-        EC_ERR("Failed to allocate datagram for bus time measuring.\n");
-        ec_datagram_clear(&datagram);
-        return -1;
-    }
-
-    ecrt_master_receive(master);
-
-    sum = 0;
-    min = 0xFFFFFFFF;
-    max = 0;
-
-    for (i = 0; i < 100; i++) {
-        ec_master_queue_datagram(master, &datagram);
-        ecrt_master_send(master);
-
-        while (1) {
-            ecrt_master_receive(master);
-
-            if (datagram.state == EC_DATAGRAM_RECEIVED) {
-                break;
-            }
-            else if (datagram.state == EC_DATAGRAM_ERROR) {
-                EC_WARN("Failed to measure bus time.\n");
-                goto error;
-            }
-            else if (datagram.state == EC_DATAGRAM_TIMED_OUT) {
-                EC_WARN("Timeout while measuring bus time.\n");
-                goto error;
-            }
-        }
-
-        cur = (unsigned int) (datagram.cycles_received
-                              - datagram.cycles_sent) * 1000 / cpu_khz;
-        sum += cur;
-        if (cur > max) max = cur;
-        if (cur < min) min = cur;
-    }
-
-    EC_DBG("Bus time is (min/avg/max) %u / %u.%u / %u us.\n",
-           min, sum / 100, sum % 100, max);
-    ec_datagram_clear(&datagram);
-    return 0;
-
-  error:
-    ec_datagram_clear(&datagram);
-    return -1;
-}
+#endif
 
 /*****************************************************************************/
 
@@ -1431,7 +1404,9 @@
     }
     
     // restart EoE process and master thread with new locking
+#ifdef EC_EOE
     ec_master_eoe_stop(master);
+#endif
     ec_master_thread_stop(master);
 
     ec_master_prepare(master); // prepare asynchronous IO
@@ -1449,7 +1424,9 @@
         EC_ERR("Failed to start master thread!\n");
         return -1;
     }
+#ifdef EC_EOE
     ec_master_eoe_start(master);
+#endif
     return 0;
 }