Disable use of CPU timestamp counter by default.
authorFlorian Pose <fp@igh-essen.com>
Thu, 19 Jun 2008 10:18:58 +0000
changeset 1040 d2527675cdd5
parent 1039 2881a83d084f
child 1041 42c9ac58d9ce
Disable use of CPU timestamp counter by default.
TODO
configure.ac
master/datagram.c
master/datagram.h
master/device.c
master/device.h
master/master.c
--- a/TODO	Thu Jun 19 10:18:18 2008 +0000
+++ b/TODO	Thu Jun 19 10:18:58 2008 +0000
@@ -8,14 +8,11 @@
 
 Version 1.4.0:
 
-* Remove get_cycles() calls and references to cpu_khz to increase
-  portability.
 * Make scanning and configuration run parallel (each).
 * Adapt remaining examples.
 * READMEs for examples.
 * Update documentation.
 * Attach Pdo names from SII or Coe dictioary to Pdos read via CoE.
-* Add a -n (numeric) switch to ethercat command.
 * Remove Eoe cycles and Idle cycles.
 
 Future issues:
@@ -33,6 +30,7 @@
 * Wait for bus scanning, even when link is not up at ecrt_request_master()?
 * Redundancy with 2 network adapters.
 * Interface/buffers for asynchronous domain IO.
+* Add a -n (numeric) switch to ethercat command.
 
 Smaller issues:
 
--- a/configure.ac	Thu Jun 19 10:18:18 2008 +0000
+++ b/configure.ac	Thu Jun 19 10:18:58 2008 +0000
@@ -490,6 +490,30 @@
 AC_SUBST(ENABLE_EOE,[$eoe])
 
 #------------------------------------------------------------------------------
+# CPU timestamp counter support
+#------------------------------------------------------------------------------
+
+AC_ARG_ENABLE([cycles],
+    AS_HELP_STRING([--enable-cycles],
+                   [Use CPU timestamp counter (default: no)]),
+    [
+        case "${enableval}" in
+            yes) cycles=1
+                ;;
+            no) cycles=0
+                ;;
+            *) AC_MSG_ERROR([Invalid value for --enable-cycles])
+                ;;
+        esac
+    ],
+    [cycles=0]
+)
+
+if test "x${cycles}" = "x1"; then
+    AC_DEFINE([EC_HAVE_CYCLES], [1], [Use CPU timestamp counter])
+fi
+
+#------------------------------------------------------------------------------
 
 AC_CONFIG_FILES([
         Doxyfile
--- a/master/datagram.c	Thu Jun 19 10:18:18 2008 +0000
+++ b/master/datagram.c	Thu Jun 19 10:18:58 2008 +0000
@@ -101,9 +101,13 @@
     datagram->index = 0x00;
     datagram->working_counter = 0x0000;
     datagram->state = EC_DATAGRAM_INIT;
+#ifdef EC_HAVE_CYCLES
     datagram->cycles_sent = 0;
+#endif
     datagram->jiffies_sent = 0;
+#ifdef EC_HAVE_CYCLES
     datagram->cycles_received = 0;
+#endif
     datagram->jiffies_received = 0;
     datagram->skip_count = 0;
     datagram->stats_output_jiffies = 0;
--- a/master/datagram.h	Thu Jun 19 10:18:18 2008 +0000
+++ b/master/datagram.h	Thu Jun 19 10:18:58 2008 +0000
@@ -106,9 +106,13 @@
     uint8_t index; /**< Index (set by master). */
     uint16_t working_counter; /**< Working counter. */
     ec_datagram_state_t state; /**< State. */
+#ifdef EC_HAVE_CYCLES
     cycles_t cycles_sent; /**< Time, when the datagram was sent. */
+#endif
     unsigned long jiffies_sent; /**< Jiffies, when the datagram was sent. */
+#ifdef EC_HAVE_CYCLES
     cycles_t cycles_received; /**< Time, when the datagram was received. */
+#endif
     unsigned long jiffies_received; /**< Jiffies, when the datagram was
                                       received. */
     unsigned int skip_count; /**< Number of requeues when not yet received. */
--- a/master/device.c	Thu Jun 19 10:18:18 2008 +0000
+++ b/master/device.c	Thu Jun 19 10:18:58 2008 +0000
@@ -384,7 +384,9 @@
         ec_device_t *device /**< EtherCAT device */
         )
 {
+#ifdef EC_HAVE_CYCLES
     device->cycles_poll = get_cycles();
+#endif
     device->jiffies_poll = jiffies;
 #ifdef EC_DEBUG_RING
     do_gettimeofday(&device->timeval_poll);
--- a/master/device.h	Thu Jun 19 10:18:18 2008 +0000
+++ b/master/device.h	Thu Jun 19 10:18:58 2008 +0000
@@ -94,7 +94,9 @@
     uint8_t link_state; /**< device link state */
     struct sk_buff *tx_skb[EC_TX_RING_SIZE]; /**< transmit skb ring */
     unsigned int tx_ring_index; /**< last ring entry used to transmit */
+#ifdef EC_HAVE_CYCLES
     cycles_t cycles_poll; /**< cycles of last poll */
+#endif
 #ifdef EC_DEBUG_RING
     struct timeval timeval_poll;
 #endif
--- a/master/master.c	Thu Jun 19 10:18:18 2008 +0000
+++ b/master/master.c	Thu Jun 19 10:18:58 2008 +0000
@@ -342,6 +342,8 @@
         ec_master_t *master /**< EtherCAT master */
         )
 {
+    unsigned long sleep_jiffies;
+    
     if (!master->thread_id) {
         EC_WARN("ec_master_thread_stop: Already finished!\n");
         return;
@@ -357,9 +359,8 @@
     if (master->fsm_datagram.state != EC_DATAGRAM_SENT) return;
     
     // wait for FSM datagram
-    while (get_cycles() - master->fsm_datagram.cycles_sent
-            < (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000))
-        schedule();
+    sleep_jiffies = max(HZ / 100, 1); // 10 ms, at least 1 jiffy
+    schedule_timeout(sleep_jiffies);
 }
 
 /*****************************************************************************/
@@ -572,12 +573,16 @@
     size_t datagram_size;
     uint8_t *frame_data, *cur_data;
     void *follows_word;
+#ifdef EC_HAVE_CYCLES
     cycles_t cycles_start, cycles_sent, cycles_end;
+#endif
     unsigned long jiffies_sent;
     unsigned int frame_count, more_datagrams_waiting;
     struct list_head sent_datagrams;
 
+#ifdef EC_HAVE_CYCLES
     cycles_start = get_cycles();
+#endif
     frame_count = 0;
     INIT_LIST_HEAD(&sent_datagrams);
 
@@ -650,13 +655,17 @@
 
         // send frame
         ec_device_send(&master->main_device, cur_data - frame_data);
+#ifdef EC_HAVE_CYCLES
         cycles_sent = get_cycles();
+#endif
         jiffies_sent = jiffies;
 
         // set datagram states and sending timestamps
         list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) {
             datagram->state = EC_DATAGRAM_SENT;
+#ifdef EC_HAVE_CYCLES
             datagram->cycles_sent = cycles_sent;
+#endif
             datagram->jiffies_sent = jiffies_sent;
             list_del_init(&datagram->sent); // empty list of sent datagrams
         }
@@ -665,12 +674,14 @@
     }
     while (more_datagrams_waiting);
 
+#ifdef EC_HAVE_CYCLES
     if (unlikely(master->debug_level > 1)) {
         cycles_end = get_cycles();
         EC_DBG("ec_master_send_datagrams sent %u frames in %uus.\n",
                frame_count,
                (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
     }
+#endif
 }
 
 /*****************************************************************************/
@@ -767,7 +778,9 @@
 
         // dequeue the received datagram
         datagram->state = EC_DATAGRAM_RECEIVED;
+#ifdef EC_HAVE_CYCLES
         datagram->cycles_received = master->main_device.cycles_poll;
+#endif
         datagram->jiffies_received = master->main_device.jiffies_poll;
         list_del_init(&datagram->queue);
     }
@@ -1260,20 +1273,34 @@
 void ecrt_master_receive(ec_master_t *master)
 {
     ec_datagram_t *datagram, *next;
+#ifdef EC_HAVE_CYCLES
     cycles_t cycles_timeout;
+#else
+    unsigned long diff_ms, timeout_ms;
+#endif
     unsigned int frames_timed_out = 0;
 
     // receive datagrams
     ec_device_poll(&master->main_device);
 
+#ifdef EC_HAVE_CYCLES
     cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
+#else
+    timeout_ms = max(EC_IO_TIMEOUT /* us */ / 1000, 2);
+#endif
 
     // dequeue all datagrams that timed out
     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
         if (datagram->state != EC_DATAGRAM_SENT) continue;
 
+#ifdef EC_HAVE_CYCLES
         if (master->main_device.cycles_poll - datagram->cycles_sent
             > cycles_timeout) {
+#else
+        diff_ms = (master->main_device.jiffies_poll
+                - datagram->jiffies_sent) * 1000 / HZ;
+        if (diff_ms > timeout_ms) {
+#endif
             frames_timed_out = 1;
             list_del_init(&datagram->queue);
             datagram->state = EC_DATAGRAM_TIMED_OUT;
@@ -1283,8 +1310,14 @@
             if (unlikely(master->debug_level > 0)) {
                 EC_DBG("TIMED OUT datagram %08x, index %02X waited %u us.\n",
                         (unsigned int) datagram, datagram->index,
+#ifdef EC_HAVE_CYCLES
                         (unsigned int) (master->main_device.cycles_poll
-                            - datagram->cycles_sent) * 1000 / cpu_khz);
+                            - datagram->cycles_sent) * 1000 / cpu_khz
+#else
+                        (unsigned int) (diff_ms * 1000)
+#endif
+                        );
+                
             }
         }
     }