Fixed calculation of expected working counter.

This commit is contained in:
Florian Pose 2008-06-10 09:54:30 +00:00
parent 9227ea241c
commit b5bee09143
2 changed files with 53 additions and 61 deletions

View File

@ -54,14 +54,6 @@ ssize_t ec_show_domain_attribute(struct kobject *, struct attribute *, char *);
/*****************************************************************************/
/** Working counter increment values for logical read/write operations.
*
* \attention This is indexed by ec_direction_t.
*/
static const unsigned int working_counter_increment[] = {2, 1};
/*****************************************************************************/
/** \cond */
EC_SYSFS_READ_ATTR(image_size);
@ -98,18 +90,17 @@ int ec_domain_init(
{
domain->master = master;
domain->index = index;
INIT_LIST_HEAD(&domain->fmmu_configs);
domain->data_size = 0;
domain->expected_working_counter = 0x0000;
domain->data = NULL;
domain->data_origin = EC_ORIG_INTERNAL;
domain->logical_base_address = 0L;
domain->logical_base_address = 0x00000000;
INIT_LIST_HEAD(&domain->datagrams);
domain->working_counter = 0xFFFF;
domain->expected_working_counter = 0x0000;
domain->working_counter_changes = 0;
domain->notify_jiffies = 0;
INIT_LIST_HEAD(&domain->datagrams);
INIT_LIST_HEAD(&domain->fmmu_configs);
// init kobject and add it to the hierarchy
memset(&domain->kobj, 0x00, sizeof(struct kobject));
kobject_init(&domain->kobj);
@ -197,25 +188,22 @@ void ec_domain_add_fmmu_config(
ec_fmmu_config_t *fmmu /**< FMMU configuration. */
)
{
unsigned int wc_increment;
fmmu->domain = domain;
domain->data_size += fmmu->data_size;
wc_increment = working_counter_increment[fmmu->dir];
domain->expected_working_counter += wc_increment;
list_add_tail(&fmmu->list, &domain->fmmu_configs);
if (domain->master->debug_level)
EC_DBG("Domain %u: Added %u bytes (now %u) with dir %u -> WC %u"
" (now %u).\n", domain->index, fmmu->data_size,
domain->data_size, fmmu->dir, wc_increment,
domain->expected_working_counter);
EC_DBG("Domain %u: Added %u bytes, total %u.\n", domain->index,
fmmu->data_size, domain->data_size);
}
/*****************************************************************************/
/** Allocates a domain datagram and appends it to the list.
*
* The datagram type and expected working counters are determined by the
* number of input and output fmmus that share the datagram.
*
* \return 0 in case of success, else < 0
*/
@ -243,16 +231,22 @@ int ec_domain_add_datagram(
kfree(datagram);
return -1;
}
// If LRW is used, output FMMUs increment the working counter by 2,
// while input FMMUs increment it by 1.
domain->expected_working_counter =
used[EC_DIR_OUTPUT] * 2 + used[EC_DIR_INPUT];
} else if (used[EC_DIR_OUTPUT]) { // outputs only
if (ec_datagram_lwr(datagram, logical_offset, data_size, data)) {
kfree(datagram);
return -1;
}
domain->expected_working_counter = used[EC_DIR_OUTPUT];
} else { // inputs only (or nothing)
if (ec_datagram_lrd(datagram, logical_offset, data_size, data)) {
kfree(datagram);
return -1;
}
domain->expected_working_counter = used[EC_DIR_INPUT];
}
list_add_tail(&datagram->list, &domain->datagrams);
@ -278,9 +272,8 @@ int ec_domain_finish(
{
uint32_t datagram_offset;
size_t datagram_size;
unsigned int datagram_count, i;
unsigned int datagram_count;
unsigned int datagram_used[2];
ec_slave_config_t *sc;
ec_fmmu_config_t *fmmu;
const ec_datagram_t *datagram;
@ -295,43 +288,39 @@ int ec_domain_finish(
}
}
// Cycle through all domain FMMUS, correct the logical base addresses and
// set up the datagrams to carry the process data.
// Cycle through all domain FMMUS and
// - correct the logical base addresses
// - set up the datagrams to carry the process data
datagram_offset = 0;
datagram_size = 0;
datagram_count = 0;
datagram_used[EC_DIR_OUTPUT] = 0;
datagram_used[EC_DIR_INPUT] = 0;
list_for_each_entry(sc, &domain->master->configs, list) {
for (i = 0; i < sc->used_fmmus; i++) {
fmmu = &sc->fmmu_configs[i];
if (fmmu->domain != domain)
continue;
list_for_each_entry(fmmu, &domain->fmmu_configs, list) {
// Correct logical FMMU address
fmmu->logical_start_address += base_address;
// Correct logical FMMU address
fmmu->logical_start_address += base_address;
// Increment Input/Output counter to determine datagram types
// and calculate expected working counters
datagram_used[fmmu->dir]++;
// Increment Input/Output counter
datagram_used[fmmu->dir]++;
// If the current FMMU's data do not fit in the current datagram,
// allocate a new one.
if (datagram_size + fmmu->data_size > EC_MAX_DATA_SIZE) {
if (ec_domain_add_datagram(domain,
domain->logical_base_address + datagram_offset,
datagram_size, domain->data + datagram_offset,
datagram_used))
return -1;
datagram_offset += datagram_size;
datagram_size = 0;
datagram_count++;
datagram_used[EC_DIR_OUTPUT] = 0;
datagram_used[EC_DIR_INPUT] = 0;
}
datagram_size += fmmu->data_size;
// If the current FMMU's data do not fit in the current datagram,
// allocate a new one.
if (datagram_size + fmmu->data_size > EC_MAX_DATA_SIZE) {
if (ec_domain_add_datagram(domain,
domain->logical_base_address + datagram_offset,
datagram_size, domain->data + datagram_offset,
datagram_used))
return -1;
datagram_offset += datagram_size;
datagram_size = 0;
datagram_count++;
datagram_used[EC_DIR_OUTPUT] = 0;
datagram_used[EC_DIR_INPUT] = 0;
}
datagram_size += fmmu->data_size;
}
// allocate last datagram, if data are left
@ -344,10 +333,12 @@ int ec_domain_finish(
datagram_count++;
}
EC_INFO("Domain %u with logical offset %u contains %u bytes.\n",
domain->index, domain->logical_base_address, domain->data_size);
EC_INFO("Domain%u: Logical address 0x%08x, %u byte, "
"expected working counter %u.\n", domain->index,
domain->logical_base_address, domain->data_size,
domain->expected_working_counter);
list_for_each_entry(datagram, &domain->datagrams, list) {
EC_INFO(" Datagram %s, logical offset %u, size %u, type %s.\n",
EC_INFO(" Datagram %s: Logical offset 0x%08x, %u byte, type %s.\n",
datagram->name, EC_READ_U32(datagram->address),
datagram->data_size, ec_datagram_type_string(datagram));
}
@ -462,10 +453,10 @@ uint8_t *ecrt_domain_data(ec_domain_t *domain)
void ecrt_domain_process(ec_domain_t *domain)
{
unsigned int working_counter_sum;
uint16_t working_counter_sum;
ec_datagram_t *datagram;
working_counter_sum = 0;
working_counter_sum = 0x0000;
list_for_each_entry(datagram, &domain->datagrams, list) {
ec_datagram_output_stats(datagram);
if (datagram->state == EC_DATAGRAM_RECEIVED) {
@ -485,8 +476,7 @@ void ecrt_domain_process(ec_domain_t *domain)
EC_INFO("Domain %u: Working counter changed to %u/%u.\n",
domain->index, domain->working_counter,
domain->expected_working_counter);
}
else {
} else {
EC_INFO("Domain %u: %u working counter changes. Currently %u/%u.\n",
domain->index, domain->working_counter_changes,
domain->working_counter, domain->expected_working_counter);

View File

@ -63,18 +63,20 @@ struct ec_domain
struct list_head list; /**< List item. */
ec_master_t *master; /**< EtherCAT master owning the domain. */
unsigned int index; /**< Index (just a number). */
struct list_head fmmu_configs; /**< FMMU configurations contained. */
size_t data_size; /**< Size of the process data. */
uint16_t expected_working_counter; /**< Expected working counter. */
uint8_t *data; /**< Memory for the process data. */
ec_origin_t data_origin; /**< Origin of the \a data memory. */
struct list_head datagrams; /**< Datagrams for process data exchange. */
uint32_t logical_base_address; /**< Logical offset address of the
process data. */
struct list_head datagrams; /**< Datagrams for process data exchange. */
uint16_t working_counter; /**< Last working counter value. */
uint16_t expected_working_counter; /**< Expected working counter. */
unsigned int working_counter_changes; /**< Working counter changes
since last notification. */
unsigned long notify_jiffies; /**< Time of last notification. */
struct list_head fmmu_configs; /**< FMMU configurations contained. */
};
/*****************************************************************************/