Removed 'end' and 'error' states from master state machine.

This commit is contained in:
Florian Pose 2008-06-18 13:53:31 +00:00
parent 6b2c9f27ef
commit f03af4c38b
5 changed files with 56 additions and 90 deletions

1
TODO
View File

@ -16,7 +16,6 @@ Version 1.4.0:
* Update documentation.
* Check for sizes of uploaded Sdos when reading mapping from CoE.
* Attach Pdo names from SII or Coe dictioary to Pdos read via CoE.
* Remove the end state of the master state machine.
* Add a -n (numeric) switch to ethercat command.
Future issues:

View File

@ -10,7 +10,7 @@ digraph master {
start -> broadcast [weight=10]
broadcast [fontname="Helvetica"]
broadcast -> end
broadcast -> start
broadcast -> clear_addresses
broadcast -> read_state [weight=10]
@ -24,7 +24,7 @@ digraph master {
action_idle -> action_process_sdo
action_idle -> sdo_dictionary
action_idle -> action_process_sii
action_idle -> end
action_idle -> start
action_next_slave_state [shape=point,label=""]
action_next_slave_state -> read_state
@ -35,8 +35,8 @@ digraph master {
action_configure -> action_next_slave_state
read_state [fontname="Helvetica"]
read_state -> acknowledge
read_state -> action_configure [weight=10]
read_state -> acknowledge [weight=10]
read_state -> action_configure
read_state -> action_next_slave_state
acknowledge [fontname="Helvetica"]
@ -46,21 +46,19 @@ digraph master {
clear_addresses -> scan_slave [weight=10]
scan_slave [fontname="Helvetica"]
scan_slave -> end
scan_slave -> start
configure_slave [fontname="Helvetica"]
configure_slave -> action_next_slave_state [weight=10]
configure_slave -> action_next_slave_state
write_sii [fontname="Helvetica"]
write_sii -> action_process_sii
write_sii -> end
write_sii -> start
sdo_dictionary [fontname="Helvetica"]
sdo_dictionary -> end
sdo_dictionary -> start
sdo_request [fontname="Helvetica"]
sdo_request -> action_process_sdo
sdo_request -> end
end [fontname="Helvetica"]
sdo_request -> start
}

View File

@ -59,8 +59,6 @@ void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
void ec_fsm_master_state_end(ec_fsm_master_t *);
void ec_fsm_master_state_error(ec_fsm_master_t *);
/*****************************************************************************/
@ -113,34 +111,18 @@ void ec_fsm_master_clear(
*
* If the state machine's datagram is not sent or received yet, the execution
* of the state machine is delayed to the next cycle.
*
* \return false, if state machine has terminated
*/
int ec_fsm_master_exec(
void ec_fsm_master_exec(
ec_fsm_master_t *fsm /**< Master state machine. */
)
{
if (fsm->datagram->state == EC_DATAGRAM_SENT
|| fsm->datagram->state == EC_DATAGRAM_QUEUED) {
// datagram was not sent or received yet.
return ec_fsm_master_running(fsm);
return;
}
fsm->state(fsm);
return ec_fsm_master_running(fsm);
}
/*****************************************************************************/
/**
* \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;
}
/*****************************************************************************/
@ -155,6 +137,18 @@ int ec_fsm_master_idle(
return fsm->idle;
}
/*****************************************************************************/
/** Restarts the master state machine.
*/
void ec_fsm_master_restart(
ec_fsm_master_t *fsm /**< Master state machine. */
)
{
fsm->state = ec_fsm_master_state_start;
fsm->state(fsm); // execute immediately
}
/******************************************************************************
* Master state machine
*****************************************************************************/
@ -198,7 +192,7 @@ void ec_fsm_master_state_broadcast(
}
if (datagram->state != EC_DATAGRAM_RECEIVED) { // link is down
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -240,7 +234,7 @@ void ec_fsm_master_state_broadcast(
// no slaves present -> finish state machine.
master->scan_busy = 0;
wake_up_interruptible(&master->scan_queue);
fsm->state = ec_fsm_master_state_end;
ec_fsm_master_restart(fsm);
return;
}
@ -251,7 +245,7 @@ void ec_fsm_master_state_broadcast(
master->slave_count = 0; // FIXME avoid scanning!
master->scan_busy = 0;
wake_up_interruptible(&master->scan_queue);
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -283,7 +277,7 @@ void ec_fsm_master_state_broadcast(
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_master_state_read_state;
} else {
fsm->state = ec_fsm_master_state_end;
ec_fsm_master_restart(fsm);
}
}
@ -471,7 +465,7 @@ void ec_fsm_master_action_idle(
if (ec_fsm_master_action_process_sii(fsm))
return; // SII write request found
fsm->state = ec_fsm_master_state_end;
ec_fsm_master_restart(fsm);
}
/*****************************************************************************/
@ -568,7 +562,7 @@ void ec_fsm_master_state_read_state(
EC_ERR("Failed to receive AL state datagram for slave %u"
" (datagram state %u)\n",
slave->ring_position, datagram->state);
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -581,7 +575,7 @@ void ec_fsm_master_state_read_state(
fsm->slave->ring_position);
}
fsm->topology_change_pending = 1;
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -648,7 +642,7 @@ void ec_fsm_master_state_clear_addresses(
datagram->state);
master->scan_busy = 0;
wake_up_interruptible(&master->scan_queue);
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -721,7 +715,7 @@ void ec_fsm_master_state_scan_slave(
ec_master_eoe_start(master);
#endif
fsm->state = ec_fsm_master_state_end;
ec_fsm_master_restart(fsm);
}
/*****************************************************************************/
@ -770,7 +764,7 @@ void ec_fsm_master_state_write_sii(
slave->ring_position);
request->state = EC_REQUEST_FAILURE;
wake_up(&master->sii_queue);
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -797,7 +791,7 @@ void ec_fsm_master_state_write_sii(
if (ec_fsm_master_action_process_sii(fsm))
return; // processing another request
fsm->state = ec_fsm_master_state_end;
ec_fsm_master_restart(fsm);
}
/*****************************************************************************/
@ -814,7 +808,7 @@ void ec_fsm_master_state_sdo_dictionary(
if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -827,7 +821,7 @@ void ec_fsm_master_state_sdo_dictionary(
sdo_count, entry_count, slave->ring_position);
}
fsm->state = ec_fsm_master_state_end;
ec_fsm_master_restart(fsm);
}
/*****************************************************************************/
@ -848,7 +842,7 @@ void ec_fsm_master_state_sdo_request(
fsm->slave->ring_position);
request->state = EC_REQUEST_FAILURE;
wake_up(&master->sdo_queue);
fsm->state = ec_fsm_master_state_error;
ec_fsm_master_restart(fsm);
return;
}
@ -864,29 +858,7 @@ void ec_fsm_master_state_sdo_request(
if (ec_fsm_master_action_process_sdo(fsm))
return; // processing another request
fsm->state = ec_fsm_master_state_end;
}
/*****************************************************************************/
/** State: ERROR.
*/
void ec_fsm_master_state_error(
ec_fsm_master_t *fsm /**< Master state machine. */
)
{
fsm->state = ec_fsm_master_state_start;
}
/*****************************************************************************/
/** State: END.
*/
void ec_fsm_master_state_end(
ec_fsm_master_t *fsm /**< Master state machine. */
)
{
fsm->state = ec_fsm_master_state_start;
ec_fsm_master_restart(fsm);
}
/*****************************************************************************/

View File

@ -108,8 +108,7 @@ struct ec_fsm_master {
void ec_fsm_master_init(ec_fsm_master_t *, ec_master_t *, ec_datagram_t *);
void ec_fsm_master_clear(ec_fsm_master_t *);
int ec_fsm_master_exec(ec_fsm_master_t *);
int ec_fsm_master_running(const ec_fsm_master_t *);
void ec_fsm_master_exec(ec_fsm_master_t *);
int ec_fsm_master_idle(const ec_fsm_master_t *);
/*****************************************************************************/

View File

@ -818,24 +818,22 @@ static int ec_master_idle_thread(ec_master_t *master)
cycles_start = get_cycles();
ec_datagram_output_stats(&master->fsm_datagram);
if (ec_fsm_master_running(&master->fsm)) { // datagram on the way
// receive
spin_lock_bh(&master->internal_lock);
ecrt_master_receive(master);
spin_unlock_bh(&master->internal_lock);
// receive
spin_lock_bh(&master->internal_lock);
ecrt_master_receive(master);
spin_unlock_bh(&master->internal_lock);
if (master->fsm_datagram.state == EC_DATAGRAM_SENT)
goto schedule;
}
if (master->fsm_datagram.state == EC_DATAGRAM_SENT)
goto schedule;
// execute master state machine
if (ec_fsm_master_exec(&master->fsm)) { // datagram ready for sending
// queue and send
spin_lock_bh(&master->internal_lock);
ec_master_queue_datagram(master, &master->fsm_datagram);
ecrt_master_send(master);
spin_unlock_bh(&master->internal_lock);
}
ec_fsm_master_exec(&master->fsm);
// queue and send
spin_lock_bh(&master->internal_lock);
ec_master_queue_datagram(master, &master->fsm_datagram);
ecrt_master_send(master);
spin_unlock_bh(&master->internal_lock);
cycles_end = get_cycles();
master->idle_cycle_times[master->idle_cycle_time_pos]
@ -883,10 +881,10 @@ static int ec_master_operation_thread(ec_master_t *master)
ec_master_output_stats(master);
// execute master state machine
if (ec_fsm_master_exec(&master->fsm)) {
// inject datagram
master->injection_seq_fsm++;
}
ec_fsm_master_exec(&master->fsm);
// inject datagram
master->injection_seq_fsm++;
cycles_end = get_cycles();
master->idle_cycle_times[master->idle_cycle_time_pos]