'ethercat domain' shows domain contents and process data.
--- a/master/cdev.c Wed Jun 04 10:41:50 2008 +0000
+++ b/master/cdev.c Wed Jun 04 13:17:15 2008 +0000
@@ -42,6 +42,7 @@
#include "cdev.h"
#include "master.h"
+#include "slave_config.h"
#include "ioctl.h"
/*****************************************************************************/
@@ -371,6 +372,44 @@
data.logical_base_address = domain->logical_base_address;
data.working_counter = domain->working_counter;
data.expected_working_counter = domain->expected_working_counter;
+ data.fmmu_count = ec_domain_fmmu_count(domain);
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+ }
+
+ case EC_IOCTL_DOMAIN_FMMU:
+ {
+ ec_ioctl_domain_fmmu_t data;
+ const ec_domain_t *domain;
+ const ec_fmmu_config_t *fmmu;
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (!(domain = ec_master_find_domain(master, data.domain_index))) {
+ EC_ERR("Domain %u does not exist!\n", data.domain_index);
+ retval = -EINVAL;
+ break;
+ }
+
+ if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
+ EC_ERR("Domain %u has less than %u fmmu configurations.\n",
+ data.domain_index, data.fmmu_index + 1);
+ retval = -EINVAL;
+ break;
+ }
+
+ data.slave_config_alias = fmmu->sc->alias;
+ data.slave_config_position = fmmu->sc->position;
+ data.fmmu_dir = fmmu->dir;
+ data.logical_address = fmmu->logical_start_address;
+ data.data_size = fmmu->data_size;
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
retval = -EFAULT;
--- a/master/domain.c Wed Jun 04 10:41:50 2008 +0000
+++ b/master/domain.c Wed Jun 04 13:17:15 2008 +0000
@@ -108,6 +108,7 @@
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));
@@ -202,6 +203,8 @@
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"
@@ -373,6 +376,38 @@
return 0;
}
+/*****************************************************************************/
+
+unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
+{
+ const ec_fmmu_config_t *fmmu;
+ unsigned int num = 0;
+
+ list_for_each_entry(fmmu, &domain->fmmu_configs, list) {
+ num++;
+ }
+
+ return num;
+}
+
+/*****************************************************************************/
+
+const ec_fmmu_config_t *ec_domain_find_fmmu(
+ const ec_domain_t *domain,
+ unsigned int index
+ )
+{
+ const ec_fmmu_config_t *fmmu;
+
+ list_for_each_entry(fmmu, &domain->fmmu_configs, list) {
+ if (index--)
+ continue;
+ return fmmu;
+ }
+
+ return NULL;
+}
+
/******************************************************************************
* Realtime interface
*****************************************************************************/
--- a/master/domain.h Wed Jun 04 10:41:50 2008 +0000
+++ b/master/domain.h Wed Jun 04 13:17:15 2008 +0000
@@ -74,6 +74,7 @@
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. */
};
/*****************************************************************************/
@@ -84,6 +85,9 @@
void ec_domain_add_fmmu_config(ec_domain_t *, ec_fmmu_config_t *);
int ec_domain_finish(ec_domain_t *, uint32_t);
+unsigned int ec_domain_fmmu_count(const ec_domain_t *);
+const ec_fmmu_config_t *ec_domain_find_fmmu(const ec_domain_t *, unsigned int);
+
/*****************************************************************************/
#endif
--- a/master/fmmu_config.c Wed Jun 04 10:41:50 2008 +0000
+++ b/master/fmmu_config.c Wed Jun 04 13:17:15 2008 +0000
@@ -58,6 +58,7 @@
ec_direction_t dir /**< Pdo direction. */
)
{
+ INIT_LIST_HEAD(&fmmu->list);
fmmu->sc = sc;
fmmu->dir = dir;
@@ -80,7 +81,7 @@
)
{
if (fmmu->sc->master->debug_level) {
- EC_DBG("FMMU: LogAddr 0x%08X, Size %3i, PhysAddr 0x%04X, Dir %s\n",
+ EC_DBG("FMMU: LogAddr 0x%08X, Size %3u, PhysAddr 0x%04X, Dir %s\n",
fmmu->logical_start_address, fmmu->data_size,
sync->physical_start_address,
(sync->control_register & 0x04) ? "out" : "in");
--- a/master/fmmu_config.h Wed Jun 04 10:41:50 2008 +0000
+++ b/master/fmmu_config.h Wed Jun 04 13:17:15 2008 +0000
@@ -50,6 +50,7 @@
/** FMMU configuration.
*/
typedef struct {
+ struct list_head list; /**< List node used by domain. */
const ec_slave_config_t *sc; /**< EtherCAT slave config. */
const ec_domain_t *domain; /**< Domain. */
ec_direction_t dir; /**< Pdo direction. */
--- a/master/ioctl.h Wed Jun 04 10:41:50 2008 +0000
+++ b/master/ioctl.h Wed Jun 04 13:17:15 2008 +0000
@@ -51,6 +51,7 @@
EC_IOCTL_PDO_ENTRY,
EC_IOCTL_DOMAIN_COUNT,
EC_IOCTL_DOMAIN,
+ EC_IOCTL_DOMAIN_FMMU,
EC_IOCTL_DATA
};
@@ -135,6 +136,7 @@
uint32_t logical_base_address;
uint16_t working_counter;
uint16_t expected_working_counter;
+ unsigned int fmmu_count;
} ec_ioctl_domain_t;
/*****************************************************************************/
@@ -142,6 +144,21 @@
typedef struct {
// inputs
unsigned int domain_index;
+ unsigned int fmmu_index;
+
+ // outputs
+ uint16_t slave_config_alias;
+ uint16_t slave_config_position;
+ uint8_t fmmu_dir;
+ uint32_t logical_address;
+ unsigned int data_size;
+} ec_ioctl_domain_fmmu_t;
+
+/*****************************************************************************/
+
+typedef struct {
+ // inputs
+ unsigned int domain_index;
unsigned int data_size;
unsigned char *target;
} ec_ioctl_data_t;
--- a/tools/Master.cpp Wed Jun 04 10:41:50 2008 +0000
+++ b/tools/Master.cpp Wed Jun 04 13:17:15 2008 +0000
@@ -166,17 +166,16 @@
getDomain(&domain, domainIndex);
+ if (!domain.data_size)
+ return;
+
processData = new unsigned char[domain.data_size];
- data.domain_index = domainIndex;
- data.data_size = domain.data_size;
- data.target = processData;
-
- if (ioctl(fd, EC_IOCTL_DATA, &data) < 0) {
- stringstream err;
- err << "Failed to get domain data: " << strerror(errno);
+ try {
+ getData(&data, domainIndex, domain.data_size, processData);
+ } catch (MasterException &e) {
delete [] processData;
- throw MasterException(err.str());
+ throw e;
}
for (i = 0; i < data.data_size; i++)
@@ -190,18 +189,64 @@
void Master::showDomain(unsigned int domainIndex)
{
- ec_ioctl_domain_t data;
+ ec_ioctl_domain_t domain;
+ unsigned char *processData;
+ ec_ioctl_data_t data;
+ unsigned int i, j;
+ ec_ioctl_domain_fmmu_t fmmu;
+ unsigned int dataOffset;
- getDomain(&data, domainIndex);
+ getDomain(&domain, domainIndex);
cout << "Domain" << domainIndex << ":"
<< " LogBaseAddr 0x"
- << hex << setfill('0') << setw(8) << data.logical_base_address
- << ", Size " << dec << data.data_size
+ << hex << setfill('0') << setw(8) << domain.logical_base_address
+ << ", Size " << dec << setfill(' ') << setw(3) << domain.data_size
<< ", WorkingCounter "
- << dec << data.working_counter
- << " of " << data.expected_working_counter
- << endl;
+ << dec << setw(3) << domain.working_counter
+ << " of " << setw(3) << domain.expected_working_counter << endl;
+
+ if (!domain.data_size)
+ return;
+
+ processData = new unsigned char[domain.data_size];
+
+ try {
+ getData(&data, domainIndex, domain.data_size, processData);
+ } catch (MasterException &e) {
+ delete [] processData;
+ throw e;
+ }
+
+ for (i = 0; i < domain.fmmu_count; i++) {
+ getFmmu(&fmmu, domainIndex, i);
+
+ cout << " " << (fmmu.fmmu_dir ? "Inputs" : "Outputs")
+ << " from slave config " << fmmu.slave_config_alias
+ << ":" << fmmu.slave_config_position
+ << ", LogAddr 0x"
+ << hex << setfill('0') << setw(8) << fmmu.logical_address
+ << ", Size "
+ << dec << setfill(' ') << setw(3) << fmmu.data_size
+ << endl;
+
+ dataOffset = fmmu.logical_address - domain.logical_base_address;
+ if (dataOffset + fmmu.data_size > domain.data_size) {
+ stringstream err;
+ err << "Fmmu information corrupted!";
+ delete [] processData;
+ throw MasterException(err.str());
+ }
+
+ cout << " " << hex << setfill('0');
+ for (j = 0; j < fmmu.data_size; j++) {
+ cout << setw(2)
+ << (unsigned int) *(processData + dataOffset + j) << " ";
+ }
+ cout << endl;
+ }
+
+ delete [] processData;
}
/****************************************************************************/
@@ -401,6 +446,22 @@
/****************************************************************************/
+void Master::getData(ec_ioctl_data_t *data, unsigned int domainIndex,
+ unsigned int dataSize, unsigned char *mem)
+{
+ data->domain_index = domainIndex;
+ data->data_size = dataSize;
+ data->target = mem;
+
+ if (ioctl(fd, EC_IOCTL_DATA, data) < 0) {
+ stringstream err;
+ err << "Failed to get domain data: " << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
void Master::getSlave(ec_ioctl_slave_t *slave, uint16_t slaveIndex)
{
slave->position = slaveIndex;
@@ -418,6 +479,30 @@
/****************************************************************************/
+void Master::getFmmu(
+ ec_ioctl_domain_fmmu_t *fmmu,
+ unsigned int domainIndex,
+ unsigned int fmmuIndex
+ )
+{
+ fmmu->domain_index = domainIndex;
+ fmmu->fmmu_index = fmmuIndex;
+
+ if (ioctl(fd, EC_IOCTL_DOMAIN_FMMU, fmmu)) {
+ stringstream err;
+ err << "Failed to get domain FMMU: ";
+ if (errno == EINVAL)
+ err << "Either domain " << domainIndex << " does not exist, "
+ << "or it contains less than " << (unsigned int) fmmuIndex + 1
+ << " FMMus!";
+ else
+ err << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
void Master::getSync(
ec_ioctl_sync_t *sync,
uint16_t slaveIndex,
@@ -432,7 +517,7 @@
err << "Failed to get sync manager: ";
if (errno == EINVAL)
err << "Either slave " << slaveIndex << " does not exist, "
- << "or contains less than " << (unsigned int) syncIndex + 1
+ << "or it contains less than " << (unsigned int) syncIndex + 1
<< " sync managers!";
else
err << strerror(errno);
@@ -458,7 +543,7 @@
err << "Failed to get Pdo: ";
if (errno == EINVAL)
err << "Either slave " << slaveIndex << " does not exist, "
- << "or contains less than " << (unsigned int) syncIndex + 1
+ << "or it contains less than " << (unsigned int) syncIndex + 1
<< " sync managers, or sync manager "
<< (unsigned int) syncIndex << " contains less than "
<< pdoPos + 1 << " Pdos!" << endl;
@@ -488,7 +573,7 @@
err << "Failed to get Pdo entry: ";
if (errno == EINVAL)
err << "Either slave " << slaveIndex << " does not exist, "
- << "or contains less than " << (unsigned int) syncIndex + 1
+ << "or it contains less than " << (unsigned int) syncIndex + 1
<< " sync managers, or sync manager "
<< (unsigned int) syncIndex << " contains less than "
<< pdoPos + 1 << " Pdos, or the Pdo at position " << pdoPos
--- a/tools/Master.h Wed Jun 04 10:41:50 2008 +0000
+++ b/tools/Master.h Wed Jun 04 13:17:15 2008 +0000
@@ -55,6 +55,9 @@
unsigned int slaveCount();
void slaveSyncs(uint16_t);
void getDomain(ec_ioctl_domain_t *, unsigned int);
+ void getFmmu(ec_ioctl_domain_fmmu_t *, unsigned int, unsigned int);
+ void getData(ec_ioctl_data_t *, unsigned int, unsigned int,
+ unsigned char *);
void getSlave(ec_ioctl_slave_t *, uint16_t);
void getSync(ec_ioctl_sync_t *, uint16_t, uint8_t);
void getPdo(ec_ioctl_pdo_t *, uint16_t, uint8_t, uint8_t);