Execute master FSM in fast mode also if slave FSM are busy.

This commit is contained in:
Florian Pose 2022-06-08 16:11:43 +02:00
parent 26e5b9f553
commit 74ec61add4
1 changed files with 18 additions and 8 deletions

View File

@ -1460,14 +1460,17 @@ void ec_master_nanosleep(const unsigned long nsecs)
/*****************************************************************************/ /*****************************************************************************/
/** Execute slave FSMs. /** Execute slave FSMs.
*
* Returns non-zero, if at least one slave FSM is busy.
*/ */
void ec_master_exec_slave_fsms( int ec_master_exec_slave_fsms(
ec_master_t *master /**< EtherCAT master. */ ec_master_t *master /**< EtherCAT master. */
) )
{ {
ec_datagram_t *datagram; ec_datagram_t *datagram;
ec_fsm_slave_t *fsm, *next; ec_fsm_slave_t *fsm, *next;
unsigned int count = 0; unsigned int count = 0;
int busy = 0;
list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) { list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) {
if (!fsm->datagram) { if (!fsm->datagram) {
@ -1475,7 +1478,7 @@ void ec_master_exec_slave_fsms(
"This is a bug!\n", fsm->slave->ring_position); "This is a bug!\n", fsm->slave->ring_position);
list_del_init(&fsm->list); list_del_init(&fsm->list);
master->fsm_exec_count--; master->fsm_exec_count--;
return; return 1;
} }
if (fsm->datagram->state == EC_DATAGRAM_INIT || if (fsm->datagram->state == EC_DATAGRAM_INIT ||
@ -1483,7 +1486,7 @@ void ec_master_exec_slave_fsms(
fsm->datagram->state == EC_DATAGRAM_SENT) { fsm->datagram->state == EC_DATAGRAM_SENT) {
// previous datagram was not sent or received yet. // previous datagram was not sent or received yet.
// wait until next thread execution // wait until next thread execution
return; return 1;
} }
datagram = ec_master_get_external_datagram(master); datagram = ec_master_get_external_datagram(master);
@ -1506,6 +1509,7 @@ void ec_master_exec_slave_fsms(
#endif #endif
master->ext_ring_idx_fsm = master->ext_ring_idx_fsm =
(master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE; (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
busy = 1;
} }
else { else {
// FSM finished // FSM finished
@ -1530,6 +1534,7 @@ void ec_master_exec_slave_fsms(
list_add_tail(&master->fsm_slave->fsm.list, list_add_tail(&master->fsm_slave->fsm.list,
&master->fsm_exec_list); &master->fsm_exec_list);
master->fsm_exec_count++; master->fsm_exec_count++;
busy = 1;
#if DEBUG_INJECT #if DEBUG_INJECT
EC_MASTER_DBG(master, 1, "New slave %u FSM" EC_MASTER_DBG(master, 1, "New slave %u FSM"
" consumed datagram %s, now %u FSMs in list.\n", " consumed datagram %s, now %u FSMs in list.\n",
@ -1545,6 +1550,8 @@ void ec_master_exec_slave_fsms(
} }
count++; count++;
} }
return busy;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1554,7 +1561,7 @@ void ec_master_exec_slave_fsms(
static int ec_master_idle_thread(void *priv_data) static int ec_master_idle_thread(void *priv_data)
{ {
ec_master_t *master = (ec_master_t *) priv_data; ec_master_t *master = (ec_master_t *) priv_data;
int fsm_exec; int fsm_exec, slave_fsms_busy;
#ifdef EC_USE_HRTIMER #ifdef EC_USE_HRTIMER
size_t sent_bytes; size_t sent_bytes;
#endif #endif
@ -1581,7 +1588,7 @@ static int ec_master_idle_thread(void *priv_data)
fsm_exec = ec_fsm_master_exec(&master->fsm); fsm_exec = ec_fsm_master_exec(&master->fsm);
ec_master_exec_slave_fsms(master); slave_fsms_busy = ec_master_exec_slave_fsms(master);
up(&master->master_sem); up(&master->master_sem);
@ -1597,7 +1604,7 @@ static int ec_master_idle_thread(void *priv_data)
#endif #endif
up(&master->io_sem); up(&master->io_sem);
if (ec_fsm_master_idle(&master->fsm)) { if (ec_fsm_master_idle(&master->fsm) && !slave_fsms_busy) {
#ifdef EC_USE_HRTIMER #ifdef EC_USE_HRTIMER
ec_master_nanosleep(master->send_interval * 1000); ec_master_nanosleep(master->send_interval * 1000);
#else #else
@ -1625,6 +1632,7 @@ static int ec_master_idle_thread(void *priv_data)
static int ec_master_operation_thread(void *priv_data) static int ec_master_operation_thread(void *priv_data)
{ {
ec_master_t *master = (ec_master_t *) priv_data; ec_master_t *master = (ec_master_t *) priv_data;
int slave_fsms_busy;
EC_MASTER_DBG(master, 1, "Operation thread running" EC_MASTER_DBG(master, 1, "Operation thread running"
" with fsm interval = %u us, max data size=%zu\n", " with fsm interval = %u us, max data size=%zu\n",
@ -1633,6 +1641,8 @@ static int ec_master_operation_thread(void *priv_data)
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
ec_datagram_output_stats(&master->fsm_datagram); ec_datagram_output_stats(&master->fsm_datagram);
slave_fsms_busy = 0;
if (master->injection_seq_rt == master->injection_seq_fsm) { if (master->injection_seq_rt == master->injection_seq_fsm) {
// output statistics // output statistics
ec_master_output_stats(master); ec_master_output_stats(master);
@ -1648,7 +1658,7 @@ static int ec_master_operation_thread(void *priv_data)
master->injection_seq_fsm++; master->injection_seq_fsm++;
} }
ec_master_exec_slave_fsms(master); slave_fsms_busy = ec_master_exec_slave_fsms(master);
up(&master->master_sem); up(&master->master_sem);
} }
@ -1657,7 +1667,7 @@ static int ec_master_operation_thread(void *priv_data)
// the op thread should not work faster than the sending RT thread // the op thread should not work faster than the sending RT thread
ec_master_nanosleep(master->send_interval * 1000); ec_master_nanosleep(master->send_interval * 1000);
#else #else
if (ec_fsm_master_idle(&master->fsm)) { if (ec_fsm_master_idle(&master->fsm) && !slave_fsms_busy) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} }