Serveral changes to avoid timeouts under high CPU load.

This commit is contained in:
Florian Pose 2006-10-16 09:07:49 +00:00
parent 0c8d3e94c3
commit 459e7f391c
5 changed files with 23 additions and 10 deletions

View File

@ -78,6 +78,7 @@ void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram */)
datagram->working_counter = 0x00;
datagram->state = EC_DATAGRAM_INIT;
datagram->cycles_sent = 0;
datagram->check_once_more = 0;
}
/*****************************************************************************/

View File

@ -119,6 +119,7 @@ typedef struct
uint16_t working_counter; /**< working counter */
ec_datagram_state_t state; /**< datagram state */
cycles_t cycles_sent; /**< time, the datagram was sent */
uint8_t check_once_more; /**< one more try in case of timeout */
}
ec_datagram_t;

View File

@ -265,7 +265,7 @@ void ec_fsm_startup_broadcast(ec_fsm_t *fsm /**< finite state machine */)
ec_master_t *master = fsm->master;
if (datagram->state != EC_DATAGRAM_RECEIVED) {
EC_ERR("Failed tor receive broadcast datagram.\n");
EC_ERR("Failed to receive broadcast datagram.\n");
fsm->master_state = ec_fsm_error;
return;
}
@ -1613,6 +1613,7 @@ void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */)
return;
}
fsm->sii_check_once_more = 1;
fsm->sii_start = get_cycles();
// issue check/fetch datagram
@ -1649,16 +1650,19 @@ void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */)
if (EC_READ_U8(datagram->data + 1) & 0x81) {
// still busy... timeout?
if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
EC_ERR("SII: Read timeout.\n");
fsm->sii_state = ec_fsm_error;
if (!fsm->sii_check_once_more) {
EC_ERR("SII: Read timeout.\n");
fsm->sii_state = ec_fsm_error;
#if 0
EC_DBG("SII busy: %02X %02X %02X %02X\n",
EC_READ_U8(datagram->data + 0),
EC_READ_U8(datagram->data + 1),
EC_READ_U8(datagram->data + 2),
EC_READ_U8(datagram->data + 3));
EC_DBG("SII busy: %02X %02X %02X %02X\n",
EC_READ_U8(datagram->data + 0),
EC_READ_U8(datagram->data + 1),
EC_READ_U8(datagram->data + 2),
EC_READ_U8(datagram->data + 3));
#endif
return;
return;
}
fsm->sii_check_once_more = 0;
}
// issue check/fetch datagram again

View File

@ -72,6 +72,7 @@ struct ec_fsm
unsigned int sii_mode; /**< SII reading done by APRD (0) or NPRD (1) */
uint8_t sii_value[4]; /**< raw SII value (32bit) */
cycles_t sii_start; /**< sii start */
uint8_t sii_check_once_more; /**< do one more check in case of timeout */
void (*change_state)(ec_fsm_t *); /**< slave state change state function */
ec_slave_state_t change_new; /**< input: new state */

View File

@ -356,6 +356,7 @@ void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */)
datagram->state = EC_DATAGRAM_SENT;
datagram->cycles_sent = cycles_start;
datagram->check_once_more = 1;
datagram->index = master->datagram_index++;
if (unlikely(master->debug_level > 1))
@ -1313,7 +1314,7 @@ void ecrt_master_receive(ec_master_t *master /**< EtherCAT master */)
ec_device_call_isr(master->device);
cycles_received = get_cycles();
cycles_timeout = EC_IO_TIMEOUT * cpu_khz / 1000;
cycles_timeout = EC_IO_TIMEOUT /* us */ * cpu_khz / 1000;
// dequeue all datagrams that timed out
list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
@ -1321,6 +1322,11 @@ void ecrt_master_receive(ec_master_t *master /**< EtherCAT master */)
case EC_DATAGRAM_SENT:
case EC_DATAGRAM_QUEUED:
if (cycles_received - datagram->cycles_sent > cycles_timeout) {
if (datagram->state == EC_DATAGRAM_SENT
&& datagram->check_once_more) {
datagram->check_once_more = 0;
break;
}
list_del_init(&datagram->queue);
datagram->state = EC_DATAGRAM_TIMED_OUT;
master->stats.timeouts++;