From 2c1597231d0bfba6f8ffcf06dd29147e928eecb9 Mon Sep 17 00:00:00 2001 From: Graeme Foot Date: Tue, 21 May 2019 18:26:31 +1200 Subject: [PATCH] Applied base-0028-ec_master_exec_slave_fsms-external-datagram-fix Slaves can fail to correctly read their SII information, leading to zero or corrupted SII information. This leads to slaves that remain in PREOP or SAFEOP. This is caused by the cached external (slave) datagrams being cycled through too quickly due to being marked as consumed when they are not. Datagrams can then be lost or incorrectly shared between multiple slaves as the ring returns a datagram that is still in use by a read SII call. This may also occur if multiple services are contending for a slaves mailbox. I have not added checks into ec_master_get_external_datagram() to check that a returned datagram is not currently in use. --- master/master.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/master/master.c b/master/master.c index 0bf44ddb..282f5452 100644 --- a/master/master.c +++ b/master/master.c @@ -1634,13 +1634,15 @@ void ec_master_exec_slave_fsms( fsm->slave->ring_position); #endif if (ec_fsm_slave_exec(fsm, datagram)) { - // FSM consumed datagram + if (datagram->state != EC_DATAGRAM_INVALID) { + // FSM consumed datagram #if DEBUG_INJECT - EC_MASTER_DBG(master, 1, "FSM consumed datagram %s\n", - datagram->name); + EC_MASTER_DBG(master, 1, "FSM consumed datagram %s\n", + datagram->name); #endif - master->ext_ring_idx_fsm = - (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE; + master->ext_ring_idx_fsm = + (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE; + } } else { // FSM finished @@ -1660,8 +1662,10 @@ void ec_master_exec_slave_fsms( datagram = ec_master_get_external_datagram(master); if (ec_fsm_slave_exec(&master->fsm_slave->fsm, datagram)) { - master->ext_ring_idx_fsm = - (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE; + if (datagram->state != EC_DATAGRAM_INVALID) { + master->ext_ring_idx_fsm = + (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE; + } list_add_tail(&master->fsm_slave->fsm.list, &master->fsm_exec_list); master->fsm_exec_count++;