# HG changeset patch # User Dave Page # Date 1429043144 14400 # Node ID a380cce7d6f0edfd884dff114f8ec5812287a629 # Parent a2701af27fdead51a6a8e00d2faf248708e6addd 16-ethercat-1.5-frame-corruption.patch from ethercat-1.5.0-patches-v2.tar.bz2 by Frank Heckenbach f.heckenbach@ at fh-soft.de Ref: http://lists.etherlab.org/pipermail/etherlab-dev/2014/000404.html with some additional edits. diff -r a2701af27fde -r a380cce7d6f0 include/ecrt.h --- a/include/ecrt.h Tue Apr 14 13:12:24 2015 -0400 +++ b/include/ecrt.h Tue Apr 14 16:25:44 2015 -0400 @@ -956,8 +956,10 @@ * * Has to be called cyclically by the application after ecrt_master_activate() * has returned. - */ -void ecrt_master_send( + * + * Returns the number of bytes sent. + */ +size_t ecrt_master_send( ec_master_t *master /**< EtherCAT master. */ ); diff -r a2701af27fde -r a380cce7d6f0 lib/master.c --- a/lib/master.c Tue Apr 14 13:12:24 2015 -0400 +++ b/lib/master.c Tue Apr 14 16:25:44 2015 -0400 @@ -607,15 +607,18 @@ /****************************************************************************/ -void ecrt_master_send(ec_master_t *master) -{ - int ret; - - ret = ioctl(master->fd, EC_IOCTL_SEND, NULL); +size_t ecrt_master_send(ec_master_t *master) +{ + int ret; + size_t sent_bytes = 0; + + ret = ioctl(master->fd, EC_IOCTL_SEND, &sent_bytes); if (EC_IOCTL_IS_ERROR(ret)) { fprintf(stderr, "Failed to send: %s\n", strerror(EC_IOCTL_ERRNO(ret))); } + + return sent_bytes; } /****************************************************************************/ diff -r a2701af27fde -r a380cce7d6f0 master/device.h --- a/master/device.h Tue Apr 14 13:12:24 2015 -0400 +++ b/master/device.h Tue Apr 14 16:25:44 2015 -0400 @@ -48,7 +48,7 @@ * different memory regions, because otherwise the network device DMA could * send the same data twice, if it is called twice. */ -#define EC_TX_RING_SIZE 2 +#define EC_TX_RING_SIZE 0x10 #ifdef EC_DEBUG_IF #include "debug.h" diff -r a2701af27fde -r a380cce7d6f0 master/ioctl.c --- a/master/ioctl.c Tue Apr 14 13:12:24 2015 -0400 +++ b/master/ioctl.c Tue Apr 14 16:25:44 2015 -0400 @@ -1913,11 +1913,18 @@ ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ ) { + size_t sent_bytes; + if (unlikely(!ctx->requested)) { return -EPERM; } - ecrt_master_send(master); + sent_bytes = ecrt_master_send(master); + + if (copy_to_user((void __user *) arg, &sent_bytes, sizeof(sent_bytes))) { + return -EFAULT; + } + return 0; } diff -r a2701af27fde -r a380cce7d6f0 master/master.c --- a/master/master.c Tue Apr 14 13:12:24 2015 -0400 +++ b/master/master.c Tue Apr 14 16:25:44 2015 -0400 @@ -981,7 +981,7 @@ /** Sends the datagrams in the queue for a certain device. * */ -void ec_master_send_datagrams( +size_t ec_master_send_datagrams( ec_master_t *master, /**< EtherCAT master */ ec_device_index_t device_index /**< Device index. */ ) @@ -996,6 +996,7 @@ unsigned long jiffies_sent; unsigned int frame_count, more_datagrams_waiting; struct list_head sent_datagrams; + size_t sent_bytes = 0; #ifdef EC_HAVE_CYCLES cycles_start = get_cycles(); @@ -1081,6 +1082,8 @@ // send frame ec_device_send(&master->devices[device_index], cur_data - frame_data); + /* preamble and inter-frame gap */ + sent_bytes += ETH_HLEN + cur_data - frame_data + ETH_FCS_LEN + 20; #ifdef EC_HAVE_CYCLES cycles_sent = get_cycles(); #endif @@ -1098,7 +1101,7 @@ frame_count++; } - while (more_datagrams_waiting); + while (more_datagrams_waiting && frame_count < EC_TX_RING_SIZE); #ifdef EC_HAVE_CYCLES if (unlikely(master->debug_level > 1)) { @@ -1108,6 +1111,7 @@ (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz); } #endif + return sent_bytes; } /*****************************************************************************/ @@ -1535,9 +1539,7 @@ { ec_master_t *master = (ec_master_t *) priv_data; int fsm_exec; -#ifdef EC_USE_HRTIMER size_t sent_bytes; -#endif // send interval in IDLE phase ec_master_set_send_interval(master, 1000000 / HZ); @@ -1570,11 +1572,7 @@ if (fsm_exec) { ec_master_queue_datagram(master, &master->fsm_datagram); } - ecrt_master_send(master); -#ifdef EC_USE_HRTIMER - sent_bytes = master->devices[EC_DEVICE_MAIN].tx_skb[ - master->devices[EC_DEVICE_MAIN].tx_ring_index]->len; -#endif + sent_bytes = ecrt_master_send(master); up(&master->io_sem); if (ec_fsm_master_idle(&master->fsm)) { @@ -1586,7 +1584,8 @@ #endif } else { #ifdef EC_USE_HRTIMER - ec_master_nanosleep(sent_bytes * EC_BYTE_TRANSMISSION_TIME_NS); + ec_master_nanosleep( + sent_bytes * EC_BYTE_TRANSMISSION_TIME_NS * 6 / 5); #else schedule(); #endif @@ -2447,10 +2446,12 @@ /*****************************************************************************/ -void ecrt_master_send(ec_master_t *master) +size_t ecrt_master_send(ec_master_t *master) { ec_datagram_t *datagram, *n; ec_device_index_t dev_idx; + size_t sent_bytes = 0; + if (master->injection_seq_rt != master->injection_seq_fsm) { // inject datagram produced by master FSM @@ -2485,8 +2486,11 @@ } // send frames - ec_master_send_datagrams(master, dev_idx); - } + sent_bytes = max(sent_bytes, + ec_master_send_datagrams(master, dev_idx)); + } + + return sent_bytes; } /*****************************************************************************/