Calculate expected working counter for domains.
This commit is contained in:
parent
49baa165af
commit
b4322990e2
1
TODO
1
TODO
|
|
@ -19,7 +19,6 @@ Version 1.4.0:
|
|||
applications.
|
||||
* Update documentation.
|
||||
* READMEs for examples.
|
||||
* Calculate expected working counter for domains.
|
||||
* Distributed clocks.
|
||||
|
||||
Future issues:
|
||||
|
|
|
|||
|
|
@ -43,9 +43,7 @@
|
|||
|
||||
#define FREQUENCY 100
|
||||
|
||||
//#define KBUS
|
||||
#define PDOS
|
||||
#define MAPPING
|
||||
#define CONFIGURE_MAPPING
|
||||
#define EXTERNAL_MEMORY
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -54,17 +52,13 @@ static struct timer_list timer;
|
|||
|
||||
// EtherCAT
|
||||
static ec_master_t *master = NULL;
|
||||
static ec_domain_t *domain1 = NULL;
|
||||
static ec_master_state_t master_state = {};
|
||||
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
|
||||
static ec_domain_t *domain1 = NULL;
|
||||
static ec_domain_state_t domain1_state = {};
|
||||
|
||||
#ifdef MAPPING
|
||||
#ifdef CONFIGURE_MAPPING
|
||||
const ec_pdo_entry_info_t el3162_channel1[] = {
|
||||
{0x3101, 1, 8}, // status
|
||||
{0x3101, 2, 16} // value
|
||||
|
|
@ -95,7 +89,6 @@ const ec_pdo_info_t el2004_mapping[] = {
|
|||
};
|
||||
#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 @@ const static ec_pdo_entry_reg_t domain1_regs[] = {
|
|||
{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 @@ void run(unsigned long data)
|
|||
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;
|
||||
// check for master state (optional)
|
||||
check_master_state();
|
||||
}
|
||||
|
||||
#ifdef KBUS
|
||||
EC_WRITE_U8(r_outputs + 2, blink ? 0xFF : 0x00);
|
||||
#endif
|
||||
// write process data
|
||||
EC_WRITE_U8(pd + off_dig_out, blink ? 0x0F : 0x00);
|
||||
|
||||
// send
|
||||
// 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 @@ void release_lock(void *data)
|
|||
|
||||
int __init init_mini_module(void)
|
||||
{
|
||||
#ifdef MAPPING
|
||||
#ifdef CONFIGURE_MAPPING
|
||||
ec_slave_config_t *sc;
|
||||
#endif
|
||||
#ifdef EXTERNAL_MEMORY
|
||||
|
|
@ -210,7 +225,7 @@ int __init init_mini_module(void)
|
|||
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 @@ int __init init_mini_module(void)
|
|||
#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))) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,14 @@ 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);
|
||||
|
|
@ -91,12 +99,14 @@ int ec_domain_init(
|
|||
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->notify_jiffies = 0;
|
||||
domain->state = 0;
|
||||
domain->working_counter_changes = 0;
|
||||
domain->notify_jiffies = 0;
|
||||
|
||||
INIT_LIST_HEAD(&domain->datagrams);
|
||||
|
||||
|
|
@ -121,11 +131,10 @@ int ec_domain_init(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
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 @@ void ec_domain_destroy(ec_domain_t *domain /**< EtherCAT domain */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
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 @@ void ec_domain_clear_data(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** 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_queue(ec_domain_t *domain)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "globals.h"
|
||||
#include "datagram.h"
|
||||
#include "master.h"
|
||||
#include "fmmu_config.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -63,6 +64,7 @@ struct ec_domain
|
|||
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 @@ struct ec_domain
|
|||
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);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -59,12 +59,12 @@ void ec_fmmu_config_init(
|
|||
)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "../include/ecrt.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "pdo.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue