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:
parent
ff75554c58
commit
45839e8666
|
|
@ -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. */
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in New Issue