diff --git a/TODO b/TODO index 18d50447..e5c20df8 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,7 @@ $Id$ Version 1.4.0: * Replace all Sysfs files via the new ethercat tool. - - Slave info (flags, mailbox, general) + - Slave info (mailbox, general) - Config info (alias, position, type, Pdos, Sdos) * Slaves as array. * Remove the end state of the master state machine. diff --git a/documentation/graphs/fsm_master.dot b/documentation/graphs/fsm_master.dot index 40e045a0..19666efb 100644 --- a/documentation/graphs/fsm_master.dot +++ b/documentation/graphs/fsm_master.dot @@ -34,13 +34,10 @@ digraph master { action_configure -> configure_slave [weight=10] action_configure -> action_next_slave_state - action_acknowledge [shape=point,label=""] - action_acknowledge -> acknowledge [weight=10] - action_acknowledge -> action_configure - action_acknowledge -> action_next_slave_state - read_state [fontname="Helvetica"] - read_state -> action_acknowledge [weight=10] + read_state -> acknowledge + read_state -> action_configure [weight=10] + read_state -> action_next_slave_state acknowledge [fontname="Helvetica"] acknowledge -> action_configure [weight=10] diff --git a/master/cdev.c b/master/cdev.c index c349e5a3..9aed3d41 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -193,6 +193,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) data.serial_number = slave->sii.serial_number; data.alias = slave->sii.alias; data.state = slave->current_state; + data.error_flag = slave->error_flag; data.sync_count = slave->sii.sync_count; data.sdo_count = ec_slave_sdo_count(slave); diff --git a/master/fsm_master.c b/master/fsm_master.c index a037c9b3..1d619efa 100644 --- a/master/fsm_master.c +++ b/master/fsm_master.c @@ -364,8 +364,7 @@ int ec_fsm_master_action_process_sdo( continue; } - if (slave->current_state == EC_SLAVE_STATE_INIT || - slave->error_flag) { + if (slave->current_state == EC_SLAVE_STATE_INIT) { req->state = EC_REQUEST_FAILURE; continue; } @@ -450,7 +449,7 @@ void ec_fsm_master_action_idle( || slave->sdo_dictionary_fetched || slave->current_state == EC_SLAVE_STATE_INIT || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ - || slave->error_flag) continue; + ) continue; if (master->debug_level) { EC_DBG("Fetching Sdo dictionary from slave %u.\n", @@ -514,9 +513,8 @@ void ec_fsm_master_action_configure( ec_slave_t *slave = fsm->slave; // Does the slave have to be configured? - if (!slave->error_flag - && (slave->current_state != slave->requested_state - || slave->force_config)) { + if ((slave->current_state != slave->requested_state + || slave->force_config) && !slave->error_flag) { // Start slave configuration, if it is allowed. down(&master->config_sem); if (!master->allow_config) { @@ -553,35 +551,6 @@ void ec_fsm_master_action_configure( /*****************************************************************************/ -/** Master action: Acknowledge. - */ -void ec_fsm_master_action_acknowledge( - ec_fsm_master_t *fsm /**< Master state machine. */ - ) -{ - ec_slave_t *slave = fsm->slave; - - if (!slave->error_flag) { - // Check, if new slave state has to be acknowledged - if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { - fsm->idle = 0; - fsm->state = ec_fsm_master_state_acknowledge; - ec_fsm_change_ack(&fsm->fsm_change, slave); - fsm->state(fsm); // execute immediately - return; - } - - // No acknowlegde necessary; check for configuration - ec_fsm_master_action_configure(fsm); - return; - } - - // slave has error flag set; process next one - ec_fsm_master_action_next_slave_state(fsm); -} - -/*****************************************************************************/ - /** Master state: READ STATE. * * Fetches the AL state of a slave. @@ -619,7 +588,24 @@ void ec_fsm_master_state_read_state( // A single slave responded ec_slave_set_state(slave, EC_READ_U8(datagram->data)); - ec_fsm_master_action_acknowledge(fsm); + + if (!slave->error_flag) { + // Check, if new slave state has to be acknowledged + if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { + fsm->idle = 0; + fsm->state = ec_fsm_master_state_acknowledge; + ec_fsm_change_ack(&fsm->fsm_change, slave); + fsm->state(fsm); // execute immediately + return; + } + + // No acknowlegde necessary; check for configuration + ec_fsm_master_action_configure(fsm); + return; + } + + // slave has error flag set; process next one + ec_fsm_master_action_next_slave_state(fsm); } /*****************************************************************************/ @@ -781,7 +767,6 @@ void ec_fsm_master_state_write_sii( if (ec_fsm_sii_exec(&fsm->fsm_sii)) return; if (!ec_fsm_sii_success(&fsm->fsm_sii)) { - slave->error_flag = 1; EC_ERR("Failed to write SII data to slave %u.\n", slave->ring_position); request->state = EC_REQUEST_FAILURE; diff --git a/master/ioctl.h b/master/ioctl.h index 38dc846d..8cfc3b4d 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -85,7 +85,7 @@ typedef struct { /*****************************************************************************/ -#define EC_IOCTL_SLAVE_NAME_SIZE 100 +#define EC_IOCTL_SLAVE_NAME_SIZE 99 typedef struct { // input @@ -98,6 +98,7 @@ typedef struct { uint32_t serial_number; uint16_t alias; uint8_t state; + uint8_t error_flag; uint8_t sync_count; uint16_t sdo_count; uint32_t sii_nwords; diff --git a/tools/Master.cpp b/tools/Master.cpp index df8739af..98b3c11b 100644 --- a/tools/Master.cpp +++ b/tools/Master.cpp @@ -264,7 +264,8 @@ void Master::listSlaves() aliasIndex++; } - cout << " " << slaveState(slave.state) << " "; + cout << " " << slaveState(slave.state) + << " " << (slave.error_flag ? 'E' : '+') << " "; if (strlen(slave.name)) { cout << slave.name;