# HG changeset patch # User Florian Pose # Date 1212585435 0 # Node ID 8b00e63fff90368256016beed14ce1f3fc9e4f93 # Parent e424c0074c672de9106d04b6e0c89d293f252f56 'ethercat domain' shows domain contents and process data. diff -r e424c0074c67 -r 8b00e63fff90 master/cdev.c --- 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; diff -r e424c0074c67 -r 8b00e63fff90 master/domain.c --- 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 *****************************************************************************/ diff -r e424c0074c67 -r 8b00e63fff90 master/domain.h --- 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 diff -r e424c0074c67 -r 8b00e63fff90 master/fmmu_config.c --- 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"); diff -r e424c0074c67 -r 8b00e63fff90 master/fmmu_config.h --- 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. */ diff -r e424c0074c67 -r 8b00e63fff90 master/ioctl.h --- 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; diff -r e424c0074c67 -r 8b00e63fff90 tools/Master.cpp --- 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 diff -r e424c0074c67 -r 8b00e63fff90 tools/Master.h --- 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);