Skip to content
Snippets Groups Projects
Commit f8fa069b authored by Florian Pose's avatar Florian Pose
Browse files

Disable use of CPU timestamp counter by default.

parent 42261a46
No related branches found
No related tags found
No related merge requests found
...@@ -8,14 +8,11 @@ $Id$ ...@@ -8,14 +8,11 @@ $Id$
Version 1.4.0: Version 1.4.0:
* Remove get_cycles() calls and references to cpu_khz to increase
portability.
* Make scanning and configuration run parallel (each). * Make scanning and configuration run parallel (each).
* Adapt remaining examples. * Adapt remaining examples.
* READMEs for examples. * READMEs for examples.
* Update documentation. * Update documentation.
* Attach Pdo names from SII or Coe dictioary to Pdos read via CoE. * 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. * Remove Eoe cycles and Idle cycles.
Future issues: Future issues:
...@@ -33,6 +30,7 @@ Future issues: ...@@ -33,6 +30,7 @@ Future issues:
* Wait for bus scanning, even when link is not up at ecrt_request_master()? * Wait for bus scanning, even when link is not up at ecrt_request_master()?
* Redundancy with 2 network adapters. * Redundancy with 2 network adapters.
* Interface/buffers for asynchronous domain IO. * Interface/buffers for asynchronous domain IO.
* Add a -n (numeric) switch to ethercat command.
Smaller issues: Smaller issues:
......
...@@ -489,6 +489,30 @@ fi ...@@ -489,6 +489,30 @@ fi
AM_CONDITIONAL(ENABLE_EOE, test "x$eoe" = "x1") AM_CONDITIONAL(ENABLE_EOE, test "x$eoe" = "x1")
AC_SUBST(ENABLE_EOE,[$eoe]) 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([ AC_CONFIG_FILES([
......
...@@ -101,9 +101,13 @@ void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram. */) ...@@ -101,9 +101,13 @@ void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram. */)
datagram->index = 0x00; datagram->index = 0x00;
datagram->working_counter = 0x0000; datagram->working_counter = 0x0000;
datagram->state = EC_DATAGRAM_INIT; datagram->state = EC_DATAGRAM_INIT;
#ifdef EC_HAVE_CYCLES
datagram->cycles_sent = 0; datagram->cycles_sent = 0;
#endif
datagram->jiffies_sent = 0; datagram->jiffies_sent = 0;
#ifdef EC_HAVE_CYCLES
datagram->cycles_received = 0; datagram->cycles_received = 0;
#endif
datagram->jiffies_received = 0; datagram->jiffies_received = 0;
datagram->skip_count = 0; datagram->skip_count = 0;
datagram->stats_output_jiffies = 0; datagram->stats_output_jiffies = 0;
......
...@@ -106,9 +106,13 @@ typedef struct { ...@@ -106,9 +106,13 @@ typedef struct {
uint8_t index; /**< Index (set by master). */ uint8_t index; /**< Index (set by master). */
uint16_t working_counter; /**< Working counter. */ uint16_t working_counter; /**< Working counter. */
ec_datagram_state_t state; /**< State. */ ec_datagram_state_t state; /**< State. */
#ifdef EC_HAVE_CYCLES
cycles_t cycles_sent; /**< Time, when the datagram was sent. */ cycles_t cycles_sent; /**< Time, when the datagram was sent. */
#endif
unsigned long jiffies_sent; /**< Jiffies, when the datagram was sent. */ unsigned long jiffies_sent; /**< Jiffies, when the datagram was sent. */
#ifdef EC_HAVE_CYCLES
cycles_t cycles_received; /**< Time, when the datagram was received. */ cycles_t cycles_received; /**< Time, when the datagram was received. */
#endif
unsigned long jiffies_received; /**< Jiffies, when the datagram was unsigned long jiffies_received; /**< Jiffies, when the datagram was
received. */ received. */
unsigned int skip_count; /**< Number of requeues when not yet received. */ unsigned int skip_count; /**< Number of requeues when not yet received. */
......
...@@ -384,7 +384,9 @@ void ec_device_poll( ...@@ -384,7 +384,9 @@ void ec_device_poll(
ec_device_t *device /**< EtherCAT device */ ec_device_t *device /**< EtherCAT device */
) )
{ {
#ifdef EC_HAVE_CYCLES
device->cycles_poll = get_cycles(); device->cycles_poll = get_cycles();
#endif
device->jiffies_poll = jiffies; device->jiffies_poll = jiffies;
#ifdef EC_DEBUG_RING #ifdef EC_DEBUG_RING
do_gettimeofday(&device->timeval_poll); do_gettimeofday(&device->timeval_poll);
......
...@@ -94,7 +94,9 @@ struct ec_device ...@@ -94,7 +94,9 @@ struct ec_device
uint8_t link_state; /**< device link state */ uint8_t link_state; /**< device link state */
struct sk_buff *tx_skb[EC_TX_RING_SIZE]; /**< transmit skb ring */ struct sk_buff *tx_skb[EC_TX_RING_SIZE]; /**< transmit skb ring */
unsigned int tx_ring_index; /**< last ring entry used to transmit */ unsigned int tx_ring_index; /**< last ring entry used to transmit */
#ifdef EC_HAVE_CYCLES
cycles_t cycles_poll; /**< cycles of last poll */ cycles_t cycles_poll; /**< cycles of last poll */
#endif
#ifdef EC_DEBUG_RING #ifdef EC_DEBUG_RING
struct timeval timeval_poll; struct timeval timeval_poll;
#endif #endif
......
...@@ -342,6 +342,8 @@ void ec_master_thread_stop( ...@@ -342,6 +342,8 @@ void ec_master_thread_stop(
ec_master_t *master /**< EtherCAT master */ ec_master_t *master /**< EtherCAT master */
) )
{ {
unsigned long sleep_jiffies;
if (!master->thread_id) { if (!master->thread_id) {
EC_WARN("ec_master_thread_stop: Already finished!\n"); EC_WARN("ec_master_thread_stop: Already finished!\n");
return; return;
...@@ -357,9 +359,8 @@ void ec_master_thread_stop( ...@@ -357,9 +359,8 @@ void ec_master_thread_stop(
if (master->fsm_datagram.state != EC_DATAGRAM_SENT) return; if (master->fsm_datagram.state != EC_DATAGRAM_SENT) return;
// wait for FSM datagram // wait for FSM datagram
while (get_cycles() - master->fsm_datagram.cycles_sent sleep_jiffies = max(HZ / 100, 1); // 10 ms, at least 1 jiffy
< (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000)) schedule_timeout(sleep_jiffies);
schedule();
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -572,12 +573,16 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */) ...@@ -572,12 +573,16 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
size_t datagram_size; size_t datagram_size;
uint8_t *frame_data, *cur_data; uint8_t *frame_data, *cur_data;
void *follows_word; void *follows_word;
#ifdef EC_HAVE_CYCLES
cycles_t cycles_start, cycles_sent, cycles_end; cycles_t cycles_start, cycles_sent, cycles_end;
#endif
unsigned long jiffies_sent; unsigned long jiffies_sent;
unsigned int frame_count, more_datagrams_waiting; unsigned int frame_count, more_datagrams_waiting;
struct list_head sent_datagrams; struct list_head sent_datagrams;
#ifdef EC_HAVE_CYCLES
cycles_start = get_cycles(); cycles_start = get_cycles();
#endif
frame_count = 0; frame_count = 0;
INIT_LIST_HEAD(&sent_datagrams); INIT_LIST_HEAD(&sent_datagrams);
...@@ -650,13 +655,17 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */) ...@@ -650,13 +655,17 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
// send frame // send frame
ec_device_send(&master->main_device, cur_data - frame_data); ec_device_send(&master->main_device, cur_data - frame_data);
#ifdef EC_HAVE_CYCLES
cycles_sent = get_cycles(); cycles_sent = get_cycles();
#endif
jiffies_sent = jiffies; jiffies_sent = jiffies;
// set datagram states and sending timestamps // set datagram states and sending timestamps
list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) { list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) {
datagram->state = EC_DATAGRAM_SENT; datagram->state = EC_DATAGRAM_SENT;
#ifdef EC_HAVE_CYCLES
datagram->cycles_sent = cycles_sent; datagram->cycles_sent = cycles_sent;
#endif
datagram->jiffies_sent = jiffies_sent; datagram->jiffies_sent = jiffies_sent;
list_del_init(&datagram->sent); // empty list of sent datagrams list_del_init(&datagram->sent); // empty list of sent datagrams
} }
...@@ -665,12 +674,14 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */) ...@@ -665,12 +674,14 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
} }
while (more_datagrams_waiting); while (more_datagrams_waiting);
#ifdef EC_HAVE_CYCLES
if (unlikely(master->debug_level > 1)) { if (unlikely(master->debug_level > 1)) {
cycles_end = get_cycles(); cycles_end = get_cycles();
EC_DBG("ec_master_send_datagrams sent %u frames in %uus.\n", EC_DBG("ec_master_send_datagrams sent %u frames in %uus.\n",
frame_count, frame_count,
(unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz); (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
} }
#endif
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -767,7 +778,9 @@ void ec_master_receive_datagrams(ec_master_t *master, /**< EtherCAT master */ ...@@ -767,7 +778,9 @@ void ec_master_receive_datagrams(ec_master_t *master, /**< EtherCAT master */
// dequeue the received datagram // dequeue the received datagram
datagram->state = EC_DATAGRAM_RECEIVED; datagram->state = EC_DATAGRAM_RECEIVED;
#ifdef EC_HAVE_CYCLES
datagram->cycles_received = master->main_device.cycles_poll; datagram->cycles_received = master->main_device.cycles_poll;
#endif
datagram->jiffies_received = master->main_device.jiffies_poll; datagram->jiffies_received = master->main_device.jiffies_poll;
list_del_init(&datagram->queue); list_del_init(&datagram->queue);
} }
...@@ -1260,20 +1273,34 @@ void ecrt_master_send(ec_master_t *master) ...@@ -1260,20 +1273,34 @@ void ecrt_master_send(ec_master_t *master)
void ecrt_master_receive(ec_master_t *master) void ecrt_master_receive(ec_master_t *master)
{ {
ec_datagram_t *datagram, *next; ec_datagram_t *datagram, *next;
#ifdef EC_HAVE_CYCLES
cycles_t cycles_timeout; cycles_t cycles_timeout;
#else
unsigned long diff_ms, timeout_ms;
#endif
unsigned int frames_timed_out = 0; unsigned int frames_timed_out = 0;
// receive datagrams // receive datagrams
ec_device_poll(&master->main_device); ec_device_poll(&master->main_device);
#ifdef EC_HAVE_CYCLES
cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000); 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 // dequeue all datagrams that timed out
list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) { list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
if (datagram->state != EC_DATAGRAM_SENT) continue; if (datagram->state != EC_DATAGRAM_SENT) continue;
#ifdef EC_HAVE_CYCLES
if (master->main_device.cycles_poll - datagram->cycles_sent if (master->main_device.cycles_poll - datagram->cycles_sent
> cycles_timeout) { > 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; frames_timed_out = 1;
list_del_init(&datagram->queue); list_del_init(&datagram->queue);
datagram->state = EC_DATAGRAM_TIMED_OUT; datagram->state = EC_DATAGRAM_TIMED_OUT;
...@@ -1283,8 +1310,14 @@ void ecrt_master_receive(ec_master_t *master) ...@@ -1283,8 +1310,14 @@ void ecrt_master_receive(ec_master_t *master)
if (unlikely(master->debug_level > 0)) { if (unlikely(master->debug_level > 0)) {
EC_DBG("TIMED OUT datagram %08x, index %02X waited %u us.\n", EC_DBG("TIMED OUT datagram %08x, index %02X waited %u us.\n",
(unsigned int) datagram, datagram->index, (unsigned int) datagram, datagram->index,
#ifdef EC_HAVE_CYCLES
(unsigned int) (master->main_device.cycles_poll (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
);
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment