'ethercat domain' shows domain contents and process data.
This commit is contained in:
parent
c74e50706b
commit
4d5b2a41a8
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
121
tools/Master.cpp
121
tools/Master.cpp
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue