Introduced idle flag in master state machine.
--- a/NEWS Mon Mar 12 11:02:05 2007 +0000
+++ b/NEWS Mon Mar 12 12:11:43 2007 +0000
@@ -37,6 +37,8 @@
* Implemented setting of secondary slave address (alias) via sysfs.
* Implemented SDO reading in operation mode via sysfs.
* Removed annoying eeprom_write_enable file. EEPROM writing always enabled.
+* Master state machine scheduled with timeout if idle, otherwise is executed
+ as fast as possible (with schedule()).
* Removed EtherCAT line comments from 8139too drivers.
-------------------------------------------------------------------------------
--- a/TODO Mon Mar 12 11:02:05 2007 +0000
+++ b/TODO Mon Mar 12 12:11:43 2007 +0000
@@ -26,7 +26,6 @@
- Evaluate EEPROM contents after writing.
- SDO dictionary fetching in operation mode.
- SDO write access in sysfs.
- - Speed up IDLE state machine through fast mode with schedule().
- Configure slave ports to automatically open on link detection.
- Calculate cycle time of operation state machine.
--- a/master/fsm_master.c Mon Mar 12 11:02:05 2007 +0000
+++ b/master/fsm_master.c Mon Mar 12 12:11:43 2007 +0000
@@ -74,6 +74,7 @@
fsm->master = master;
fsm->datagram = datagram;
fsm->state = ec_fsm_master_state_start;
+ fsm->idle = 0;
fsm->slaves_responding = 0;
fsm->topology_change_pending = 0;
fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
@@ -126,15 +127,30 @@
/*****************************************************************************/
/**
- \return false, if state machine has terminated
-*/
-
-int ec_fsm_master_running(ec_fsm_master_t *fsm /**< master state machine */)
+ * \return false, if state machine has terminated
+ */
+
+int ec_fsm_master_running(
+ const ec_fsm_master_t *fsm /**< master state machine */
+ )
{
return fsm->state != ec_fsm_master_state_end
&& fsm->state != ec_fsm_master_state_error;
}
+/*****************************************************************************/
+
+/**
+ * \return true, if the state machine is in an idle phase
+ */
+
+int ec_fsm_master_idle(
+ const ec_fsm_master_t *fsm /**< master state machine */
+ )
+{
+ return fsm->idle;
+}
+
/******************************************************************************
* master state machine
*****************************************************************************/
@@ -146,6 +162,7 @@
void ec_fsm_master_state_start(ec_fsm_master_t *fsm)
{
+ fsm->idle = 1;
ec_datagram_brd(fsm->datagram, 0x0130, 2);
fsm->state = ec_fsm_master_state_broadcast;
}
@@ -167,8 +184,7 @@
if (datagram->state == EC_DATAGRAM_TIMED_OUT)
return; // always retry
- if (datagram->state != EC_DATAGRAM_RECEIVED) { // EC_DATAGRAM_ERROR
- // link is down
+ if (datagram->state != EC_DATAGRAM_RECEIVED) { // link is down
fsm->slaves_responding = 0;
list_for_each_entry(slave, &master->slaves, list) {
ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
@@ -210,6 +226,7 @@
master->mode == EC_MASTER_MODE_IDLE) {
fsm->topology_change_pending = 0;
fsm->tainted = 0;
+ fsm->idle = 0;
ec_master_eoe_stop(master);
ec_master_destroy_slaves(master);
@@ -359,6 +376,7 @@
slave->ring_position);
// start uploading SDO
+ fsm->idle = 0;
fsm->slave = slave;
fsm->sdo_request = request;
fsm->state = ec_fsm_master_state_sdo_request;
@@ -406,6 +424,7 @@
}
}
+ fsm->idle = 0;
fsm->slave = slave;
fsm->state = ec_fsm_master_state_configure_slave;
ec_fsm_slave_start_conf(&fsm->fsm_slave, slave);
@@ -439,6 +458,7 @@
slave->sdo_dictionary_fetched = 1;
// start fetching SDO dictionary
+ fsm->idle = 0;
fsm->slave = slave;
fsm->state = ec_fsm_master_state_sdodict;
ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
@@ -469,6 +489,7 @@
// is there another slave to query?
if (slave->list.next != &master->slaves) {
// process next slave
+ fsm->idle = 1;
fsm->slave = list_entry(slave->list.next, ec_slave_t, list);
ec_datagram_nprd(fsm->datagram, fsm->slave->station_address,
0x0130, 2);
@@ -487,6 +508,7 @@
// At least one slave is offline. validate!
EC_INFO("Validating bus.\n");
+ fsm->idle = 0;
fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
fsm->state = ec_fsm_master_state_validate_vendor;
ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008, EC_FSM_SII_POSITION);
@@ -533,6 +555,7 @@
// check, if new slave state has to be acknowledged
if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
+ fsm->idle = 0;
fsm->state = ec_fsm_master_state_acknowledge;
ec_fsm_change_ack(&fsm->fsm_change, slave);
ec_fsm_change_exec(&fsm->fsm_change);
--- a/master/fsm_master.h Mon Mar 12 11:02:05 2007 +0000
+++ b/master/fsm_master.h Mon Mar 12 12:11:43 2007 +0000
@@ -81,6 +81,7 @@
unsigned int retries; /**< retries on datagram timeout. */
void (*state)(ec_fsm_master_t *); /**< master state function */
+ int idle; /**< state machine is in idle phase */
unsigned int slaves_responding; /**< number of responding slaves */
unsigned int topology_change_pending; /**< bus topology changed */
ec_slave_state_t slave_states; /**< states of responding slaves */
@@ -104,7 +105,8 @@
void ec_fsm_master_clear(ec_fsm_master_t *);
int ec_fsm_master_exec(ec_fsm_master_t *);
-int ec_fsm_master_running(ec_fsm_master_t *);
+int ec_fsm_master_running(const ec_fsm_master_t *);
+int ec_fsm_master_idle(const ec_fsm_master_t *);
/*****************************************************************************/
--- a/master/master.c Mon Mar 12 11:02:05 2007 +0000
+++ b/master/master.c Mon Mar 12 12:11:43 2007 +0000
@@ -836,8 +836,13 @@
master->idle_cycle_time_pos++;
master->idle_cycle_time_pos %= HZ;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ if (ec_fsm_master_idle(&master->fsm)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ else {
+ schedule();
+ }
}
master->thread_id = 0;
@@ -883,8 +888,13 @@
master->idle_cycle_time_pos %= HZ;
schedule:
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ if (ec_fsm_master_idle(&master->fsm)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ else {
+ schedule();
+ }
}
master->thread_id = 0;