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.
This commit is contained in:
Dave Page 2015-04-14 16:25:44 -04:00
parent ff75554c58
commit 45839e8666
5 changed files with 33 additions and 17 deletions

View File

@ -956,8 +956,10 @@ int ecrt_master_set_send_interval(
*
* Has to be called cyclically by the application after ecrt_master_activate()
* has returned.
*
* Returns the number of bytes sent.
*/
void ecrt_master_send(
size_t ecrt_master_send(
ec_master_t *master /**< EtherCAT master. */
);

View File

@ -607,15 +607,18 @@ int ecrt_master_set_send_interval(ec_master_t *master,
/****************************************************************************/
void ecrt_master_send(ec_master_t *master)
size_t ecrt_master_send(ec_master_t *master)
{
int ret;
size_t sent_bytes = 0;
ret = ioctl(master->fd, EC_IOCTL_SEND, NULL);
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;
}
/****************************************************************************/

View File

@ -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"

View File

@ -1913,11 +1913,18 @@ static ATTRIBUTES int ec_ioctl_send(
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;
}

View File

@ -981,7 +981,7 @@ void ec_master_queue_datagram_ext(
/** 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 @@ void ec_master_send_datagrams(
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 @@ void ec_master_send_datagrams(
// 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 @@ void ec_master_send_datagrams(
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 @@ void ec_master_send_datagrams(
(unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
}
#endif
return sent_bytes;
}
/*****************************************************************************/
@ -1535,9 +1539,7 @@ static int ec_master_idle_thread(void *priv_data)
{
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 @@ static int ec_master_idle_thread(void *priv_data)
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 @@ static int ec_master_idle_thread(void *priv_data)
#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_deactivate(ec_master_t *master)
/*****************************************************************************/
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 @@ void ecrt_master_send(ec_master_t *master)
}
// send frames
ec_master_send_datagrams(master, dev_idx);
sent_bytes = max(sent_bytes,
ec_master_send_datagrams(master, dev_idx));
}
return sent_bytes;
}
/*****************************************************************************/