From eb6e709e57b2a85bca904b19de93c6f363f63fb0 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 19 Sep 2007 17:17:45 +0000 Subject: [PATCH] Improved handling for spontaneous AL state changes. --- NEWS | 1 + master/fsm_change.c | 9 ++++++--- master/fsm_change.h | 1 + master/fsm_slave.c | 12 ++++++++---- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 1d09c78d..ec32ba5e 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ $Id$ Changes in version 1.3.2: +* Improved handling for spontaneous AL state changes. * Master takes mailbox sync manager configurations from EEPROM words 0x0018-0x001b, if no sync manager configurations are provided. * Calculate checksum when writing EEPROM or alias address. diff --git a/master/fsm_change.c b/master/fsm_change.c index 648e443f..b263c3aa 100644 --- a/master/fsm_change.c +++ b/master/fsm_change.c @@ -66,6 +66,7 @@ void ec_fsm_change_init(ec_fsm_change_t *fsm, /**< finite state machine */ { fsm->state = NULL; fsm->datagram = datagram; + fsm->spontaneous_change = 0; } /*****************************************************************************/ @@ -223,6 +224,7 @@ void ec_fsm_change_state_check(ec_fsm_change_t *fsm // read AL status from slave ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); fsm->retries = EC_FSM_RETRIES; + fsm->spontaneous_change = 0; fsm->state = ec_fsm_change_state_status; } @@ -281,10 +283,11 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm // Slave spontaneously changed its state just before the new state // was written. Accept current state as old state and wait for // state change + fsm->spontaneous_change = 1; fsm->old_state = slave->current_state; EC_WARN("Slave %i changed to %s in the meantime.\n", slave->ring_position, cur_state); - goto again; + goto check_again; } // state change error @@ -309,11 +312,11 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm ec_state_string(fsm->requested_state, state_str); fsm->state = ec_fsm_change_state_error; EC_ERR("Timeout while setting state %s on slave %i.\n", - state_str, slave->ring_position); + state_str, slave->ring_position); return; } - again: + check_again: // no timeout yet. check again ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); fsm->retries = EC_FSM_RETRIES; diff --git a/master/fsm_change.h b/master/fsm_change.h index a2e03e28..dde9c293 100644 --- a/master/fsm_change.h +++ b/master/fsm_change.h @@ -78,6 +78,7 @@ struct ec_fsm_change ec_slave_state_t old_state; /**< prior slave state */ unsigned long jiffies_start; /**< change timer */ uint8_t take_time; /**< take sending timestamp */ + uint8_t spontaneous_change; /**< spontaneous state change detected */ }; /*****************************************************************************/ diff --git a/master/fsm_slave.c b/master/fsm_slave.c index 861d8fd3..c3010250 100644 --- a/master/fsm_slave.c +++ b/master/fsm_slave.c @@ -595,7 +595,8 @@ void ec_fsm_slave_conf_state_init(ec_fsm_slave_t *fsm /**< slave state machine * if (ec_fsm_change_exec(&fsm->fsm_change)) return; if (!ec_fsm_change_success(&fsm->fsm_change)) { - slave->error_flag = 1; + if (!fsm->fsm_change.spontaneous_change) + slave->error_flag = 1; fsm->state = ec_fsm_slave_state_error; return; } @@ -799,7 +800,8 @@ void ec_fsm_slave_conf_state_preop(ec_fsm_slave_t *fsm /**< slave state machine if (ec_fsm_change_exec(&fsm->fsm_change)) return; if (!ec_fsm_change_success(&fsm->fsm_change)) { - slave->error_flag = 1; + if (!fsm->fsm_change.spontaneous_change) + slave->error_flag = 1; fsm->state = ec_fsm_slave_state_error; return; } @@ -1077,7 +1079,8 @@ void ec_fsm_slave_conf_state_saveop(ec_fsm_slave_t *fsm /**< slave state machine if (ec_fsm_change_exec(&fsm->fsm_change)) return; if (!ec_fsm_change_success(&fsm->fsm_change)) { - fsm->slave->error_flag = 1; + if (!fsm->fsm_change.spontaneous_change) + fsm->slave->error_flag = 1; fsm->state = ec_fsm_slave_state_error; return; } @@ -1117,7 +1120,8 @@ void ec_fsm_slave_conf_state_op(ec_fsm_slave_t *fsm /**< slave state machine */) if (ec_fsm_change_exec(&fsm->fsm_change)) return; if (!ec_fsm_change_success(&fsm->fsm_change)) { - slave->error_flag = 1; + if (!fsm->fsm_change.spontaneous_change) + slave->error_flag = 1; fsm->state = ec_fsm_slave_state_error; return; }