Skip to content
Snippets Groups Projects
Commit 7430f90e authored by Florian Pose's avatar Florian Pose
Browse files

Introduced ec_slave_online_state_t, ec_slave_set_online_state(), renamed

slave->online to ec_online_state and introduced
ec_slave_set_app_state().
parent 97fa4f5d
No related branches found
No related tags found
No related merge requests found
...@@ -317,7 +317,8 @@ int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */) ...@@ -317,7 +317,8 @@ int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */)
void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */) void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
{ {
if (!eoe->slave->online || !eoe->slave->master->main_device.link_state) if (eoe->slave->online_state == EC_SLAVE_OFFLINE ||
!eoe->slave->master->main_device.link_state)
return; return;
ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram); ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
...@@ -518,7 +519,8 @@ void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE handler */) ...@@ -518,7 +519,8 @@ void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE handler */)
unsigned int wakeup = 0; unsigned int wakeup = 0;
#endif #endif
if (!eoe->slave->online || !eoe->slave->master->main_device.link_state) if (eoe->slave->online_state == EC_SLAVE_OFFLINE ||
!eoe->slave->master->main_device.link_state)
return; return;
spin_lock_bh(&eoe->tx_queue_lock); spin_lock_bh(&eoe->tx_queue_lock);
......
...@@ -185,7 +185,7 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin ...@@ -185,7 +185,7 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
// link is down // link is down
fsm->slaves_responding = 0; fsm->slaves_responding = 0;
list_for_each_entry(slave, &master->slaves, list) { list_for_each_entry(slave, &master->slaves, list) {
slave->online = 0; ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
} }
fsm->state = ec_fsm_master_state_error; fsm->state = ec_fsm_master_state_error;
return; return;
...@@ -302,7 +302,7 @@ int ec_fsm_master_action_process_eeprom( ...@@ -302,7 +302,7 @@ int ec_fsm_master_action_process_eeprom(
up(&master->eeprom_sem); up(&master->eeprom_sem);
slave = request->slave; slave = request->slave;
if (!slave->online || slave->error_flag) { if (slave->online_state == EC_SLAVE_OFFLINE || slave->error_flag) {
EC_ERR("Discarding EEPROM data, slave %i not ready.\n", EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
slave->ring_position); slave->ring_position);
request->state = EC_EEPROM_REQ_ERROR; request->state = EC_EEPROM_REQ_ERROR;
...@@ -344,7 +344,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm ...@@ -344,7 +344,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
// check if any slaves are not in the state, they're supposed to be // check if any slaves are not in the state, they're supposed to be
list_for_each_entry(slave, &master->slaves, list) { list_for_each_entry(slave, &master->slaves, list) {
if (slave->error_flag if (slave->error_flag
|| !slave->online || slave->online_state == EC_SLAVE_OFFLINE
|| slave->requested_state == EC_SLAVE_STATE_UNKNOWN || slave->requested_state == EC_SLAVE_STATE_UNKNOWN
|| (slave->current_state == slave->requested_state || (slave->current_state == slave->requested_state
&& slave->self_configured)) continue; && slave->self_configured)) continue;
...@@ -380,7 +380,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm ...@@ -380,7 +380,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
EC_DBG("Processing SDO request...\n"); EC_DBG("Processing SDO request...\n");
slave = master->sdo_request->sdo->slave; slave = master->sdo_request->sdo->slave;
if (slave->current_state == EC_SLAVE_STATE_INIT if (slave->current_state == EC_SLAVE_STATE_INIT
|| !slave->online) { || slave->online_state == EC_SLAVE_OFFLINE) {
EC_ERR("Failed to process SDO request, slave %i not ready.\n", EC_ERR("Failed to process SDO request, slave %i not ready.\n",
slave->ring_position); slave->ring_position);
master->sdo_request->return_code = -1; master->sdo_request->return_code = -1;
...@@ -403,7 +403,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm ...@@ -403,7 +403,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
|| slave->sdo_dictionary_fetched || slave->sdo_dictionary_fetched
|| slave->current_state == EC_SLAVE_STATE_INIT || slave->current_state == EC_SLAVE_STATE_INIT
|| jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
|| !slave->online || slave->online_state == EC_SLAVE_OFFLINE
|| slave->error_flag) continue; || slave->error_flag) continue;
if (master->debug_level) { if (master->debug_level) {
...@@ -459,7 +459,7 @@ void ec_fsm_master_action_next_slave_state(ec_fsm_master_t *fsm ...@@ -459,7 +459,7 @@ void ec_fsm_master_action_next_slave_state(ec_fsm_master_t *fsm
if (fsm->validate) { if (fsm->validate) {
fsm->validate = 0; fsm->validate = 0;
list_for_each_entry(slave, &master->slaves, list) { list_for_each_entry(slave, &master->slaves, list) {
if (slave->online) continue; if (slave->online_state == EC_SLAVE_ONLINE) continue;
// At least one slave is offline. validate! // At least one slave is offline. validate!
EC_INFO("Validating bus.\n"); EC_INFO("Validating bus.\n");
...@@ -485,7 +485,6 @@ void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state mach ...@@ -485,7 +485,6 @@ void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state mach
{ {
ec_slave_t *slave = fsm->slave; ec_slave_t *slave = fsm->slave;
ec_datagram_t *datagram = fsm->datagram; ec_datagram_t *datagram = fsm->datagram;
uint8_t new_state;
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
ec_master_queue_datagram(fsm->master, fsm->datagram); ec_master_queue_datagram(fsm->master, fsm->datagram);
...@@ -501,39 +500,14 @@ void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state mach ...@@ -501,39 +500,14 @@ void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state mach
// did the slave not respond to its station address? // did the slave not respond to its station address?
if (datagram->working_counter != 1) { if (datagram->working_counter != 1) {
if (slave->online) { ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
slave->online = 0;
if (slave->master->debug_level)
EC_DBG("Slave %i: offline.\n", slave->ring_position);
}
ec_fsm_master_action_next_slave_state(fsm); ec_fsm_master_action_next_slave_state(fsm);
return; return;
} }
// slave responded // slave responded
new_state = EC_READ_U8(datagram->data); ec_slave_set_state(slave, EC_READ_U8(datagram->data)); // set app state first
if (!slave->online) { // slave was offline before ec_slave_set_online_state(slave, EC_SLAVE_ONLINE);
slave->online = 1;
slave->error_flag = 0; // clear error flag
slave->current_state = new_state;
if (slave->master->debug_level) {
char cur_state[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, cur_state);
EC_DBG("Slave %i: online (%s).\n",
slave->ring_position, cur_state);
}
}
else if (new_state != slave->current_state) {
if (slave->master->debug_level) {
char old_state[EC_STATE_STRING_SIZE],
cur_state[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, old_state);
ec_state_string(new_state, cur_state);
EC_DBG("Slave %i: %s -> %s.\n",
slave->ring_position, old_state, cur_state);
}
slave->current_state = new_state;
}
// check, if new slave state has to be acknowledged // check, if new slave state has to be acknowledged
if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) { if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
...@@ -614,7 +588,7 @@ void ec_fsm_master_action_addresses(ec_fsm_master_t *fsm /**< master state machi ...@@ -614,7 +588,7 @@ void ec_fsm_master_action_addresses(ec_fsm_master_t *fsm /**< master state machi
{ {
ec_datagram_t *datagram = fsm->datagram; ec_datagram_t *datagram = fsm->datagram;
while (fsm->slave->online) { while (fsm->slave->online_state == EC_SLAVE_ONLINE) {
if (fsm->slave->list.next == &fsm->master->slaves) { // last slave? if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
fsm->state = ec_fsm_master_state_start; fsm->state = ec_fsm_master_state_start;
fsm->state(fsm); // execute immediately fsm->state(fsm); // execute immediately
......
...@@ -528,7 +528,7 @@ void ec_master_leave_operation_mode(ec_master_t *master ...@@ -528,7 +528,7 @@ void ec_master_leave_operation_mode(ec_master_t *master
// don't try to set PREOP for slaves that don't respond, // don't try to set PREOP for slaves that don't respond,
// because of 3 second timeout. // because of 3 second timeout.
if (!slave->online) { if (slave->online_state == EC_SLAVE_OFFLINE) {
if (master->debug_level) if (master->debug_level)
EC_DBG("Skipping to configure offline slave %i.\n", EC_DBG("Skipping to configure offline slave %i.\n",
slave->ring_position); slave->ring_position);
......
...@@ -116,7 +116,7 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */ ...@@ -116,7 +116,7 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
slave->current_state = EC_SLAVE_STATE_UNKNOWN; slave->current_state = EC_SLAVE_STATE_UNKNOWN;
slave->self_configured = 0; slave->self_configured = 0;
slave->error_flag = 0; slave->error_flag = 0;
slave->online = 1; slave->online_state = EC_SLAVE_ONLINE;
slave->fmmu_count = 0; slave->fmmu_count = 0;
slave->coupler_index = 0; slave->coupler_index = 0;
...@@ -328,6 +328,58 @@ void ec_slave_reset(ec_slave_t *slave /**< EtherCAT slave */) ...@@ -328,6 +328,58 @@ void ec_slave_reset(ec_slave_t *slave /**< EtherCAT slave */)
/*****************************************************************************/ /*****************************************************************************/
/**
* Sets the application state of a slave.
*/
void ec_slave_set_state(ec_slave_t *slave, /**< EtherCAT slave */
ec_slave_state_t new_state /**< new application state */
)
{
if (new_state != slave->current_state) {
if (slave->master->debug_level) {
char old_state[EC_STATE_STRING_SIZE],
cur_state[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, old_state);
ec_state_string(new_state, cur_state);
EC_DBG("Slave %i: %s -> %s.\n",
slave->ring_position, old_state, cur_state);
}
slave->current_state = new_state;
}
}
/*****************************************************************************/
/**
* Sets the online state of a slave.
*/
void ec_slave_set_online_state(ec_slave_t *slave, /**< EtherCAT slave */
ec_slave_online_state_t new_state /**< new online state */
)
{
if (new_state == EC_SLAVE_OFFLINE &&
slave->online_state == EC_SLAVE_ONLINE) {
if (slave->master->debug_level)
EC_DBG("Slave %i: offline.\n", slave->ring_position);
}
else if (new_state == EC_SLAVE_ONLINE &&
slave->online_state == EC_SLAVE_OFFLINE) {
slave->error_flag = 0; // clear error flag
if (slave->master->debug_level) {
char cur_state[EC_STATE_STRING_SIZE];
ec_state_string(slave->current_state, cur_state);
EC_DBG("Slave %i: online (%s).\n",
slave->ring_position, cur_state);
}
}
slave->online_state = new_state;
}
/*****************************************************************************/
/** /**
*/ */
...@@ -636,8 +688,8 @@ size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */ ...@@ -636,8 +688,8 @@ size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
off += sprintf(buffer + off, " ("); off += sprintf(buffer + off, " (");
off += ec_state_string(slave->requested_state, buffer + off); off += ec_state_string(slave->requested_state, buffer + off);
off += sprintf(buffer + off, ")\nFlags: %s, %s\n", off += sprintf(buffer + off, ")\nFlags: %s, %s\n",
slave->online ? "online" : "OFFLINE", slave->online_state == EC_SLAVE_ONLINE ? "online" : "OFFLINE",
slave->error_flag ? "ERROR" : "ok"); slave->error_flag ? "ERROR" : "ok");
off += sprintf(buffer + off, "Ring position: %i\n", off += sprintf(buffer + off, "Ring position: %i\n",
slave->ring_position); slave->ring_position);
off += sprintf(buffer + off, "Advanced position: %i:%i\n", off += sprintf(buffer + off, "Advanced position: %i:%i\n",
......
...@@ -72,6 +72,12 @@ typedef enum ...@@ -72,6 +72,12 @@ typedef enum
} }
ec_slave_state_t; ec_slave_state_t;
typedef enum {
EC_SLAVE_OFFLINE,
EC_SLAVE_ONLINE
}
ec_slave_online_state_t;
/*****************************************************************************/ /*****************************************************************************/
/** /**
...@@ -195,11 +201,11 @@ struct ec_slave ...@@ -195,11 +201,11 @@ struct ec_slave
struct kobject kobj; /**< kobject */ struct kobject kobj; /**< kobject */
ec_master_t *master; /**< master owning the slave */ ec_master_t *master; /**< master owning the slave */
ec_slave_state_t requested_state; /**< requested slave state */ ec_slave_state_t requested_state; /**< requested application state */
ec_slave_state_t current_state; /**< current slave state */ ec_slave_state_t current_state; /**< current application state */
unsigned int self_configured; /**< slave was configured by this master */ unsigned int self_configured; /**< slave was configured by this master */
unsigned int error_flag; /**< stop processing after an error */ unsigned int error_flag; /**< stop processing after an error */
unsigned int online; /**< non-zero, if the slave responds. */ unsigned int online_state; /**< online state */
// addresses // addresses
uint16_t ring_position; /**< ring position */ uint16_t ring_position; /**< ring position */
...@@ -266,6 +272,8 @@ int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *, ...@@ -266,6 +272,8 @@ int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *,
const ec_sii_sync_t *); const ec_sii_sync_t *);
void ec_slave_request_state(ec_slave_t *, ec_slave_state_t); void ec_slave_request_state(ec_slave_t *, ec_slave_state_t);
void ec_slave_set_state(ec_slave_t *, ec_slave_state_t);
void ec_slave_set_online_state(ec_slave_t *, ec_slave_online_state_t);
// SII categories // SII categories
int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *); int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment