# HG changeset patch # User Florian Pose # Date 1213870738 0 # Node ID d2527675cdd501de10499a19d87b67a6e1d20abf # Parent 2881a83d084f3da3aad3306996ac4ca308766bbf Disable use of CPU timestamp counter by default. diff -r 2881a83d084f -r d2527675cdd5 TODO --- 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: diff -r 2881a83d084f -r d2527675cdd5 configure.ac --- 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 diff -r 2881a83d084f -r d2527675cdd5 master/datagram.c --- 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; diff -r 2881a83d084f -r d2527675cdd5 master/datagram.h --- 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. */ diff -r 2881a83d084f -r d2527675cdd5 master/device.c --- 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); diff -r 2881a83d084f -r d2527675cdd5 master/device.h --- 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 diff -r 2881a83d084f -r d2527675cdd5 master/master.c --- 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 + ); + } } }