Disable use of CPU timestamp counter by default.
This commit is contained in:
parent
02ccc34a1e
commit
cdd45226aa
4
TODO
4
TODO
|
|
@ -8,14 +8,11 @@ $Id$
|
|||
|
||||
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 @@ Future issues:
|
|||
* 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:
|
||||
|
||||
|
|
|
|||
24
configure.ac
24
configure.ac
|
|
@ -489,6 +489,30 @@ fi
|
|||
AM_CONDITIONAL(ENABLE_EOE, test "x$eoe" = "x1")
|
||||
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([
|
||||
|
|
|
|||
|
|
@ -101,9 +101,13 @@ void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram. */)
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -106,9 +106,13 @@ typedef struct {
|
|||
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. */
|
||||
|
|
|
|||
|
|
@ -384,7 +384,9 @@ void ec_device_poll(
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,9 @@ struct ec_device
|
|||
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
|
||||
|
|
|
|||
|
|
@ -342,6 +342,8 @@ void ec_master_thread_stop(
|
|||
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 @@ void ec_master_thread_stop(
|
|||
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 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
|
|||
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 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
// 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 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
|
|||
}
|
||||
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 @@ void ec_master_receive_datagrams(ec_master_t *master, /**< EtherCAT master */
|
|||
|
||||
// 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_send(ec_master_t *master)
|
|||
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 @@ void ecrt_master_receive(ec_master_t *master)
|
|||
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
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue