# HG changeset patch # User Florian Pose # Date 1354302931 -3600 # Node ID d461b1f07296bd22a72855ed85bf3a1ad9d4161f # Parent abc1d1caead730e0363e837c045e197fb674e397 Added configure option for redundancy (--with-devices). diff -r abc1d1caead7 -r d461b1f07296 TODO --- 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: diff -r abc1d1caead7 -r d461b1f07296 configure.ac --- 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 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 diff -r abc1d1caead7 -r d461b1f07296 master/datagram_pair.c --- 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); diff -r abc1d1caead7 -r d461b1f07296 master/datagram_pair.h --- 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[]); /*****************************************************************************/ diff -r abc1d1caead7 -r d461b1f07296 master/device.c --- 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"); diff -r abc1d1caead7 -r d461b1f07296 master/domain.c --- 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) { diff -r abc1d1caead7 -r d461b1f07296 master/domain.h --- 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 diff -r abc1d1caead7 -r d461b1f07296 master/fsm_master.c --- 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; diff -r abc1d1caead7 -r d461b1f07296 master/fsm_master.h --- 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 */ diff -r abc1d1caead7 -r d461b1f07296 master/globals.h --- 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! /*****************************************************************************/ diff -r abc1d1caead7 -r d461b1f07296 master/ioctl.c --- 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; diff -r abc1d1caead7 -r d461b1f07296 master/ioctl.h --- 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; diff -r abc1d1caead7 -r d461b1f07296 master/master.c --- 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; } diff -r abc1d1caead7 -r d461b1f07296 master/master.h --- 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 *); diff -r abc1d1caead7 -r d461b1f07296 master/module.c --- 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; diff -r abc1d1caead7 -r d461b1f07296 tool/Command.cpp --- 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); diff -r abc1d1caead7 -r d461b1f07296 tool/Command.h --- 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 ConfigList; ConfigList selectedConfigs(MasterDevice &); typedef list DomainList; - DomainList selectedDomains(MasterDevice &); + DomainList selectedDomains(MasterDevice &, const ec_ioctl_master_t &); static string alStateString(uint8_t); diff -r abc1d1caead7 -r d461b1f07296 tool/CommandData.cpp --- 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); diff -r abc1d1caead7 -r d461b1f07296 tool/CommandDomains.cpp --- 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; diff -r abc1d1caead7 -r d461b1f07296 tool/CommandDomains.h --- 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); }; /****************************************************************************/ diff -r abc1d1caead7 -r d461b1f07296 tool/CommandMaster.cpp --- 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) {