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) {