Added configure option for redundancy (--with-devices).
--- a/TODO Fri Nov 30 15:24:38 2012 +0100
+++ b/TODO Fri Nov 30 20:15:31 2012 +0100
@@ -8,6 +8,15 @@
-------------------------------------------------------------------------------
+Version 1.5.2:
+
+• Try redundancy with more then 2 devices.
+• Document --with-devices.
+• Document RTDM interface.
+• Set the "Cyclic Generation Start Time" based on the slave's
+ "System Time" register instead of using the application time.
+• Add ecrt_slave_config_reg_pdo_entry_by_pos().
+
Future issues:
* Fix link detection in generic driver.
@@ -19,7 +28,6 @@
* Only output watchdog config if not default.
* Implement CompleteAccess for SDO uploads.
* Output warning when send_ext() is called in illegal context.
-* Change SDO index at runtime for SDO request.
* Implement ecrt_slave_config_request_state().
* Remove default buffer size in SDO upload.
* Override sync manager size?
@@ -29,8 +37,6 @@
- Skip setting system time offset when application detached.
- How to use the SYNC1 shift time?
- Do not output graph, if topology calculation failed.
- - Set the "Cyclic Generation Start Time" based on the slave's
- "System Time" register instead of using the application time.
- Check if register 0x0980 is working, to avoid clearing it when
configuring.
* Mailbox protocol handlers.
@@ -43,7 +49,6 @@
* Separate CoE debugging.
* Evaluate EEPROM contents after writing.
* Optimize alignment of process data.
-* Redundancy with 2 network adapters.
* Interface/buffers for asynchronous domain IO.
* Make scanning and configuration run parallel (each).
* ethercat tool:
--- a/configure.ac Fri Nov 30 15:24:38 2012 +0100
+++ b/configure.ac Fri Nov 30 20:15:31 2012 +0100
@@ -782,6 +782,38 @@
fi
#------------------------------------------------------------------------------
+# Redundancy (number of devices)
+#------------------------------------------------------------------------------
+
+AC_ARG_WITH([devices],
+ AC_HELP_STRING(
+ [--with-devices=<NUMBER>],
+ [Number of Ethernet devices per master. Default: 1]
+ ),
+ [
+ devices=[$withval]
+ ],
+ [
+ devices=1
+ ]
+)
+
+AC_MSG_CHECKING([for number of Ethernet devices])
+
+if test "${devices}" -lt 1; then
+ AC_MSG_ERROR([Number must be greater zero!])
+else
+ if test "${devices}" -gt 1; then
+ AC_MSG_RESULT([$devices (Redundancy enabled)])
+ else
+ AC_MSG_RESULT([$devices (Redundancy disabled)])
+ fi
+fi
+
+AC_DEFINE_UNQUOTED([EC_MAX_NUM_DEVICES], $devices,
+ [Max. number of Ethernet devices per master])
+
+#------------------------------------------------------------------------------
AC_CONFIG_FILES([
Doxyfile
--- a/master/datagram_pair.c Fri Nov 30 15:24:38 2012 +0100
+++ b/master/datagram_pair.c Fri Nov 30 20:15:31 2012 +0100
@@ -58,29 +58,34 @@
INIT_LIST_HEAD(&pair->list);
pair->domain = domain;
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
ec_datagram_init(&pair->datagrams[dev_idx]);
snprintf(pair->datagrams[dev_idx].name,
EC_DATAGRAM_NAME_SIZE, "domain%u-%u-%s", domain->index,
- logical_offset, ec_device_names[dev_idx]);
+ logical_offset, ec_device_names[dev_idx != 0]);
pair->datagrams[dev_idx].device_index = dev_idx;
}
pair->expected_working_counter = 0U;
- /* backup datagram has its own memory */
- ret = ec_datagram_prealloc(&pair->datagrams[EC_DEVICE_BACKUP],
- data_size);
- if (ret) {
- goto out_datagrams;
+ for (dev_idx = EC_DEVICE_BACKUP;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ /* backup datagrams have their own memory */
+ ret = ec_datagram_prealloc(&pair->datagrams[dev_idx], data_size);
+ if (ret) {
+ goto out_datagrams;
+ }
}
+#if EC_MAX_NUM_DEVICES > 1
if (!(pair->send_buffer = kmalloc(data_size, GFP_KERNEL))) {
EC_MASTER_ERR(domain->master,
"Failed to allocate domain send buffer!\n");
ret = -ENOMEM;
goto out_datagrams;
}
+#endif
/* The ec_datagram_lxx() calls below can not fail, because either the
* datagram has external memory or it is preallocated. */
@@ -88,8 +93,12 @@
if (used[EC_DIR_OUTPUT] && used[EC_DIR_INPUT]) { // inputs and outputs
ec_datagram_lrw_ext(&pair->datagrams[EC_DEVICE_MAIN],
logical_offset, data_size, data);
- ec_datagram_lrw(&pair->datagrams[EC_DEVICE_BACKUP],
- logical_offset, data_size);
+
+ for (dev_idx = EC_DEVICE_BACKUP;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ ec_datagram_lrw(&pair->datagrams[dev_idx],
+ logical_offset, data_size);
+ }
// If LRW is used, output FMMUs increment the working counter by 2,
// while input FMMUs increment it by 1.
@@ -98,27 +107,35 @@
} else if (used[EC_DIR_OUTPUT]) { // outputs only
ec_datagram_lwr_ext(&pair->datagrams[EC_DEVICE_MAIN],
logical_offset, data_size, data);
- ec_datagram_lwr(&pair->datagrams[EC_DEVICE_BACKUP],
- logical_offset, data_size);
+ for (dev_idx = EC_DEVICE_BACKUP;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ ec_datagram_lwr(&pair->datagrams[dev_idx],
+ logical_offset, data_size);
+ }
pair->expected_working_counter = used[EC_DIR_OUTPUT];
} else { // inputs only (or nothing)
ec_datagram_lrd_ext(&pair->datagrams[EC_DEVICE_MAIN],
logical_offset, data_size, data);
- ec_datagram_lrd(&pair->datagrams[EC_DEVICE_BACKUP],
- logical_offset, data_size);
+ for (dev_idx = EC_DEVICE_BACKUP;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ ec_datagram_lrd(&pair->datagrams[dev_idx], logical_offset,
+ data_size);
+ }
pair->expected_working_counter = used[EC_DIR_INPUT];
}
- for (dev_idx = 0; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
ec_datagram_zero(&pair->datagrams[dev_idx]);
}
return 0;
out_datagrams:
- for (dev_idx = 0; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
ec_datagram_clear(&pair->datagrams[dev_idx]);
}
@@ -135,13 +152,17 @@
{
unsigned int dev_idx;
- for (dev_idx = 0; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(pair->domain->master);
+ dev_idx++) {
ec_datagram_clear(&pair->datagrams[dev_idx]);
}
+#if EC_MAX_NUM_DEVICES > 1
if (pair->send_buffer) {
kfree(pair->send_buffer);
}
+#endif
}
/*****************************************************************************/
@@ -150,13 +171,14 @@
*/
uint16_t ec_datagram_pair_process(
ec_datagram_pair_t *pair, /**< Datagram pair. */
- uint16_t wc_sum[EC_NUM_DEVICES] /**< Working counter sums. */
+ uint16_t wc_sum[] /**< Working counter sums. */
)
{
unsigned int dev_idx;
uint16_t pair_wc = 0;
- for (dev_idx = 0; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = 0; dev_idx < ec_master_num_devices(pair->domain->master);
+ dev_idx++) {
ec_datagram_t *datagram = &pair->datagrams[dev_idx];
ec_datagram_output_stats(datagram);
--- a/master/datagram_pair.h Fri Nov 30 15:24:38 2012 +0100
+++ b/master/datagram_pair.h Fri Nov 30 20:15:31 2012 +0100
@@ -49,9 +49,10 @@
typedef struct {
struct list_head list; /**< List header. */
ec_domain_t *domain;
- ec_datagram_t datagrams[EC_NUM_DEVICES]; /**< Main and backup datagram.
- */
+ ec_datagram_t datagrams[EC_MAX_NUM_DEVICES]; /**< Datagrams. */
+#if EC_MAX_NUM_DEVICES > 1
uint8_t *send_buffer;
+#endif
unsigned int expected_working_counter; /**< Expectord working conter. */
} ec_datagram_pair_t;
@@ -61,8 +62,7 @@
uint8_t *, size_t, const unsigned int []);
void ec_datagram_pair_clear(ec_datagram_pair_t *);
-uint16_t ec_datagram_pair_process(ec_datagram_pair_t *,
- uint16_t[EC_NUM_DEVICES]);
+uint16_t ec_datagram_pair_process(ec_datagram_pair_t *, uint16_t[]);
/*****************************************************************************/
--- a/master/device.c Fri Nov 30 15:24:38 2012 +0100
+++ b/master/device.c Fri Nov 30 20:15:31 2012 +0100
@@ -81,10 +81,12 @@
device->tx_ring_index = 0;
#ifdef EC_DEBUG_IF
- if (device == &master->main_device)
+ if (device == &master->devices[EC_DEVICE_MAIN]) {
mb = 'm';
- else if (device == &master->backup_device)
+ }
+ else {
mb = 'b';
+ }
sprintf(ifname, "ecdbg%c%u", mb, master->index);
@@ -136,7 +138,9 @@
{
unsigned int i;
- if (device->open) ec_device_close(device);
+ if (device->open) {
+ ec_device_close(device);
+ }
for (i = 0; i < EC_TX_RING_SIZE; i++)
dev_kfree_skb(device->tx_skb[i]);
#ifdef EC_DEBUG_IF
@@ -541,6 +545,7 @@
{
int ret;
ec_master_t *master = device->master;
+ unsigned int all_open = 1, dev_idx;
ret = ec_device_open(device);
if (ret) {
@@ -548,9 +553,15 @@
return ret;
}
- if (master->devices[EC_DEVICE_MAIN].open &&
- (ec_mac_is_zero(master->macs[EC_DEVICE_BACKUP]) ||
- master->devices[EC_DEVICE_BACKUP].open)) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(device->master); dev_idx++) {
+ if (!master->devices[dev_idx].open) {
+ all_open = 0;
+ break;
+ }
+ }
+
+ if (all_open) {
ret = ec_master_enter_idle_phase(device->master);
if (ret) {
EC_MASTER_ERR(device->master, "Failed to enter IDLE phase!\n");
--- a/master/domain.c Fri Nov 30 15:24:38 2012 +0100
+++ b/master/domain.c Fri Nov 30 20:15:31 2012 +0100
@@ -59,6 +59,8 @@
unsigned int index /**< Index. */
)
{
+ unsigned int dev_idx;
+
domain->master = master;
domain->index = index;
INIT_LIST_HEAD(&domain->fmmu_configs);
@@ -67,8 +69,10 @@
domain->data_origin = EC_ORIG_INTERNAL;
domain->logical_base_address = 0x00000000;
INIT_LIST_HEAD(&domain->datagram_pairs);
- domain->working_counter[EC_DEVICE_MAIN] = 0x0000;
- domain->working_counter[EC_DEVICE_BACKUP] = 0x0000;
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
+ domain->working_counter[dev_idx] = 0x0000;
+ }
domain->expected_working_counter = 0x0000;
domain->working_counter_changes = 0;
domain->redundancy_active = 0;
@@ -355,6 +359,8 @@
/*****************************************************************************/
+#if EC_MAX_NUM_DEVICES > 1
+
/** Process received data.
*/
int data_changed(
@@ -377,6 +383,8 @@
return 0;
}
+#endif
+
/******************************************************************************
* Application interface
*****************************************************************************/
@@ -443,15 +451,17 @@
void ecrt_domain_process(ec_domain_t *domain)
{
- uint16_t wc_sum[EC_NUM_DEVICES] = {};
+ uint16_t wc_sum[EC_MAX_NUM_DEVICES] = {}, redundant_wc, wc_total;
ec_datagram_pair_t *pair;
- ec_datagram_t *main_datagram, *backup_datagram;
+ ec_datagram_t *main_datagram;
uint32_t logical_datagram_address;
size_t datagram_size;
uint16_t datagram_pair_wc;
- unsigned int datagram_offset;
+ unsigned int dev_idx, wc_change;
+#if EC_MAX_NUM_DEVICES > 1
ec_fmmu_config_t *fmmu =
list_first_entry(&domain->fmmu_configs, ec_fmmu_config_t, list);
+#endif
unsigned int redundancy;
#if DEBUG_REDUNDANCY
@@ -461,7 +471,6 @@
list_for_each_entry(pair, &domain->datagram_pairs, list) {
main_datagram = &pair->datagrams[EC_DEVICE_MAIN];
- backup_datagram = &pair->datagrams[EC_DEVICE_BACKUP];
logical_datagram_address = EC_READ_U32(main_datagram->address);
datagram_size = main_datagram->data_size;
@@ -472,8 +481,16 @@
datagram_pair_wc = ec_datagram_pair_process(pair, wc_sum);
- /* Go through all FMMU configs to detect data changes. */
+#if EC_MAX_NUM_DEVICES > 1
+ if (ec_master_num_devices(domain->master) < 2) {
+ continue;
+ }
+
+ /* Redundancy: Go through all FMMU configs to detect data changes. */
list_for_each_entry_from(fmmu, &domain->fmmu_configs, list) {
+ unsigned int datagram_offset;
+ ec_datagram_t *backup_datagram =
+ &pair->datagrams[EC_DEVICE_BACKUP];
if (fmmu->dir != EC_DIR_INPUT) {
continue;
@@ -533,9 +550,16 @@
#endif
}
}
- }
-
- redundancy = wc_sum[EC_DEVICE_BACKUP] > 0;
+#endif // EC_MAX_NUM_DEVICES > 1
+ }
+
+ redundant_wc = 0;
+ for (dev_idx = EC_DEVICE_BACKUP;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ redundant_wc += wc_sum[dev_idx];
+ }
+
+ redundancy = redundant_wc > 0;
if (redundancy != domain->redundancy_active) {
if (redundancy) {
EC_MASTER_WARN(domain->master,
@@ -549,12 +573,19 @@
domain->redundancy_active = redundancy;
}
- if ((wc_sum[EC_DEVICE_MAIN] != domain->working_counter[EC_DEVICE_MAIN])
- || (wc_sum[EC_DEVICE_BACKUP]
- != domain->working_counter[EC_DEVICE_BACKUP])) {
+ wc_change = 0;
+ wc_total = 0;
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ if (wc_sum[dev_idx] != domain->working_counter[dev_idx]) {
+ wc_change = 1;
+ domain->working_counter[dev_idx] = wc_sum[dev_idx];
+ }
+ wc_total += wc_sum[dev_idx];
+ }
+
+ if (wc_change) {
domain->working_counter_changes++;
- domain->working_counter[EC_DEVICE_MAIN] = wc_sum[EC_DEVICE_MAIN];
- domain->working_counter[EC_DEVICE_BACKUP] = wc_sum[EC_DEVICE_BACKUP];
}
if (domain->working_counter_changes &&
@@ -562,20 +593,28 @@
domain->notify_jiffies = jiffies;
if (domain->working_counter_changes == 1) {
EC_MASTER_INFO(domain->master, "Domain %u: Working counter"
- " changed to %u/%u (%u+%u).\n", domain->index,
- domain->working_counter[EC_DEVICE_MAIN] +
- domain->working_counter[EC_DEVICE_BACKUP],
- domain->expected_working_counter,
- wc_sum[EC_DEVICE_MAIN], wc_sum[EC_DEVICE_BACKUP]);
+ " changed to %u/%u", domain->index,
+ wc_total, domain->expected_working_counter);
} else {
EC_MASTER_INFO(domain->master, "Domain %u: %u working counter"
- " changes - now %u/%u (%u+%u).\n", domain->index,
+ " changes - now %u/%u", domain->index,
domain->working_counter_changes,
- domain->working_counter[EC_DEVICE_MAIN] +
- domain->working_counter[EC_DEVICE_BACKUP],
- domain->expected_working_counter,
- wc_sum[EC_DEVICE_MAIN], wc_sum[EC_DEVICE_BACKUP]);
- }
+ wc_total, domain->expected_working_counter);
+ }
+ if (ec_master_num_devices(domain->master) > 1) {
+ printk(" (");
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(domain->master);
+ dev_idx++) {
+ printk("%u", domain->working_counter[dev_idx]);
+ if (dev_idx + 1 < ec_master_num_devices(domain->master)) {
+ printk("+");
+ }
+ }
+ printk(")");
+ }
+ printk(".\n");
+
domain->working_counter_changes = 0;
}
}
@@ -589,17 +628,21 @@
list_for_each_entry(datagram_pair, &domain->datagram_pairs, list) {
+#if EC_MAX_NUM_DEVICES > 1
/* copy main data to send buffer */
memcpy(datagram_pair->send_buffer,
datagram_pair->datagrams[EC_DEVICE_MAIN].data,
datagram_pair->datagrams[EC_DEVICE_MAIN].data_size);
+#endif
+ ec_master_queue_datagram(domain->master,
+ &datagram_pair->datagrams[EC_DEVICE_MAIN]);
/* copy main data to backup datagram */
- memcpy(datagram_pair->datagrams[EC_DEVICE_BACKUP].data,
- datagram_pair->datagrams[EC_DEVICE_MAIN].data,
- datagram_pair->datagrams[EC_DEVICE_MAIN].data_size);
-
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_BACKUP;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ memcpy(datagram_pair->datagrams[dev_idx].data,
+ datagram_pair->datagrams[EC_DEVICE_MAIN].data,
+ datagram_pair->datagrams[EC_DEVICE_MAIN].data_size);
ec_master_queue_datagram(domain->master,
&datagram_pair->datagrams[dev_idx]);
}
@@ -610,9 +653,15 @@
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
{
- state->working_counter =
- domain->working_counter[EC_DEVICE_MAIN]
- + domain->working_counter[EC_DEVICE_BACKUP];
+ unsigned int dev_idx;
+ uint16_t wc = 0;
+
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
+ wc += domain->working_counter[dev_idx];
+ }
+
+ state->working_counter = wc;
if (state->working_counter) {
if (state->working_counter == domain->expected_working_counter) {
--- a/master/domain.h Fri Nov 30 15:24:38 2012 +0100
+++ b/master/domain.h Fri Nov 30 20:15:31 2012 +0100
@@ -65,8 +65,7 @@
process data. */
struct list_head datagram_pairs; /**< Datagrams pairs (main/backup) for
process data exchange. */
-
- uint16_t working_counter[EC_NUM_DEVICES]; /**< Last working counter
+ uint16_t working_counter[EC_MAX_NUM_DEVICES]; /**< Last working counter
values. */
uint16_t expected_working_counter; /**< Expected working counter. */
unsigned int working_counter_changes; /**< Working counter changes
--- a/master/fsm_master.c Fri Nov 30 15:24:38 2012 +0100
+++ b/master/fsm_master.c Fri Nov 30 20:15:31 2012 +0100
@@ -86,7 +86,8 @@
fsm->state = ec_fsm_master_state_start;
fsm->idle = 0;
fsm->dev_idx = EC_DEVICE_MAIN;
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
fsm->link_state[dev_idx] = 0;
fsm->slaves_responding[dev_idx] = 0;
fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN;
@@ -209,7 +210,7 @@
fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter;
EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n",
fsm->slaves_responding[fsm->dev_idx],
- ec_device_names[fsm->dev_idx]);
+ ec_device_names[fsm->dev_idx != 0]);
}
if (fsm->link_state[fsm->dev_idx] &&
@@ -218,7 +219,7 @@
EC_MASTER_DBG(master, 1, "Master state machine detected "
"link down on %s device. Clearing slave list.\n",
- ec_device_names[fsm->dev_idx]);
+ ec_device_names[fsm->dev_idx != 0]);
#ifdef EC_EOE
ec_master_eoe_stop(master);
@@ -226,7 +227,8 @@
#endif
ec_master_clear_slaves(master);
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(master); dev_idx++) {
fsm->slave_states[dev_idx] = 0x00;
fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on
next link up. */
@@ -243,14 +245,14 @@
fsm->slave_states[fsm->dev_idx] = states;
ec_state_string(states, state_str, 1);
EC_MASTER_INFO(master, "Slave states on %s device: %s.\n",
- ec_device_names[fsm->dev_idx], state_str);
+ ec_device_names[fsm->dev_idx != 0], state_str);
}
} else {
fsm->slave_states[fsm->dev_idx] = 0x00;
}
fsm->dev_idx++;
- if (fsm->dev_idx < EC_NUM_DEVICES) {
+ if (fsm->dev_idx < ec_master_num_devices(master)) {
// check number of responding slaves on next device
fsm->state = ec_fsm_master_state_start;
fsm->state(fsm); // execute immediately
@@ -279,8 +281,8 @@
#endif
ec_master_clear_slaves(master);
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES;
- dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(master); dev_idx++) {
count += fsm->slaves_responding[dev_idx];
}
@@ -708,7 +710,7 @@
if (datagram->state != EC_DATAGRAM_RECEIVED) {
EC_MASTER_ERR(master, "Failed to receive address"
" clearing datagram on %s link: ",
- ec_device_names[fsm->dev_idx]);
+ ec_device_names[fsm->dev_idx != 0]);
ec_datagram_print_state(datagram);
master->scan_busy = 0;
wake_up_interruptible(&master->scan_queue);
@@ -719,13 +721,13 @@
if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:"
" Cleared %u of %u",
- ec_device_names[fsm->dev_idx], datagram->working_counter,
+ ec_device_names[fsm->dev_idx != 0], datagram->working_counter,
fsm->slaves_responding[fsm->dev_idx]);
}
EC_MASTER_DBG(master, 1, "Sending broadcast-write"
" to measure transmission delays on %s link.\n",
- ec_device_names[fsm->dev_idx]);
+ ec_device_names[fsm->dev_idx != 0]);
ec_datagram_bwr(datagram, 0x0900, 1);
ec_datagram_zero(datagram);
@@ -750,7 +752,7 @@
if (datagram->state != EC_DATAGRAM_RECEIVED) {
EC_MASTER_ERR(master, "Failed to receive delay measuring datagram"
- " on %s link: ", ec_device_names[fsm->dev_idx]);
+ " on %s link: ", ec_device_names[fsm->dev_idx != 0]);
ec_datagram_print_state(datagram);
master->scan_busy = 0;
wake_up_interruptible(&master->scan_queue);
@@ -760,13 +762,13 @@
EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring"
" on %s link.\n",
- datagram->working_counter, ec_device_names[fsm->dev_idx]);
+ datagram->working_counter, ec_device_names[fsm->dev_idx != 0]);
do {
fsm->dev_idx++;
- } while (fsm->dev_idx < EC_NUM_DEVICES &&
+ } while (fsm->dev_idx < ec_master_num_devices(master) &&
!fsm->slaves_responding[fsm->dev_idx]);
- if (fsm->dev_idx < EC_NUM_DEVICES) {
+ if (fsm->dev_idx < ec_master_num_devices(master)) {
ec_fsm_master_enter_clear_addresses(fsm);
return;
}
@@ -777,7 +779,7 @@
fsm->slave = master->slaves;
EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
fsm->slave->ring_position,
- ec_device_names[fsm->slave->device_index]);
+ ec_device_names[fsm->slave->device_index != 0]);
fsm->state = ec_fsm_master_state_scan_slave;
ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
@@ -823,7 +825,7 @@
if (fsm->slave < master->slaves + master->slave_count) {
EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
fsm->slave->ring_position,
- ec_device_names[fsm->slave->device_index]);
+ ec_device_names[fsm->slave->device_index != 0]);
ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
fsm->datagram->device_index = fsm->slave->device_index;
--- a/master/fsm_master.h Fri Nov 30 15:24:38 2012 +0100
+++ b/master/fsm_master.h Fri Nov 30 20:15:31 2012 +0100
@@ -105,15 +105,15 @@
*/
int idle; /**< state machine is in idle phase */
unsigned long scan_jiffies; /**< beginning of slave scanning */
- uint8_t link_state[EC_NUM_DEVICES]; /**< Last link state for every device.
- */
- unsigned int slaves_responding[EC_NUM_DEVICES]; /**< Number of responding
- slaves for every device.
- */
+ uint8_t link_state[EC_MAX_NUM_DEVICES]; /**< Last link state for every
+ device. */
+ unsigned int slaves_responding[EC_MAX_NUM_DEVICES]; /**< Number of
+ responding slaves
+ for every device. */
unsigned int rescan_required; /**< A bus rescan is required. */
- ec_slave_state_t slave_states[EC_NUM_DEVICES]; /**< AL states of
- responding slaves for
- every device. */
+ ec_slave_state_t slave_states[EC_MAX_NUM_DEVICES]; /**< AL states of
+ responding slaves for
+ every device. */
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 */
--- a/master/globals.h Fri Nov 30 15:24:38 2012 +0100
+++ b/master/globals.h Fri Nov 30 20:15:31 2012 +0100
@@ -200,11 +200,10 @@
*/
typedef enum {
EC_DEVICE_MAIN, /**< Main device. */
- EC_DEVICE_BACKUP, /**< Backup device */
- EC_NUM_DEVICES /**< Number of devices. */
+ EC_DEVICE_BACKUP /**< Backup device */
} ec_device_index_t;
-extern const char *ec_device_names[EC_NUM_DEVICES];
+extern const char *ec_device_names[2]; // only main and backup!
/*****************************************************************************/
--- a/master/ioctl.c Fri Nov 30 15:24:38 2012 +0100
+++ b/master/ioctl.c Fri Nov 30 20:15:31 2012 +0100
@@ -93,80 +93,86 @@
void *arg /**< Userspace address to store the results. */
)
{
- ec_ioctl_master_t data;
- unsigned int i, j;
-
- if (down_interruptible(&master->master_sem))
+ ec_ioctl_master_t io;
+ unsigned int dev_idx, j;
+
+ if (down_interruptible(&master->master_sem)) {
return -EINTR;
-
- data.slave_count = master->slave_count;
- data.config_count = ec_master_config_count(master);
- data.domain_count = ec_master_domain_count(master);
+ }
+
+ io.slave_count = master->slave_count;
+ io.config_count = ec_master_config_count(master);
+ io.domain_count = ec_master_domain_count(master);
#ifdef EC_EOE
- data.eoe_handler_count = ec_master_eoe_handler_count(master);
+ io.eoe_handler_count = ec_master_eoe_handler_count(master);
#endif
- data.phase = (uint8_t) master->phase;
- data.active = (uint8_t) master->active;
- data.scan_busy = master->scan_busy;
+ io.phase = (uint8_t) master->phase;
+ io.active = (uint8_t) master->active;
+ io.scan_busy = master->scan_busy;
up(&master->master_sem);
- if (down_interruptible(&master->device_sem))
+ if (down_interruptible(&master->device_sem)) {
return -EINTR;
-
- for (i = 0; i < EC_NUM_DEVICES; i++) {
- ec_device_t *device = &master->devices[i];
+ }
+
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(master); dev_idx++) {
+ ec_device_t *device = &master->devices[dev_idx];
if (device->dev) {
- memcpy(data.devices[i].address,
- device->dev->dev_addr, ETH_ALEN);
+ memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
+ ETH_ALEN);
} else {
- memcpy(data.devices[i].address, master->macs[i], ETH_ALEN);
+ memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
+ ETH_ALEN);
}
- data.devices[i].attached = device->dev ? 1 : 0;
- data.devices[i].link_state = device->link_state ? 1 : 0;
- data.devices[i].tx_count = device->tx_count;
- data.devices[i].rx_count = device->rx_count;
- data.devices[i].tx_bytes = device->tx_bytes;
- data.devices[i].rx_bytes = device->rx_bytes;
- data.devices[i].tx_errors = device->tx_errors;
+ io.devices[dev_idx].attached = device->dev ? 1 : 0;
+ io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
+ io.devices[dev_idx].tx_count = device->tx_count;
+ io.devices[dev_idx].rx_count = device->rx_count;
+ io.devices[dev_idx].tx_bytes = device->tx_bytes;
+ io.devices[dev_idx].rx_bytes = device->rx_bytes;
+ io.devices[dev_idx].tx_errors = device->tx_errors;
for (j = 0; j < EC_RATE_COUNT; j++) {
- data.devices[i].tx_frame_rates[j] =
+ io.devices[dev_idx].tx_frame_rates[j] =
device->tx_frame_rates[j];
- data.devices[i].rx_frame_rates[j] =
+ io.devices[dev_idx].rx_frame_rates[j] =
device->rx_frame_rates[j];
- data.devices[i].tx_byte_rates[j] =
+ io.devices[dev_idx].tx_byte_rates[j] =
device->tx_byte_rates[j];
- data.devices[i].rx_byte_rates[j] =
+ io.devices[dev_idx].rx_byte_rates[j] =
device->rx_byte_rates[j];
}
}
-
- data.tx_count = master->device_stats.tx_count;
- data.rx_count = master->device_stats.rx_count;
- data.tx_bytes = master->device_stats.tx_bytes;
- data.rx_bytes = master->device_stats.rx_bytes;
- for (i = 0; i < EC_RATE_COUNT; i++) {
- data.tx_frame_rates[i] =
- master->device_stats.tx_frame_rates[i];
- data.rx_frame_rates[i] =
- master->device_stats.rx_frame_rates[i];
- data.tx_byte_rates[i] =
- master->device_stats.tx_byte_rates[i];
- data.rx_byte_rates[i] =
- master->device_stats.rx_byte_rates[i];
- data.loss_rates[i] =
- master->device_stats.loss_rates[i];
+ io.num_devices = ec_master_num_devices(master);
+
+ io.tx_count = master->device_stats.tx_count;
+ io.rx_count = master->device_stats.rx_count;
+ io.tx_bytes = master->device_stats.tx_bytes;
+ io.rx_bytes = master->device_stats.rx_bytes;
+ for (j = 0; j < EC_RATE_COUNT; j++) {
+ io.tx_frame_rates[j] =
+ master->device_stats.tx_frame_rates[j];
+ io.rx_frame_rates[j] =
+ master->device_stats.rx_frame_rates[j];
+ io.tx_byte_rates[j] =
+ master->device_stats.tx_byte_rates[j];
+ io.rx_byte_rates[j] =
+ master->device_stats.rx_byte_rates[j];
+ io.loss_rates[j] =
+ master->device_stats.loss_rates[j];
}
up(&master->device_sem);
- data.app_time = master->app_time;
- data.ref_clock =
+ io.app_time = master->app_time;
+ io.ref_clock =
master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
- if (copy_to_user((void __user *) arg, &data, sizeof(data)))
- return -EFAULT;
+ if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
+ return -EFAULT;
+ }
return 0;
}
@@ -459,7 +465,8 @@
data.data_size = domain->data_size;
data.logical_base_address = domain->logical_base_address;
- for (dev_idx = 0; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
data.working_counter[dev_idx] = domain->working_counter[dev_idx];
}
data.expected_working_counter = domain->expected_working_counter;
--- a/master/ioctl.h Fri Nov 30 15:24:38 2012 +0100
+++ b/master/ioctl.h Fri Nov 30 20:15:31 2012 +0100
@@ -56,7 +56,7 @@
*
* Increment this when changing the ioctl interface!
*/
-#define EC_IOCTL_VERSION_MAGIC 23
+#define EC_IOCTL_VERSION_MAGIC 24
// Command-line tool
#define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t)
@@ -187,7 +187,8 @@
int32_t rx_frame_rates[EC_RATE_COUNT];
int32_t tx_byte_rates[EC_RATE_COUNT];
int32_t rx_byte_rates[EC_RATE_COUNT];
- } devices[EC_NUM_DEVICES];
+ } devices[EC_MAX_NUM_DEVICES];
+ uint32_t num_devices;
uint64_t tx_count;
uint64_t rx_count;
uint64_t tx_bytes;
@@ -304,7 +305,7 @@
// outputs
uint32_t data_size;
uint32_t logical_base_address;
- uint16_t working_counter[EC_NUM_DEVICES];
+ uint16_t working_counter[EC_MAX_NUM_DEVICES];
uint16_t expected_working_counter;
uint32_t fmmu_count;
} ec_ioctl_domain_t;
--- a/master/master.c Fri Nov 30 15:24:38 2012 +0100
+++ b/master/master.c Fri Nov 30 20:15:31 2012 +0100
@@ -136,14 +136,28 @@
)
{
int ret;
+ unsigned int dev_idx;
master->index = index;
master->reserved = 0;
sema_init(&master->master_sem, 1);
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_MAX_NUM_DEVICES; dev_idx++) {
+ master->macs[dev_idx] = NULL;
+ }
+
master->macs[EC_DEVICE_MAIN] = main_mac;
+
+#if EC_MAX_NUM_DEVICES > 1
master->macs[EC_DEVICE_BACKUP] = backup_mac;
+ master->num_devices = 1 + !ec_mac_is_zero(backup_mac);
+#else
+ if (!ec_mac_is_zero(backup_mac)) {
+ EC_MASTER_WARN(master, "Ignoring backup MAC address!");
+ }
+#endif
+
ec_master_clear_device_stats(master);
sema_init(&master->device_sem, 1);
@@ -209,13 +223,13 @@
init_waitqueue_head(&master->sii_queue);
// init devices
- ret = ec_device_init(&master->devices[EC_DEVICE_MAIN], master);
- if (ret < 0)
- goto out_return;
-
- ret = ec_device_init(&master->devices[EC_DEVICE_BACKUP], master);
- if (ret < 0)
- goto out_clear_main;
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
+ ret = ec_device_init(&master->devices[dev_idx], master);
+ if (ret < 0) {
+ goto out_clear_devices;
+ }
+ }
// init state machine datagram
ec_datagram_init(&master->fsm_datagram);
@@ -224,7 +238,7 @@
if (ret < 0) {
ec_datagram_clear(&master->fsm_datagram);
EC_MASTER_ERR(master, "Failed to allocate FSM datagram.\n");
- goto out_clear_backup;
+ goto out_clear_devices;
}
// create state machine object
@@ -325,11 +339,10 @@
out_clear_fsm:
ec_fsm_master_clear(&master->fsm);
ec_datagram_clear(&master->fsm_datagram);
-out_clear_backup:
- ec_device_clear(&master->devices[EC_DEVICE_BACKUP]);
-out_clear_main:
- ec_device_clear(&master->devices[EC_DEVICE_MAIN]);
-out_return:
+out_clear_devices:
+ for (; dev_idx > 0; dev_idx--) {
+ ec_device_clear(&master->devices[dev_idx - 1]);
+ }
return ret;
}
@@ -341,6 +354,8 @@
ec_master_t *master /**< EtherCAT master */
)
{
+ unsigned int dev_idx;
+
#ifdef EC_RTDM
ec_rtdm_dev_clear(&master->rtdm_dev);
#endif
@@ -365,8 +380,11 @@
ec_datagram_clear(&master->ref_sync_datagram);
ec_fsm_master_clear(&master->fsm);
ec_datagram_clear(&master->fsm_datagram);
- ec_device_clear(&master->devices[EC_DEVICE_BACKUP]);
- ec_device_clear(&master->devices[EC_DEVICE_MAIN]);
+
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
+ ec_device_clear(&master->devices[dev_idx]);
+ }
}
/*****************************************************************************/
@@ -575,7 +593,8 @@
master->phase = EC_IDLE;
// reset number of responding slaves to trigger scanning
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
master->fsm.slaves_responding[dev_idx] = 0;
}
@@ -1222,7 +1241,7 @@
ec_device_stats_t *s = &master->device_stats;
s32 tx_frame_rate, rx_frame_rate, tx_byte_rate, rx_byte_rate, loss_rate;
u64 loss;
- unsigned int i;
+ unsigned int i, dev_idx;
// frame statistics
if (likely(jiffies - s->jiffies < HZ)) {
@@ -1255,8 +1274,10 @@
s->last_rx_bytes = s->rx_bytes;
s->last_loss = loss;
- ec_device_update_stats(&master->devices[EC_DEVICE_MAIN]);
- ec_device_update_stats(&master->devices[EC_DEVICE_BACKUP]);
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
+ ec_device_update_stats(&master->devices[dev_idx]);
+ }
s->jiffies = jiffies;
}
@@ -2265,7 +2286,8 @@
ec_master_inject_external_datagrams(master);
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
if (unlikely(!master->devices[dev_idx].link_state)) {
// link is down, no datagram can be sent
list_for_each_entry_safe(datagram, n,
@@ -2297,12 +2319,13 @@
void ecrt_master_receive(ec_master_t *master)
{
+ unsigned int dev_idx;
ec_datagram_t *datagram, *next;
// receive datagrams
- ec_device_poll(&master->devices[EC_DEVICE_MAIN]);
- if (master->devices[EC_DEVICE_BACKUP].dev) {
- ec_device_poll(&master->devices[EC_DEVICE_BACKUP]);
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
+ ec_device_poll(&master->devices[dev_idx]);
}
ec_master_update_device_stats(master);
@@ -2540,7 +2563,8 @@
state->al_states = 0;
state->link_up = 0U;
- for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
/* Announce sum of responding slaves on all links. */
state->slaves_responding += master->fsm.slaves_responding[dev_idx];
@@ -2557,7 +2581,7 @@
int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx,
ec_master_link_state_t *state)
{
- if (dev_idx >= EC_NUM_DEVICES) {
+ if (dev_idx >= ec_master_num_devices(master)) {
return -EINVAL;
}
--- a/master/master.h Fri Nov 30 15:24:38 2012 +0100
+++ b/master/master.h Fri Nov 30 20:15:31 2012 +0100
@@ -172,6 +172,12 @@
/*****************************************************************************/
+#if EC_MAX_NUM_DEVICES < 1
+#error Invalid number of devices
+#endif
+
+/*****************************************************************************/
+
/** EtherCAT master.
*
* Manages slaves, domains and IO.
@@ -193,8 +199,13 @@
struct semaphore master_sem; /**< Master semaphore. */
- ec_device_t devices[EC_NUM_DEVICES]; /**< EtherCAT devices. */
- const uint8_t *macs[EC_NUM_DEVICES]; /**< Device MAC addresses. */
+ ec_device_t devices[EC_MAX_NUM_DEVICES]; /**< EtherCAT devices. */
+ const uint8_t *macs[EC_MAX_NUM_DEVICES]; /**< Device MAC addresses. */
+#if EC_MAX_NUM_DEVICES > 1
+ unsigned int num_devices; /**< Number of devices. Access this always via
+ ec_master_num_devices(), because it may be
+ optimized! */
+#endif
struct semaphore device_sem; /**< Device semaphore. */
ec_device_stats_t device_stats; /**< Device statistics. */
@@ -290,6 +301,12 @@
const uint8_t *, dev_t, struct class *, unsigned int);
void ec_master_clear(ec_master_t *);
+#if EC_MAX_NUM_DEVICES > 1
+#define ec_master_num_devices(MASTER) ((MASTER)->num_devices)
+#else
+#define ec_master_num_devices(MASTER) 1
+#endif
+
// phase transitions
int ec_master_enter_idle_phase(ec_master_t *);
void ec_master_leave_idle_phase(ec_master_t *);
--- a/master/module.c Fri Nov 30 15:24:38 2012 +0100
+++ b/master/module.c Fri Nov 30 20:15:31 2012 +0100
@@ -453,7 +453,7 @@
/** Device names.
*/
-const char *ec_device_names[EC_NUM_DEVICES] = {
+const char *ec_device_names[2] = {
"main",
"backup"
};
@@ -476,29 +476,34 @@
{
ec_master_t *master;
char str[EC_MAX_MAC_STRING_SIZE];
- unsigned int i, j;
+ unsigned int i, dev_idx;
for (i = 0; i < master_count; i++) {
master = &masters[i];
ec_mac_print(net_dev->dev_addr, str);
- down(&master->device_sem);
-
- for (j = 0; j < EC_NUM_DEVICES; j++) {
- if (!master->devices[j].dev
- && (ec_mac_equal(master->macs[j], net_dev->dev_addr)
- || ec_mac_is_broadcast(master->macs[j]))) {
+ if (down_interruptible(&master->device_sem)) {
+ EC_MASTER_WARN(master, "%s() interrupted!\n", __func__);
+ return NULL;
+ }
+
+ for (dev_idx = EC_DEVICE_MAIN;
+ dev_idx < ec_master_num_devices(master); dev_idx++) {
+ if (!master->devices[dev_idx].dev
+ && (ec_mac_equal(master->macs[dev_idx], net_dev->dev_addr)
+ || ec_mac_is_broadcast(master->macs[dev_idx]))) {
EC_INFO("Accepting %s as %s device for master %u.\n",
- str, ec_device_names[j], master->index);
-
- ec_device_attach(&master->devices[j], net_dev, poll, module);
+ str, ec_device_names[dev_idx != 0], master->index);
+
+ ec_device_attach(&master->devices[dev_idx],
+ net_dev, poll, module);
up(&master->device_sem);
snprintf(net_dev->name, IFNAMSIZ, "ec%c%u",
- ec_device_names[j][0], master->index);
-
- return &master->devices[j]; // offer accepted
+ ec_device_names[dev_idx != 0][0], master->index);
+
+ return &master->devices[dev_idx]; // offer accepted
}
}
@@ -523,7 +528,7 @@
)
{
ec_master_t *master, *errptr = NULL;
- unsigned int i, got_modules = 0;
+ unsigned int dev_idx = EC_DEVICE_MAIN;
EC_INFO("Requesting master %u...\n", master_index);
@@ -560,17 +565,14 @@
goto out_release;
}
- for (i = 0; i < EC_NUM_DEVICES; i++) {
- ec_device_t *device = &master->devices[i];
- if (device->dev) {
- if (!try_module_get(device->module)) {
- up(&master->device_sem);
- EC_MASTER_ERR(master, "Device module is unloading!\n");
- errptr = ERR_PTR(-ENODEV);
- goto out_module_put;
- }
- }
- got_modules++;
+ for (; dev_idx < ec_master_num_devices(master); dev_idx++) {
+ ec_device_t *device = &master->devices[dev_idx];
+ if (!try_module_get(device->module)) {
+ up(&master->device_sem);
+ EC_MASTER_ERR(master, "Device module is unloading!\n");
+ errptr = ERR_PTR(-ENODEV);
+ goto out_module_put;
+ }
}
up(&master->device_sem);
@@ -585,11 +587,9 @@
return master;
out_module_put:
- for (; got_modules > 0; got_modules--) {
- ec_device_t *device = &master->devices[i - 1];
- if (device->dev) {
- module_put(device->module);
- }
+ for (; dev_idx > 0; dev_idx--) {
+ ec_device_t *device = &master->devices[dev_idx - 1];
+ module_put(device->module);
}
out_release:
master->reserved = 0;
@@ -609,7 +609,7 @@
void ecrt_release_master(ec_master_t *master)
{
- unsigned int i;
+ unsigned int dev_idx;
EC_MASTER_INFO(master, "Releasing master...\n");
@@ -621,10 +621,9 @@
ec_master_leave_operation_phase(master);
- for (i = 0; i < EC_NUM_DEVICES; i++) {
- if (master->devices[i].dev) {
- module_put(master->devices[i].module);
- }
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
+ dev_idx++) {
+ module_put(master->devices[dev_idx].module);
}
master->reserved = 0;
--- a/tool/Command.cpp Fri Nov 30 15:24:38 2012 +0100
+++ b/tool/Command.cpp Fri Nov 30 20:15:31 2012 +0100
@@ -467,19 +467,17 @@
/****************************************************************************/
-Command::DomainList Command::selectedDomains(MasterDevice &m)
-{
- ec_ioctl_master_t master;
+Command::DomainList Command::selectedDomains(MasterDevice &m,
+ const ec_ioctl_master_t &io)
+{
DomainList list;
- m.getMaster(&master);
-
- PositionParser pp(master.domain_count);
+ PositionParser pp(io.domain_count);
NumberListParser::List domList = pp.parse(domains.c_str());
NumberListParser::List::const_iterator di;
for (di = domList.begin(); di != domList.end(); di++) {
- if (*di < master.domain_count) {
+ if (*di < io.domain_count) {
ec_ioctl_domain_t d;
m.getDomain(&d, *di);
list.push_back(d);
--- a/tool/Command.h Fri Nov 30 15:24:38 2012 +0100
+++ b/tool/Command.h Fri Nov 30 20:15:31 2012 +0100
@@ -139,7 +139,7 @@
typedef list<ec_ioctl_config_t> ConfigList;
ConfigList selectedConfigs(MasterDevice &);
typedef list<ec_ioctl_domain_t> DomainList;
- DomainList selectedDomains(MasterDevice &);
+ DomainList selectedDomains(MasterDevice &, const ec_ioctl_master_t &);
static string alStateString(uint8_t);
--- a/tool/CommandData.cpp Fri Nov 30 15:24:38 2012 +0100
+++ b/tool/CommandData.cpp Fri Nov 30 20:15:31 2012 +0100
@@ -82,9 +82,12 @@
MasterIndexList::const_iterator mi;
for (mi = masterIndices.begin();
mi != masterIndices.end(); mi++) {
+ ec_ioctl_master_t io;
MasterDevice m(*mi);
m.open(MasterDevice::Read);
- domains = selectedDomains(m);
+ m.getMaster(&io);
+
+ domains = selectedDomains(m, io);
for (di = domains.begin(); di != domains.end(); di++) {
outputDomainData(m, *di);
--- a/tool/CommandDomains.cpp Fri Nov 30 15:24:38 2012 +0100
+++ b/tool/CommandDomains.cpp Fri Nov 30 20:15:31 2012 +0100
@@ -108,16 +108,18 @@
MasterIndexList::const_iterator mi;
for (mi = masterIndices.begin();
mi != masterIndices.end(); mi++) {
+ ec_ioctl_master_t io;
MasterDevice m(*mi);
m.open(MasterDevice::Read);
- domains = selectedDomains(m);
+ m.getMaster(&io);
+ domains = selectedDomains(m, io);
if (domains.size() && doIndent) {
cout << "Master" << dec << *mi << endl;
}
for (di = domains.begin(); di != domains.end(); di++) {
- showDomain(m, *di, doIndent);
+ showDomain(m, io, *di, doIndent);
}
}
}
@@ -126,6 +128,7 @@
void CommandDomains::showDomain(
MasterDevice &m,
+ const ec_ioctl_master_t &master,
const ec_ioctl_domain_t &domain,
bool doIndent
)
@@ -138,7 +141,7 @@
string indent(doIndent ? " " : "");
unsigned int wc_sum = 0, dev_idx;
- for (dev_idx = 0; dev_idx < EC_NUM_DEVICES; dev_idx++) {
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < master.num_devices; dev_idx++) {
wc_sum += domain.working_counter[dev_idx];
}
@@ -151,10 +154,16 @@
<< ", WorkingCounter "
<< wc_sum << "/"
<< domain.expected_working_counter;
- if (EC_NUM_DEVICES == 2) {
- cout << " (" << domain.working_counter[EC_DEVICE_MAIN]
- << "+" << domain.working_counter[EC_DEVICE_BACKUP]
- << ")";
+ if (master.num_devices > 1) {
+ cout << " (";
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < master.num_devices;
+ dev_idx++) {
+ cout << domain.working_counter[dev_idx];
+ if (dev_idx + 1 < master.num_devices) {
+ cout << "+";
+ }
+ }
+ cout << ")";
}
cout << endl;
--- a/tool/CommandDomains.h Fri Nov 30 15:24:38 2012 +0100
+++ b/tool/CommandDomains.h Fri Nov 30 20:15:31 2012 +0100
@@ -44,7 +44,8 @@
void execute(const StringVector &);
protected:
- void showDomain(MasterDevice &, const ec_ioctl_domain_t &, bool);
+ void showDomain(MasterDevice &, const ec_ioctl_master_t &,
+ const ec_ioctl_domain_t &, bool);
};
/****************************************************************************/
--- a/tool/CommandMaster.cpp Fri Nov 30 15:24:38 2012 +0100
+++ b/tool/CommandMaster.cpp Fri Nov 30 20:15:31 2012 +0100
@@ -70,7 +70,7 @@
MasterIndexList masterIndices;
ec_ioctl_master_t data;
stringstream err;
- unsigned int i, j;
+ unsigned int dev_idx, j;
time_t epoch;
char time_str[MAX_TIME_STR_SIZE + 1];
size_t time_str_size;
@@ -104,84 +104,78 @@
<< " Slaves: " << data.slave_count << endl
<< " Ethernet devices:" << endl;
- for (i = 0; i < 2; i++) {
- cout << " " << (i == 0 ? "Main" : "Backup") << ": ";
- if (data.devices[i].address[0] == 0x00
- && data.devices[i].address[1] == 0x00
- && data.devices[i].address[2] == 0x00
- && data.devices[i].address[3] == 0x00
- && data.devices[i].address[4] == 0x00
- && data.devices[i].address[5] == 0x00) {
- cout << "None." << endl;
- } else {
- cout << hex << setfill('0')
- << setw(2) << (unsigned int) data.devices[i].address[0]
- << ":"
- << setw(2) << (unsigned int) data.devices[i].address[1]
- << ":"
- << setw(2) << (unsigned int) data.devices[i].address[2]
- << ":"
- << setw(2) << (unsigned int) data.devices[i].address[3]
- << ":"
- << setw(2) << (unsigned int) data.devices[i].address[4]
- << ":"
- << setw(2) << (unsigned int) data.devices[i].address[5]
- << " ("
- << (data.devices[i].attached ? "attached" : "waiting...")
- << ")" << endl << dec
- << " Link: "
- << (data.devices[i].link_state ? "UP" : "DOWN") << endl
- << " Tx frames: "
- << data.devices[i].tx_count << endl
- << " Tx bytes: "
- << data.devices[i].tx_bytes << endl
- << " Rx frames: "
- << data.devices[i].rx_count << endl
- << " Rx bytes: "
- << data.devices[i].rx_bytes << endl
- << " Tx errors: "
- << data.devices[i].tx_errors << endl
- << " Tx frame rate [1/s]: "
- << setfill(' ') << setprecision(0) << fixed;
- for (j = 0; j < EC_RATE_COUNT; j++) {
- cout << setw(ColWidth)
- << data.devices[i].tx_frame_rates[j] / 1000.0;
- if (j < EC_RATE_COUNT - 1) {
- cout << " ";
- }
- }
- cout << endl
- << " Tx rate [KByte/s]: "
- << setprecision(1) << fixed;
- for (j = 0; j < EC_RATE_COUNT; j++) {
- cout << setw(ColWidth)
- << data.devices[i].tx_byte_rates[j] / 1024.0;
- if (j < EC_RATE_COUNT - 1) {
- cout << " ";
- }
- }
- cout << endl
- << " Rx frame rate [1/s]: "
- << setfill(' ') << setprecision(0) << fixed;
- for (j = 0; j < EC_RATE_COUNT; j++) {
- cout << setw(ColWidth)
- << data.devices[i].rx_frame_rates[j] / 1000.0;
- if (j < EC_RATE_COUNT - 1) {
- cout << " ";
- }
- }
- cout << endl
- << " Rx rate [KByte/s]: "
- << setprecision(1) << fixed;
- for (j = 0; j < EC_RATE_COUNT; j++) {
- cout << setw(ColWidth)
- << data.devices[i].rx_byte_rates[j] / 1024.0;
- if (j < EC_RATE_COUNT - 1) {
- cout << " ";
- }
- }
- cout << setprecision(0) << endl;
- }
+ for (dev_idx = EC_DEVICE_MAIN; dev_idx < data.num_devices;
+ dev_idx++) {
+ cout << " " << (dev_idx == EC_DEVICE_MAIN ? "Main" : "Backup")
+ << ": ";
+ cout << hex << setfill('0')
+ << setw(2) << (unsigned int) data.devices[dev_idx].address[0]
+ << ":"
+ << setw(2) << (unsigned int) data.devices[dev_idx].address[1]
+ << ":"
+ << setw(2) << (unsigned int) data.devices[dev_idx].address[2]
+ << ":"
+ << setw(2) << (unsigned int) data.devices[dev_idx].address[3]
+ << ":"
+ << setw(2) << (unsigned int) data.devices[dev_idx].address[4]
+ << ":"
+ << setw(2) << (unsigned int) data.devices[dev_idx].address[5]
+ << " ("
+ << (data.devices[dev_idx].attached ?
+ "attached" : "waiting...")
+ << ")" << endl << dec
+ << " Link: "
+ << (data.devices[dev_idx].link_state ? "UP" : "DOWN") << endl
+ << " Tx frames: "
+ << data.devices[dev_idx].tx_count << endl
+ << " Tx bytes: "
+ << data.devices[dev_idx].tx_bytes << endl
+ << " Rx frames: "
+ << data.devices[dev_idx].rx_count << endl
+ << " Rx bytes: "
+ << data.devices[dev_idx].rx_bytes << endl
+ << " Tx errors: "
+ << data.devices[dev_idx].tx_errors << endl
+ << " Tx frame rate [1/s]: "
+ << setfill(' ') << setprecision(0) << fixed;
+ for (j = 0; j < EC_RATE_COUNT; j++) {
+ cout << setw(ColWidth)
+ << data.devices[dev_idx].tx_frame_rates[j] / 1000.0;
+ if (j < EC_RATE_COUNT - 1) {
+ cout << " ";
+ }
+ }
+ cout << endl
+ << " Tx rate [KByte/s]: "
+ << setprecision(1) << fixed;
+ for (j = 0; j < EC_RATE_COUNT; j++) {
+ cout << setw(ColWidth)
+ << data.devices[dev_idx].tx_byte_rates[j] / 1024.0;
+ if (j < EC_RATE_COUNT - 1) {
+ cout << " ";
+ }
+ }
+ cout << endl
+ << " Rx frame rate [1/s]: "
+ << setfill(' ') << setprecision(0) << fixed;
+ for (j = 0; j < EC_RATE_COUNT; j++) {
+ cout << setw(ColWidth)
+ << data.devices[dev_idx].rx_frame_rates[j] / 1000.0;
+ if (j < EC_RATE_COUNT - 1) {
+ cout << " ";
+ }
+ }
+ cout << endl
+ << " Rx rate [KByte/s]: "
+ << setprecision(1) << fixed;
+ for (j = 0; j < EC_RATE_COUNT; j++) {
+ cout << setw(ColWidth)
+ << data.devices[dev_idx].rx_byte_rates[j] / 1024.0;
+ if (j < EC_RATE_COUNT - 1) {
+ cout << " ";
+ }
+ }
+ cout << setprecision(0) << endl;
}
unsigned int lost = data.tx_count - data.rx_count;
if (lost == 1) {