Calculate expected working counter for domains.
--- a/TODO Fri Feb 22 16:04:23 2008 +0000
+++ b/TODO Fri Feb 22 17:23:05 2008 +0000
@@ -19,7 +19,6 @@
applications.
* Update documentation.
* READMEs for examples.
-* Calculate expected working counter for domains.
* Distributed clocks.
Future issues:
--- a/examples/mini/mini.c Fri Feb 22 16:04:23 2008 +0000
+++ b/examples/mini/mini.c Fri Feb 22 17:23:05 2008 +0000
@@ -43,9 +43,7 @@
#define FREQUENCY 100
-//#define KBUS
-#define PDOS
-#define MAPPING
+#define CONFIGURE_MAPPING
#define EXTERNAL_MEMORY
/*****************************************************************************/
@@ -54,17 +52,13 @@
// EtherCAT
static ec_master_t *master = NULL;
+static ec_master_state_t master_state = {};
+spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
+
static ec_domain_t *domain1 = NULL;
-spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
-static ec_master_state_t master_state, old_state = {};
-
-// data fields
-#ifdef KBUS
-static void *r_inputs;
-static void *r_outputs;
-#endif
-
-#ifdef MAPPING
+static ec_domain_state_t domain1_state = {};
+
+#ifdef CONFIGURE_MAPPING
const ec_pdo_entry_info_t el3162_channel1[] = {
{0x3101, 1, 8}, // status
{0x3101, 2, 16} // value
@@ -95,7 +89,6 @@
};
#endif
-#ifdef PDOS
static uint8_t *pd; /**< Process data. */
static unsigned int off_ana_in;
static unsigned int off_dig_out;
@@ -105,7 +98,49 @@
{0, 3, Beckhoff_EL2004, 0x3001, 1, &off_dig_out},
{}
};
-#endif
+
+/*****************************************************************************/
+
+void check_domain1_state(void)
+{
+ ec_domain_state_t ds;
+
+ ecrt_domain_state(domain1, &ds);
+ if (ds.working_counter != domain1_state.working_counter)
+ printk(KERN_INFO PFX "domain1 working_counter changed to %u.\n",
+ ds.working_counter);
+
+ if (ds.wc_state != domain1_state.wc_state)
+ printk(KERN_INFO PFX "domain1 wc_state changed to %u.\n",
+ ds.wc_state);
+
+ domain1_state = ds;
+}
+
+/*****************************************************************************/
+
+void check_master_state(void)
+{
+ ec_master_state_t ms;
+
+ spin_lock(&master_lock);
+ ecrt_master_state(master, &ms);
+ spin_unlock(&master_lock);
+
+ if (ms.bus_state != master_state.bus_state) {
+ printk(KERN_INFO PFX "bus state changed to %i.\n", ms.bus_state);
+ }
+ if (ms.bus_tainted != master_state.bus_tainted) {
+ printk(KERN_INFO PFX "tainted flag changed to %u.\n",
+ ms.bus_tainted);
+ }
+ if (ms.slaves_responding != master_state.slaves_responding) {
+ printk(KERN_INFO PFX "slaves_responding changed to %u.\n",
+ ms.slaves_responding);
+ }
+
+ master_state = ms;
+}
/*****************************************************************************/
@@ -114,53 +149,33 @@
static unsigned int counter = 0;
static unsigned int blink = 0;
- // receive
+ // receive process data
spin_lock(&master_lock);
ecrt_master_receive(master);
ecrt_domain_process(domain1);
spin_unlock(&master_lock);
- // process data
- EC_WRITE_U8(pd + off_dig_out, blink ? 0x0F : 0x00);
+ // check process data state (optional)
+ check_domain1_state();
if (counter) {
counter--;
- }
- else {
+ } else { // do this at FREQUENCY
counter = FREQUENCY;
+
+ // calculate new process data
blink = !blink;
- spin_lock(&master_lock);
- ecrt_master_state(master, &master_state);
- spin_unlock(&master_lock);
-
- if (master_state.bus_state != old_state.bus_state) {
- printk(KERN_INFO PFX "bus state changed to %i.\n",
- master_state.bus_state);
- }
- if (master_state.bus_tainted != old_state.bus_tainted) {
- printk(KERN_INFO PFX "tainted flag changed to %u.\n",
- master_state.bus_tainted);
- }
- if (master_state.slaves_responding !=
- old_state.slaves_responding) {
- printk(KERN_INFO PFX "slaves_responding changed to %u.\n",
- master_state.slaves_responding);
- }
-
- old_state = master_state;
- }
-
-#ifdef KBUS
- EC_WRITE_U8(r_outputs + 2, blink ? 0xFF : 0x00);
-#endif
-
- // send
+ // check for master state (optional)
+ check_master_state();
+ }
+
+ // write process data
+ EC_WRITE_U8(pd + off_dig_out, blink ? 0x0F : 0x00);
+
+ // send process data
spin_lock(&master_lock);
ecrt_domain_queue(domain1);
- spin_unlock(&master_lock);
-
- spin_lock(&master_lock);
ecrt_master_send(master);
spin_unlock(&master_lock);
@@ -188,7 +203,7 @@
int __init init_mini_module(void)
{
-#ifdef MAPPING
+#ifdef CONFIGURE_MAPPING
ec_slave_config_t *sc;
#endif
#ifdef EXTERNAL_MEMORY
@@ -210,7 +225,7 @@
goto out_release_master;
}
-#ifdef MAPPING
+#ifdef CONFIGURE_MAPPING
printk(KERN_INFO PFX "Configuring Pdo mapping...\n");
if (!(sc = ecrt_master_slave_config(master, 0, 1, Beckhoff_EL3162))) {
printk(KERN_ERR PFX "Failed to get slave configuration.\n");
@@ -234,12 +249,10 @@
#endif
printk(KERN_INFO PFX "Registering Pdo entries...\n");
-#ifdef PDOS
if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
printk(KERN_ERR PFX "Pdo entry registration failed!\n");
goto out_release_master;
}
-#endif
#ifdef EXTERNAL_MEMORY
if ((size = ecrt_domain_size(domain1))) {
--- a/master/domain.c Fri Feb 22 16:04:23 2008 +0000
+++ b/master/domain.c Fri Feb 22 17:23:05 2008 +0000
@@ -54,6 +54,14 @@
/*****************************************************************************/
+/** 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);
@@ -91,12 +99,14 @@
domain->master = master;
domain->index = index;
domain->data_size = 0;
+ domain->expected_working_counter = 0;
domain->data = NULL;
domain->data_origin = EC_ORIG_INTERNAL;
domain->logical_base_address = 0L;
domain->working_counter = 0xFFFFFFFF;
+ domain->state = 0;
+ domain->working_counter_changes = 0;
domain->notify_jiffies = 0;
- domain->working_counter_changes = 0;
INIT_LIST_HEAD(&domain->datagrams);
@@ -121,11 +131,10 @@
/*****************************************************************************/
-/**
- Domain destructor.
- Clears and frees a domain object.
-*/
-
+/** Domain destructor.
+ *
+ * Clears and frees a domain object.
+ */
void ec_domain_destroy(ec_domain_t *domain /**< EtherCAT domain */)
{
ec_datagram_t *datagram;
@@ -143,12 +152,11 @@
/*****************************************************************************/
-/**
- Clear and free domain.
- This method is called by the kobject,
- once there are no more references to it.
-*/
-
+/** Clear and free domain.
+ *
+ * This method is called by the kobject, once there are no more references
+ * to it.
+ */
void ec_domain_clear(struct kobject *kobj /**< kobject of the domain */)
{
ec_domain_t *domain;
@@ -182,6 +190,21 @@
/*****************************************************************************/
+/** Adds an FMMU configuration to the domain.
+ */
+void ec_domain_add_fmmu_config(
+ ec_domain_t *domain, /**< EtherCAT domain. */
+ ec_fmmu_config_t *fmmu /**< FMMU configuration. */
+ )
+{
+ fmmu->domain = domain;
+
+ domain->data_size += fmmu->data_size;
+ domain->expected_working_counter += working_counter_increment[fmmu->dir];
+}
+
+/*****************************************************************************/
+
/** Allocates a domain datagram and appends it to the list.
*
* \return 0 in case of success, else < 0
@@ -449,7 +472,16 @@
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
{
state->working_counter = domain->working_counter;
- state->wc_state = EC_WC_ZERO; // FIXME
+
+ if (domain->working_counter) {
+ if (domain->working_counter == domain->expected_working_counter) {
+ state->wc_state = EC_WC_COMPLETE;
+ } else {
+ state->wc_state = EC_WC_INCOMPLETE;
+ }
+ } else {
+ state->wc_state = EC_WC_ZERO;
+ }
}
/*****************************************************************************/
--- a/master/domain.h Fri Feb 22 16:04:23 2008 +0000
+++ b/master/domain.h Fri Feb 22 17:23:05 2008 +0000
@@ -47,6 +47,7 @@
#include "globals.h"
#include "datagram.h"
#include "master.h"
+#include "fmmu_config.h"
/*****************************************************************************/
@@ -63,6 +64,7 @@
ec_master_t *master; /**< EtherCAT master owning the domain. */
unsigned int index; /**< Index (just a number). */
size_t data_size; /**< Size of the process data. */
+ unsigned int 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. */
@@ -80,6 +82,7 @@
int ec_domain_init(ec_domain_t *, ec_master_t *, unsigned int);
void ec_domain_destroy(ec_domain_t *);
+void ec_domain_add_fmmu_config(ec_domain_t *, ec_fmmu_config_t *);
int ec_domain_finish(ec_domain_t *, uint32_t);
/*****************************************************************************/
--- a/master/fmmu_config.c Fri Feb 22 16:04:23 2008 +0000
+++ b/master/fmmu_config.c Fri Feb 22 17:23:05 2008 +0000
@@ -59,12 +59,12 @@
)
{
fmmu->sc = sc;
- fmmu->domain = domain;
fmmu->dir = dir;
fmmu->logical_start_address = domain->data_size;
fmmu->data_size = ec_pdo_mapping_total_size(&sc->mapping[dir]);
- domain->data_size += fmmu->data_size;
+
+ ec_domain_add_fmmu_config(domain, fmmu);
}
/*****************************************************************************/
--- a/master/fmmu_config.h Fri Feb 22 16:04:23 2008 +0000
+++ b/master/fmmu_config.h Fri Feb 22 17:23:05 2008 +0000
@@ -43,21 +43,20 @@
#include "../include/ecrt.h"
#include "globals.h"
+#include "sync.h"
/*****************************************************************************/
/** FMMU configuration.
*/
-typedef struct
-{
+typedef struct {
const ec_slave_config_t *sc; /**< EtherCAT slave config. */
const ec_domain_t *domain; /**< Domain. */
ec_direction_t dir; /**< Pdo direction. */
uint32_t logical_start_address; /**< Logical start address. */
unsigned int data_size; /**< Covered Pdo size. */
-}
-ec_fmmu_config_t;
+} ec_fmmu_config_t;
/*****************************************************************************/
--- a/master/pdo_mapping.h Fri Feb 22 16:04:23 2008 +0000
+++ b/master/pdo_mapping.h Fri Feb 22 17:23:05 2008 +0000
@@ -46,6 +46,7 @@
#include "../include/ecrt.h"
#include "globals.h"
+#include "pdo.h"
/*****************************************************************************/