'ethercat domain' shows domain contents and process data.

This commit is contained in:
Florian Pose 2008-06-04 13:17:15 +00:00
parent c74e50706b
commit 4d5b2a41a8
8 changed files with 204 additions and 19 deletions

View File

@ -42,6 +42,7 @@
#include "cdev.h"
#include "master.h"
#include "slave_config.h"
#include "ioctl.h"
/*****************************************************************************/
@ -371,6 +372,44 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
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;

View File

@ -108,6 +108,7 @@ int ec_domain_init(
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 @@ void ec_domain_add_fmmu_config(
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 @@ ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< kobject */
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
*****************************************************************************/

View File

@ -74,6 +74,7 @@ struct ec_domain
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_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);
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

View File

@ -58,6 +58,7 @@ void ec_fmmu_config_init(
ec_direction_t dir /**< Pdo direction. */
)
{
INIT_LIST_HEAD(&fmmu->list);
fmmu->sc = sc;
fmmu->dir = dir;
@ -80,7 +81,7 @@ void ec_fmmu_config_page(
)
{
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");

View File

@ -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. */

View File

@ -51,6 +51,7 @@ enum {
EC_IOCTL_PDO_ENTRY,
EC_IOCTL_DOMAIN_COUNT,
EC_IOCTL_DOMAIN,
EC_IOCTL_DOMAIN_FMMU,
EC_IOCTL_DATA
};
@ -135,10 +136,26 @@ typedef struct {
uint32_t logical_base_address;
uint16_t working_counter;
uint16_t expected_working_counter;
unsigned int fmmu_count;
} ec_ioctl_domain_t;
/*****************************************************************************/
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;

View File

@ -166,17 +166,16 @@ void Master::outputDomainData(unsigned int domainIndex)
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::outputDomainData(unsigned int domainIndex)
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::getDomain(ec_ioctl_domain_t *data, unsigned int index)
/****************************************************************************/
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::getSlave(ec_ioctl_slave_t *slave, uint16_t slaveIndex)
/****************************************************************************/
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 @@ void Master::getSync(
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 @@ void Master::getPdo(
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 @@ void Master::getPdoEntry(
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

View File

@ -55,6 +55,9 @@ class Master
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);