Removed bus validation; slave configuration during realtime operation;
improved scan/config busy flags.
This commit is contained in:
parent
03e138323c
commit
80c1bf823d
7
NEWS
7
NEWS
|
|
@ -48,6 +48,7 @@ Changes in version 1.4.0:
|
|||
scheduled for reading and writing during realtime operation.
|
||||
- Exported ecrt_slave_config_sdo(), the generic Sdo configuration
|
||||
function.
|
||||
- Removed the bus_state and bus_tainted flags from ec_master_state_t.
|
||||
* Mapping of Pdo entries is now supported.
|
||||
* Current Pdo assignment/mapping is now read via CoE during bus scan, using
|
||||
direct Sdo access, independent of the dictionary.
|
||||
|
|
@ -58,6 +59,12 @@ Changes in version 1.4.0:
|
|||
- Added e1000 driver for kernel 2.6.24, thanks to Matthias Luescher.
|
||||
- Added alpha support for the Reaktek r8169 chipset, thanks to Scott
|
||||
Hassan.
|
||||
* Removed the "bus validation" routines. Slave scanning is now done any time
|
||||
the bus topology changes, even during realtime operation. Because of this,
|
||||
the bus_tainted flag was deprecated and removed.
|
||||
* Slave configuration is not done during ecrt_master_activate() any more, but
|
||||
later during realtime operation. The state of the configuration can be
|
||||
queried via the ecrt_domain_state() and ecrt_slave_config_state() functions.
|
||||
* Added support for slaves that do not support the LRW datagram type. Separate
|
||||
domains have to be used for inputs and output.
|
||||
* Allow gaps in PDO mapping read from CoE.
|
||||
|
|
|
|||
16
TODO
16
TODO
|
|
@ -8,31 +8,39 @@ $Id$
|
|||
|
||||
Version 1.4.0:
|
||||
|
||||
* Remove bus validation; make bus scanning possible at any time.
|
||||
* Remove self_configured flag to avoid unnecessary process data
|
||||
interruptions.
|
||||
* Replace Sysfs interface with cdev and a user space program
|
||||
to replace lsec; move a few sysfs attributes to proc.
|
||||
* Implement realtime interface via cdev.
|
||||
* Make scanning and configuration run parallel (each).
|
||||
* Improve slave config allow flag and completion object.
|
||||
* Mailbox state machine using toggle bits.
|
||||
* Mailbox protocol handlers.
|
||||
* READMEs for examples.
|
||||
* Remove get_cycles() calls and references to cpu_khz to increase
|
||||
portability.
|
||||
* Remove ecdb.h and let lsec output PDO information 'cut-and-pastable' for
|
||||
applications.
|
||||
* SDO write access in sysfs.
|
||||
* Update documentation.
|
||||
* Do not configure in ecrt_master_activate(), but later in the state machine.
|
||||
* Supply new ec_master_state_t.
|
||||
* Scanning of Sdo dictionary / writing EEPROM in OPERATION state.
|
||||
* Adapt remaining examples.
|
||||
* READMEs for examples.
|
||||
* Separate Pdo and Pdo entry classes.
|
||||
* Attach Pdo names.
|
||||
* Wait for bus scanning, even when link is not up at ecrt_request_master().
|
||||
* Implement ecrt_slave_config_state().
|
||||
* Add something like lsec -n to show numeric vendor IDs.
|
||||
* Remove the end state of the master state machine.
|
||||
* Rename the sdodict state to sdo_dictionary.
|
||||
* Check the position of the acknowledge state.
|
||||
* Remove the xmldev files.
|
||||
* Remove some debugging (add_sync_manager, clearing station addresses).
|
||||
* Rename "Scanning pdo mapping/configuration".
|
||||
* Separate CoE debugging.
|
||||
* Make ecrt_master_slave_config() return no error when slave is not present
|
||||
or invalid.
|
||||
* Remove ec_master_prepare().
|
||||
|
||||
Future issues:
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ digraph master {
|
|||
action_configure [shape=point,label=""]
|
||||
action_next_slave_state [shape=point,label=""]
|
||||
action_process_states [shape=point,label=""]
|
||||
action_addresses [shape=point,label=""]
|
||||
|
||||
start -> broadcast [weight=10]
|
||||
|
||||
|
|
@ -33,7 +32,6 @@ digraph master {
|
|||
action_process_states -> end
|
||||
|
||||
action_next_slave_state -> read_states
|
||||
action_next_slave_state -> validate_vendor
|
||||
action_next_slave_state -> action_process_states
|
||||
|
||||
//read_states -> error
|
||||
|
|
@ -43,20 +41,6 @@ digraph master {
|
|||
//acknowledge -> error
|
||||
acknowledge -> action_next_slave_state
|
||||
|
||||
//validate_vendor -> error
|
||||
validate_vendor -> validate_product
|
||||
|
||||
action_addresses -> end
|
||||
action_addresses -> rewrite_addresses
|
||||
|
||||
//validate_product -> error
|
||||
validate_product -> action_addresses
|
||||
validate_product -> validate_vendor
|
||||
|
||||
//rewrite_addresses -> error
|
||||
rewrite_addresses -> end
|
||||
rewrite_addresses -> action_addresses
|
||||
|
||||
//clear_addresses -> error
|
||||
clear_addresses -> scan_slaves
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@
|
|||
* - Added an Sdo access interface, working with Sdo requests. These can be
|
||||
* scheduled for reading and writing during realtime operation.
|
||||
* - Exported ecrt_slave_config_sdo(), the generic Sdo configuration function.
|
||||
* - Removed the bus_state and bus_tainted flags from ec_master_state_t.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
|
@ -148,28 +149,11 @@ typedef struct ec_sdo_request ec_sdo_request_t; /**< \see ec_sdo_request. */
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Bus state.
|
||||
*
|
||||
* This is used in ec_master_state_t.
|
||||
*
|
||||
* \deprecated
|
||||
* \todo remove
|
||||
*/
|
||||
typedef enum {
|
||||
EC_BUS_FAILURE = -1, /**< At least one configured slave is offline. */
|
||||
EC_BUS_OK /**< All configured slaves are online. */
|
||||
} ec_bus_state_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Master state.
|
||||
*
|
||||
* This is used for the output parameter of ecrt_master_state().
|
||||
*/
|
||||
typedef struct {
|
||||
ec_bus_state_t bus_state; /**< \see ec_bus_state_t */
|
||||
unsigned int bus_tainted; /**< Non-zero, if the bus topology differs from
|
||||
the requested configuration. */
|
||||
unsigned int slaves_responding; /**< Number of slaves in the bus. */
|
||||
} ec_master_state_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,9 +54,6 @@ void ec_fsm_master_state_start(ec_fsm_master_t *);
|
|||
void ec_fsm_master_state_broadcast(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_read_states(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_acknowledge(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_validate_vendor(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_validate_product(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_rewrite_addresses(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_configure_slave(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *);
|
||||
void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *);
|
||||
|
|
@ -84,8 +81,6 @@ void ec_fsm_master_init(ec_fsm_master_t *fsm, /**< master state machine */
|
|||
fsm->slaves_responding = 0;
|
||||
fsm->topology_change_pending = 0;
|
||||
fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
|
||||
fsm->validate = 0;
|
||||
fsm->tainted = 0;
|
||||
|
||||
// init sub-state-machines
|
||||
ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram);
|
||||
|
|
@ -212,16 +207,6 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
|
|||
EC_INFO("%u slave%s responding.\n",
|
||||
fsm->slaves_responding,
|
||||
fsm->slaves_responding == 1 ? "" : "s");
|
||||
|
||||
if (master->mode == EC_MASTER_MODE_OPERATION) {
|
||||
if (fsm->slaves_responding == master->slave_count) {
|
||||
fsm->validate = 1; // start validation later
|
||||
}
|
||||
else {
|
||||
EC_WARN("Invalid slave count. Bus in tainted state.\n");
|
||||
fsm->tainted = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// slave states changed?
|
||||
|
|
@ -236,15 +221,13 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
|
|||
down(&master->scan_sem);
|
||||
if (!master->allow_scan) {
|
||||
up(&master->scan_sem);
|
||||
}
|
||||
else {
|
||||
master->scan_state = EC_REQUEST_BUSY;
|
||||
} else {
|
||||
master->scan_busy = 1;
|
||||
up(&master->scan_sem);
|
||||
|
||||
// topology change when scan is allowed:
|
||||
// clear all slaves and scan the bus
|
||||
fsm->topology_change_pending = 0;
|
||||
fsm->tainted = 0;
|
||||
fsm->idle = 0;
|
||||
fsm->scan_jiffies = jiffies;
|
||||
|
||||
|
|
@ -258,7 +241,7 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
|
|||
|
||||
if (!master->slave_count) {
|
||||
// no slaves present -> finish state machine.
|
||||
master->scan_state = EC_REQUEST_SUCCESS;
|
||||
master->scan_busy = 0;
|
||||
wake_up_interruptible(&master->scan_queue);
|
||||
fsm->state = ec_fsm_master_state_end;
|
||||
return;
|
||||
|
|
@ -270,7 +253,7 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
|
|||
GFP_ATOMIC))) {
|
||||
EC_ERR("Failed to allocate slave %i!\n", i);
|
||||
ec_master_destroy_slaves(master);
|
||||
master->scan_state = EC_REQUEST_FAILURE;
|
||||
master->scan_busy = 0;
|
||||
wake_up_interruptible(&master->scan_queue);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
|
|
@ -279,7 +262,7 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
|
|||
if (ec_slave_init(slave, master, i, i + 1)) {
|
||||
// freeing of "slave" already done
|
||||
ec_master_destroy_slaves(master);
|
||||
master->scan_state = EC_REQUEST_FAILURE;
|
||||
master->scan_busy = 0;
|
||||
wake_up_interruptible(&master->scan_queue);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
|
|
@ -504,10 +487,7 @@ int ec_fsm_master_action_configure(
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (fsm->config_error)
|
||||
master->config_state = EC_REQUEST_FAILURE;
|
||||
else
|
||||
master->config_state = EC_REQUEST_SUCCESS;
|
||||
master->config_busy = 0;
|
||||
wake_up_interruptible(&master->config_queue);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -526,12 +506,12 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
|
|||
ec_master_t *master = fsm->master;
|
||||
ec_slave_t *slave;
|
||||
|
||||
// Start slave configuration, if it is allowed.
|
||||
down(&master->config_sem);
|
||||
if (!master->allow_config) {
|
||||
up(&master->config_sem);
|
||||
} else {
|
||||
master->config_state = EC_REQUEST_BUSY;
|
||||
fsm->config_error = 0;
|
||||
master->config_busy = 1;
|
||||
up(&master->config_sem);
|
||||
|
||||
// check for pending slave configurations
|
||||
|
|
@ -603,25 +583,6 @@ void ec_fsm_master_action_next_slave_state(ec_fsm_master_t *fsm
|
|||
}
|
||||
|
||||
// all slave states read
|
||||
|
||||
// check, if a bus validation has to be done
|
||||
if (fsm->validate) {
|
||||
fsm->validate = 0;
|
||||
list_for_each_entry(slave, &master->slaves, list) {
|
||||
if (slave->online_state == EC_SLAVE_ONLINE) continue;
|
||||
|
||||
// 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_USE_INCREMENT_ADDRESS);
|
||||
ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ec_fsm_master_action_process_states(fsm);
|
||||
}
|
||||
|
||||
|
|
@ -698,162 +659,6 @@ void ec_fsm_master_state_acknowledge(ec_fsm_master_t *fsm /**< master state mach
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Master state: VALIDATE_VENDOR.
|
||||
Validates the vendor ID of a slave.
|
||||
*/
|
||||
|
||||
void ec_fsm_master_state_validate_vendor(ec_fsm_master_t *fsm /**< master state machine */)
|
||||
{
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
|
||||
if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
|
||||
|
||||
if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
|
||||
fsm->slave->error_flag = 1;
|
||||
EC_ERR("Failed to validate vendor ID of slave %i.\n",
|
||||
slave->ring_position);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii.vendor_id) {
|
||||
EC_ERR("Slave %i has an invalid vendor ID!\n", slave->ring_position);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// vendor ID is ok. check product code.
|
||||
fsm->state = ec_fsm_master_state_validate_product;
|
||||
ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x000A,
|
||||
EC_FSM_SII_USE_INCREMENT_ADDRESS);
|
||||
ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Master action: ADDRESS.
|
||||
Looks for slave, that have lost their configuration and writes
|
||||
their station address, so that they can be reconfigured later.
|
||||
*/
|
||||
|
||||
void ec_fsm_master_action_addresses(ec_fsm_master_t *fsm /**< master state machine */)
|
||||
{
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
|
||||
while (fsm->slave->online_state == EC_SLAVE_ONLINE) {
|
||||
if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
|
||||
fsm->state = ec_fsm_master_state_end;
|
||||
return;
|
||||
}
|
||||
// check next slave
|
||||
fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
|
||||
}
|
||||
|
||||
if (fsm->master->debug_level)
|
||||
EC_DBG("Reinitializing slave %i.\n", fsm->slave->ring_position);
|
||||
|
||||
// write station address
|
||||
ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
|
||||
EC_WRITE_U16(datagram->data, fsm->slave->station_address);
|
||||
fsm->retries = EC_FSM_RETRIES;
|
||||
fsm->state = ec_fsm_master_state_rewrite_addresses;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Master state: VALIDATE_PRODUCT.
|
||||
Validates the product ID of a slave.
|
||||
*/
|
||||
|
||||
void ec_fsm_master_state_validate_product(ec_fsm_master_t *fsm /**< master state machine */)
|
||||
{
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
|
||||
if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
|
||||
|
||||
if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
|
||||
fsm->slave->error_flag = 1;
|
||||
EC_ERR("Failed to validate product code of slave %i.\n",
|
||||
slave->ring_position);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii.product_code) {
|
||||
EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
|
||||
EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii.product_code,
|
||||
EC_READ_U32(fsm->fsm_sii.value));
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// have all states been validated?
|
||||
if (slave->list.next == &fsm->master->slaves) {
|
||||
fsm->topology_change_pending = 0;
|
||||
fsm->tainted = 0;
|
||||
fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
|
||||
// start writing addresses to offline slaves
|
||||
ec_fsm_master_action_addresses(fsm);
|
||||
return;
|
||||
}
|
||||
|
||||
// validate next slave
|
||||
fsm->slave = list_entry(fsm->slave->list.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_USE_INCREMENT_ADDRESS);
|
||||
ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Master state: REWRITE ADDRESS.
|
||||
Checks, if the new station address has been written to the slave.
|
||||
*/
|
||||
|
||||
void ec_fsm_master_state_rewrite_addresses(ec_fsm_master_t *fsm
|
||||
/**< master state machine */
|
||||
)
|
||||
{
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
|
||||
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
|
||||
return;
|
||||
|
||||
if (datagram->state != EC_DATAGRAM_RECEIVED) {
|
||||
EC_ERR("Failed to receive address datagram for slave %i"
|
||||
" (datagram state %i).\n",
|
||||
slave->ring_position, datagram->state);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (datagram->working_counter != 1) {
|
||||
EC_ERR("Failed to write station address of slave %i: ",
|
||||
slave->ring_position);
|
||||
ec_datagram_print_wc_error(datagram);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
|
||||
fsm->state = ec_fsm_master_state_end;
|
||||
return;
|
||||
}
|
||||
|
||||
// check next slave
|
||||
fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
|
||||
// Write new station address to slave
|
||||
ec_fsm_master_action_addresses(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Master state: CLEAR ADDRESSES.
|
||||
*/
|
||||
|
|
@ -871,7 +676,7 @@ void ec_fsm_master_state_clear_addresses(
|
|||
if (datagram->state != EC_DATAGRAM_RECEIVED) {
|
||||
EC_ERR("Failed to receive address clearing datagram (state %i).\n",
|
||||
datagram->state);
|
||||
master->scan_state = EC_REQUEST_FAILURE;
|
||||
master->scan_busy = 0;
|
||||
wake_up_interruptible(&master->scan_queue);
|
||||
fsm->state = ec_fsm_master_state_error;
|
||||
return;
|
||||
|
|
@ -915,13 +720,11 @@ void ec_fsm_master_state_scan_slaves(
|
|||
if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate EoE handler memory for slave %u!\n",
|
||||
slave->ring_position);
|
||||
}
|
||||
else if (ec_eoe_init(eoe, slave)) {
|
||||
} else if (ec_eoe_init(eoe, slave)) {
|
||||
EC_ERR("Failed to init EoE handler for slave %u!\n",
|
||||
slave->ring_position);
|
||||
kfree(eoe);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
list_add_tail(&eoe->list, &master->eoe_handlers);
|
||||
}
|
||||
}
|
||||
|
|
@ -938,6 +741,9 @@ void ec_fsm_master_state_scan_slaves(
|
|||
EC_INFO("Bus scanning completed in %u ms.\n",
|
||||
(u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ);
|
||||
|
||||
master->scan_busy = 0;
|
||||
wake_up_interruptible(&master->scan_queue);
|
||||
|
||||
// Attach slave configurations
|
||||
ec_master_attach_slave_configs(master);
|
||||
|
||||
|
|
@ -946,9 +752,6 @@ void ec_fsm_master_state_scan_slaves(
|
|||
ec_master_eoe_start(master);
|
||||
#endif
|
||||
|
||||
master->scan_state = EC_REQUEST_SUCCESS;
|
||||
wake_up_interruptible(&master->scan_queue);
|
||||
|
||||
fsm->state = ec_fsm_master_state_end;
|
||||
}
|
||||
|
||||
|
|
@ -966,8 +769,9 @@ void ec_fsm_master_state_configure_slave(ec_fsm_master_t *fsm
|
|||
if (ec_fsm_slave_config_exec(&fsm->fsm_slave_config)) // execute slave's state machine
|
||||
return;
|
||||
|
||||
if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config))
|
||||
fsm->config_error = 1;
|
||||
if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config)) {
|
||||
// TODO: mark slave_config as failed.
|
||||
}
|
||||
|
||||
// configure next slave, if necessary
|
||||
if (ec_fsm_master_action_configure(fsm))
|
||||
|
|
|
|||
|
|
@ -90,10 +90,6 @@ struct ec_fsm_master {
|
|||
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 */
|
||||
unsigned int validate; /**< non-zero, if validation to do */
|
||||
unsigned int tainted; /**< non-zero, if the current bus topology does
|
||||
not meet the initial conditions */
|
||||
unsigned int config_error; /**< error during slave configuration */
|
||||
ec_slave_t *slave; /**< current slave */
|
||||
ec_sii_write_request_t *sii_request; /**< SII write request */
|
||||
off_t sii_index; /**< index to SII write request data */
|
||||
|
|
|
|||
|
|
@ -126,12 +126,12 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
|
||||
INIT_LIST_HEAD(&master->configs);
|
||||
|
||||
master->scan_state = EC_REQUEST_SUCCESS;
|
||||
master->scan_busy = 0;
|
||||
master->allow_scan = 1;
|
||||
init_MUTEX(&master->scan_sem);
|
||||
init_waitqueue_head(&master->scan_queue);
|
||||
|
||||
master->config_state = EC_REQUEST_SUCCESS;
|
||||
master->config_busy = 0;
|
||||
master->allow_config = 1;
|
||||
init_MUTEX(&master->config_sem);
|
||||
init_waitqueue_head(&master->config_queue);
|
||||
|
|
@ -146,7 +146,6 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
master->stats.corrupted = 0;
|
||||
master->stats.unmatched = 0;
|
||||
master->stats.output_jiffies = 0;
|
||||
master->pdo_slaves_offline = 0; // assume all Pdo slaves online
|
||||
master->frames_timed_out = 0;
|
||||
|
||||
for (i = 0; i < HZ; i++) {
|
||||
|
|
@ -442,37 +441,39 @@ int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
down(&master->config_sem);
|
||||
master->allow_config = 0; // temporarily disable slave configuration
|
||||
up(&master->config_sem);
|
||||
if (master->config_busy) {
|
||||
up(&master->config_sem);
|
||||
|
||||
// wait for slave configuration to complete
|
||||
if (wait_event_interruptible(master->config_queue,
|
||||
master->config_state != EC_REQUEST_BUSY)) {
|
||||
EC_INFO("Finishing slave configuration interrupted by signal.\n");
|
||||
goto out_allow;
|
||||
// wait for slave configuration to complete
|
||||
if (wait_event_interruptible(master->config_queue,
|
||||
!master->config_busy)) {
|
||||
EC_INFO("Finishing slave configuration interrupted by signal.\n");
|
||||
goto out_allow;
|
||||
}
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Waiting for pending slave configuration returned.\n");
|
||||
} else {
|
||||
up(&master->config_sem);
|
||||
}
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Waiting for pending slave configuration returned.\n");
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Disable scanning, current scan state: %u\n",
|
||||
master->scan_state);
|
||||
down(&master->scan_sem);
|
||||
master->allow_scan = 0; // 'lock' the slave list
|
||||
up(&master->scan_sem);
|
||||
if (!master->scan_busy) {
|
||||
up(&master->scan_sem);
|
||||
} else {
|
||||
up(&master->scan_sem);
|
||||
|
||||
if (master->scan_state == EC_REQUEST_BUSY) {
|
||||
// wait for slave scan to complete
|
||||
if (wait_event_interruptible(master->scan_queue,
|
||||
master->scan_state != EC_REQUEST_BUSY)) {
|
||||
if (wait_event_interruptible(master->scan_queue, !master->scan_busy)) {
|
||||
EC_INFO("Waiting for slave scan interrupted by signal.\n");
|
||||
goto out_allow;
|
||||
}
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Waiting for pending slave scan returned.\n");
|
||||
}
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Waiting for pending slave scan returned.\n");
|
||||
|
||||
// set states for all slaves
|
||||
list_for_each_entry(slave, &master->slaves, list) {
|
||||
ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
|
||||
|
|
@ -1005,11 +1006,6 @@ ssize_t ec_master_info(ec_master_t *master, /**< EtherCAT master */
|
|||
|
||||
off += sprintf(buffer + off, "\nSlaves: %i\n",
|
||||
master->slave_count);
|
||||
off += sprintf(buffer + off, "Status: %s\n",
|
||||
master->fsm.tainted ? "TAINTED" : "sane");
|
||||
off += sprintf(buffer + off, "Pdo slaves: %s\n",
|
||||
master->pdo_slaves_offline ? "INCOMPLETE" : "online");
|
||||
|
||||
off += sprintf(buffer + off, "\nDevices:\n");
|
||||
|
||||
down(&master->device_sem);
|
||||
|
|
@ -1349,26 +1345,9 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
domain_offset += domain->data_size;
|
||||
}
|
||||
|
||||
// request slave configuration
|
||||
down(&master->config_sem);
|
||||
master->allow_config = 1; // request the current configuration
|
||||
up(&master->config_sem);
|
||||
master->allow_scan = 1; // allow re-scanning on topology change
|
||||
|
||||
if (master->main_device.link_state) {
|
||||
// wait for configuration to complete
|
||||
master->config_state = EC_REQUEST_BUSY;
|
||||
if (wait_event_interruptible(master->config_queue,
|
||||
master->config_state != EC_REQUEST_BUSY)) {
|
||||
EC_INFO("Waiting for configuration interrupted by signal.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (master->config_state != EC_REQUEST_SUCCESS) {
|
||||
EC_ERR("Failed to configure slaves.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// restart EoE process and master thread with new locking
|
||||
#ifdef EC_EOE
|
||||
ec_master_eoe_stop(master);
|
||||
|
|
@ -1390,6 +1369,7 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
EC_ERR("Failed to start master thread!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef EC_EOE
|
||||
ec_master_eoe_start(master);
|
||||
#endif
|
||||
|
|
@ -1532,10 +1512,6 @@ void ecrt_master_callbacks(ec_master_t *master, int (*request_cb)(void *),
|
|||
|
||||
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
|
||||
{
|
||||
state->bus_state =
|
||||
(master->pdo_slaves_offline || master->frames_timed_out)
|
||||
? EC_BUS_FAILURE : EC_BUS_OK;
|
||||
state->bus_tainted = master->fsm.tainted;
|
||||
state->slaves_responding = master->fsm.slaves_responding;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,14 +104,14 @@ struct ec_master {
|
|||
struct list_head configs; /**< Bus configuration list. */
|
||||
unsigned int configs_attached; /**< Slave configurations were attached. */
|
||||
|
||||
ec_request_state_t scan_state; /**< current scanning state */
|
||||
unsigned int scan_busy; /**< Current scan state. */
|
||||
unsigned int allow_scan; /**< non-zero, if slave scanning is allowed */
|
||||
struct semaphore scan_sem; /**< semaphore protecting the scan_state
|
||||
variable and the allow_scan flag */
|
||||
wait_queue_head_t scan_queue; /**< queue for processes that wait for
|
||||
slave scanning */
|
||||
|
||||
ec_request_state_t config_state; /**< state of slave configuration */
|
||||
unsigned int config_busy; /**< State of slave configuration. */
|
||||
unsigned int allow_config; /**< non-zero, if slave scanning is allowed */
|
||||
struct semaphore config_sem; /**< semaphore protecting the config_state
|
||||
variable and the allow_config flag */
|
||||
|
|
@ -125,9 +125,6 @@ struct ec_master {
|
|||
|
||||
int debug_level; /**< master debug level */
|
||||
ec_stats_t stats; /**< cyclic statistics */
|
||||
unsigned int pdo_slaves_offline; /**< number of slaves, for which Pdos
|
||||
were registered and that are offline
|
||||
(used for bus status) */
|
||||
unsigned int frames_timed_out; /**< there were frame timeouts in the last
|
||||
call to ecrt_master_receive() */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue