Added 'pdos' command to ethercat tool.
This commit is contained in:
parent
12287e723e
commit
fd77ad604d
273
master/cdev.c
273
master/cdev.c
|
|
@ -52,15 +52,15 @@ int eccdev_open(struct inode *, struct file *);
|
|||
int eccdev_release(struct inode *, struct file *);
|
||||
ssize_t eccdev_read(struct file *, char __user *, size_t, loff_t *);
|
||||
ssize_t eccdev_write(struct file *, const char __user *, size_t, loff_t *);
|
||||
int eccdev_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
|
||||
long eccdev_ioctl(struct file *, unsigned int, unsigned long);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static struct file_operations eccdev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = eccdev_open,
|
||||
.release = eccdev_release,
|
||||
.ioctl = eccdev_ioctl
|
||||
.owner = THIS_MODULE,
|
||||
.open = eccdev_open,
|
||||
.release = eccdev_release,
|
||||
.unlocked_ioctl = eccdev_ioctl
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
|
|
@ -107,9 +107,11 @@ void ec_cdev_clear(ec_cdev_t *cdev /**< EtherCAT XML device */)
|
|||
int eccdev_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
|
||||
ec_master_t *master = cdev->master;
|
||||
|
||||
filp->private_data = cdev;
|
||||
EC_DBG("File opened.\n");
|
||||
if (master->debug_level)
|
||||
EC_DBG("File opened.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -117,88 +119,237 @@ int eccdev_open(struct inode *inode, struct file *filp)
|
|||
|
||||
int eccdev_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
//ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
|
||||
ec_cdev_t *cdev = (ec_cdev_t *) filp->private_data;
|
||||
ec_master_t *master = cdev->master;
|
||||
|
||||
EC_DBG("File closed.\n");
|
||||
if (master->debug_level)
|
||||
EC_DBG("File closed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int eccdev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
|
||||
ec_cdev_t *cdev = (ec_cdev_t *) filp->private_data;
|
||||
ec_master_t *master = cdev->master;
|
||||
long retval = 0;
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("ioctl(inode = %x, filp = %x, cmd = %u, arg = %u)\n",
|
||||
(u32) inode, (u32) filp, (u32) cmd, (u32) arg);
|
||||
EC_DBG("ioctl(filp = %x, cmd = %u, arg = %u)\n",
|
||||
(u32) filp, (u32) cmd, (u32) arg);
|
||||
|
||||
// FIXME lock
|
||||
|
||||
switch (cmd) {
|
||||
case EC_IOCTL_SLAVE_COUNT:
|
||||
retval = master->slave_count;
|
||||
break;
|
||||
|
||||
case EC_IOCTL_SLAVE:
|
||||
{
|
||||
unsigned int slave_count = master->slave_count;
|
||||
EC_INFO("EC_IOCTL_SLAVE_COUNT\n");
|
||||
if (!arg)
|
||||
return -EFAULT;
|
||||
if (copy_to_user((void __user *) arg, &slave_count,
|
||||
sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
ec_ioctl_slave_t data;
|
||||
const ec_slave_t *slave;
|
||||
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(slave = ec_master_find_slave(
|
||||
master, 0, data.position))) {
|
||||
EC_ERR("Slave %u does not exist!\n", data.position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data.vendor_id = slave->sii.vendor_id;
|
||||
data.product_code = slave->sii.product_code;
|
||||
data.alias = slave->sii.alias;
|
||||
data.state = slave->current_state;
|
||||
|
||||
data.sync_count = slave->sii.sync_count;
|
||||
|
||||
if (slave->sii.name) {
|
||||
strncpy(data.name, slave->sii.name,
|
||||
EC_IOCTL_SLAVE_NAME_SIZE);
|
||||
data.name[EC_IOCTL_SLAVE_NAME_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EC_IOCTL_SLAVE_INFO:
|
||||
case EC_IOCTL_SYNC:
|
||||
{
|
||||
struct ec_ioctl_slave_info *infos, *info;
|
||||
unsigned int slave_count = master->slave_count;
|
||||
ec_ioctl_sync_t data;
|
||||
const ec_slave_t *slave;
|
||||
unsigned int i = 0;
|
||||
const ec_sync_t *sync;
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("EC_IOCTL_SLAVE_INFOS\n");
|
||||
|
||||
if (!slave_count)
|
||||
return 0;
|
||||
|
||||
if (!arg)
|
||||
return -EFAULT;
|
||||
|
||||
if (!(infos = kmalloc(slave_count *
|
||||
sizeof(struct ec_ioctl_slave_info),
|
||||
GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
|
||||
list_for_each_entry(slave, &master->slaves, list) {
|
||||
info = &infos[i++];
|
||||
info->vendor_id = slave->sii.vendor_id;
|
||||
info->product_code = slave->sii.product_code;
|
||||
info->alias = slave->sii.alias;
|
||||
info->ring_position = slave->ring_position;
|
||||
info->state = slave->current_state;
|
||||
if (slave->sii.name) {
|
||||
strncpy(info->description, slave->sii.name,
|
||||
EC_IOCTL_SLAVE_INFO_DESC_SIZE);
|
||||
info->description[EC_IOCTL_SLAVE_INFO_DESC_SIZE - 1]
|
||||
= 0;
|
||||
} else {
|
||||
info->description[0] = 0;
|
||||
}
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(slave = ec_master_find_slave(
|
||||
master, 0, data.slave_position))) {
|
||||
EC_ERR("Slave %u does not exist!\n", data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *) arg, infos, slave_count *
|
||||
sizeof(struct ec_ioctl_slave_info))) {
|
||||
kfree(infos);
|
||||
return -EFAULT;
|
||||
if (data.sync_index >= slave->sii.sync_count) {
|
||||
EC_ERR("Sync manager %u does not exist in slave %u!\n",
|
||||
data.sync_index, data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(infos);
|
||||
return 0;
|
||||
sync = &slave->sii.syncs[data.sync_index];
|
||||
|
||||
data.physical_start_address = sync->physical_start_address;
|
||||
data.default_size = sync->length;
|
||||
data.control_register = sync->control_register;
|
||||
data.enable = sync->enable;
|
||||
data.assign_source = sync->assign_source;
|
||||
data.pdo_count = ec_pdo_list_count(&sync->pdos);
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EC_IOCTL_PDO:
|
||||
{
|
||||
ec_ioctl_pdo_t data;
|
||||
const ec_slave_t *slave;
|
||||
const ec_sync_t *sync;
|
||||
const ec_pdo_t *pdo;
|
||||
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(slave = ec_master_find_slave(
|
||||
master, 0, data.slave_position))) {
|
||||
EC_ERR("Slave %u does not exist!\n", data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.sync_index >= slave->sii.sync_count) {
|
||||
EC_ERR("Sync manager %u does not exist in slave %u!\n",
|
||||
data.sync_index, data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
sync = &slave->sii.syncs[data.sync_index];
|
||||
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
|
||||
&sync->pdos, data.pdo_pos))) {
|
||||
EC_ERR("Sync manager %u does not contain a Pdo with "
|
||||
"position %u in slave %u!\n", data.sync_index,
|
||||
data.pdo_pos, data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data.dir = pdo->dir;
|
||||
data.index = pdo->index;
|
||||
data.entry_count = ec_pdo_entry_count(pdo);
|
||||
|
||||
if (pdo->name) {
|
||||
strncpy(data.name, pdo->name, EC_IOCTL_PDO_NAME_SIZE);
|
||||
data.name[EC_IOCTL_PDO_NAME_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EC_IOCTL_PDO_ENTRY:
|
||||
{
|
||||
ec_ioctl_pdo_entry_t data;
|
||||
const ec_slave_t *slave;
|
||||
const ec_sync_t *sync;
|
||||
const ec_pdo_t *pdo;
|
||||
const ec_pdo_entry_t *entry;
|
||||
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(slave = ec_master_find_slave(
|
||||
master, 0, data.slave_position))) {
|
||||
EC_ERR("Slave %u does not exist!\n", data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.sync_index >= slave->sii.sync_count) {
|
||||
EC_ERR("Sync manager %u does not exist in slave %u!\n",
|
||||
data.sync_index, data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
sync = &slave->sii.syncs[data.sync_index];
|
||||
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
|
||||
&sync->pdos, data.pdo_pos))) {
|
||||
EC_ERR("Sync manager %u does not contain a Pdo with "
|
||||
"position %u in slave %u!\n", data.sync_index,
|
||||
data.pdo_pos, data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(entry = ec_pdo_find_entry_by_pos_const(
|
||||
pdo, data.entry_pos))) {
|
||||
EC_ERR("Pdo 0x%04X does not contain an entry with "
|
||||
"position %u in slave %u!\n", data.pdo_pos,
|
||||
data.entry_pos, data.slave_position);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data.index = entry->index;
|
||||
data.subindex = entry->subindex;
|
||||
data.bit_length = entry->bit_length;
|
||||
if (entry->name) {
|
||||
strncpy(data.name, entry->name,
|
||||
EC_IOCTL_PDO_ENTRY_NAME_SIZE);
|
||||
data.name[EC_IOCTL_PDO_ENTRY_NAME_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
retval = -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -44,22 +44,80 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
EC_IOCTL_SLAVE_COUNT = 0,
|
||||
EC_IOCTL_SLAVE_INFO,
|
||||
EC_IOCTL_SLAVE_COUNT,
|
||||
EC_IOCTL_SLAVE,
|
||||
EC_IOCTL_SYNC,
|
||||
EC_IOCTL_PDO,
|
||||
EC_IOCTL_PDO_ENTRY,
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_SLAVE_INFO_DESC_SIZE 243
|
||||
#define EC_IOCTL_SLAVE_NAME_SIZE 114
|
||||
|
||||
struct ec_ioctl_slave_info {
|
||||
typedef struct {
|
||||
// input
|
||||
uint16_t position;
|
||||
|
||||
// outputs
|
||||
uint32_t vendor_id;
|
||||
uint32_t product_code;
|
||||
uint16_t alias;
|
||||
uint16_t ring_position;
|
||||
uint8_t state;
|
||||
char description[EC_IOCTL_SLAVE_INFO_DESC_SIZE];
|
||||
};
|
||||
uint8_t sync_count;
|
||||
char name[EC_IOCTL_SLAVE_NAME_SIZE];
|
||||
} ec_ioctl_slave_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint16_t slave_position;
|
||||
unsigned int sync_index;
|
||||
|
||||
// outputs
|
||||
uint16_t physical_start_address;
|
||||
uint16_t default_size;
|
||||
uint8_t control_register;
|
||||
uint8_t enable;
|
||||
uint8_t assign_source;
|
||||
uint8_t pdo_count;
|
||||
} ec_ioctl_sync_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_PDO_NAME_SIZE 114
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint16_t slave_position;
|
||||
unsigned int sync_index;
|
||||
unsigned int pdo_pos;
|
||||
|
||||
// outputs
|
||||
uint8_t dir;
|
||||
uint16_t index;
|
||||
uint8_t entry_count;
|
||||
char name[EC_IOCTL_PDO_NAME_SIZE];
|
||||
} ec_ioctl_pdo_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_PDO_ENTRY_NAME_SIZE 110
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint16_t slave_position;
|
||||
unsigned int sync_index;
|
||||
unsigned int pdo_pos;
|
||||
unsigned int entry_pos;
|
||||
|
||||
// outputs
|
||||
uint16_t index;
|
||||
uint8_t subindex;
|
||||
uint8_t bit_length;
|
||||
char name[EC_IOCTL_PDO_NAME_SIZE];
|
||||
} ec_ioctl_pdo_entry_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
214
tools/Master.cpp
214
tools/Master.cpp
|
|
@ -16,7 +16,6 @@
|
|||
using namespace std;
|
||||
|
||||
#include "Master.h"
|
||||
#include "../master/ioctl.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
|
@ -63,70 +62,205 @@ void Master::close()
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
unsigned int Master::slaveCount()
|
||||
{
|
||||
unsigned int numSlaves;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_SLAVE_COUNT, &numSlaves)) {
|
||||
stringstream err;
|
||||
err << "Failed to get number of slaves: " << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
|
||||
return numSlaves;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::listSlaves()
|
||||
{
|
||||
unsigned int numSlaves = slaveCount(), i;
|
||||
struct ec_ioctl_slave_info *infos, *info;
|
||||
ec_ioctl_slave_t slave;
|
||||
uint16_t lastAlias, aliasIndex;
|
||||
|
||||
if (!numSlaves)
|
||||
return;
|
||||
|
||||
infos = new struct ec_ioctl_slave_info[numSlaves];
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_SLAVE_INFO, infos)) {
|
||||
stringstream err;
|
||||
err << "Failed to get slave information: " << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
|
||||
lastAlias = 0;
|
||||
aliasIndex = 0;
|
||||
for (i = 0; i < numSlaves; i++) {
|
||||
info = &infos[i];
|
||||
cout << setw(2) << info->ring_position << " ";
|
||||
getSlave(&slave, i);
|
||||
cout << setw(2) << i << " ";
|
||||
|
||||
if (info->alias) {
|
||||
lastAlias = info->alias;
|
||||
if (slave.alias) {
|
||||
lastAlias = slave.alias;
|
||||
aliasIndex = 0;
|
||||
}
|
||||
if (lastAlias) {
|
||||
cout << setw(10) << "#" << lastAlias << ":" << aliasIndex;
|
||||
}
|
||||
|
||||
cout << " " << slaveState(info->state) << " ";
|
||||
cout << " " << slaveState(slave.state) << " ";
|
||||
|
||||
if (strlen(info->description)) {
|
||||
cout << info->description;
|
||||
if (strlen(slave.name)) {
|
||||
cout << slave.name;
|
||||
} else {
|
||||
cout << "0x" << hex << setfill('0') << info->vendor_id
|
||||
<< ":0x" << info->product_code;
|
||||
cout << "0x" << hex << setfill('0') << slave.vendor_id
|
||||
<< ":0x" << slave.product_code;
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
delete [] infos;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
string Master::slaveState(uint8_t state) const
|
||||
void Master::listPdos(int slavePosition)
|
||||
{
|
||||
ec_ioctl_slave_t slave;
|
||||
ec_ioctl_sync_t sync;
|
||||
ec_ioctl_pdo_t pdo;
|
||||
ec_ioctl_pdo_entry_t entry;
|
||||
unsigned int i, j, k;
|
||||
|
||||
getSlave(&slave, slavePosition);
|
||||
|
||||
for (i = 0; i < slave.sync_count; i++) {
|
||||
getSync(&sync, slavePosition, i);
|
||||
|
||||
cout << "SM" << i << ":"
|
||||
<< " PhysAddr 0x"
|
||||
<< hex << setfill('0') << setw(4) << sync.physical_start_address
|
||||
<< ", DefaultSize "
|
||||
<< dec << setfill(' ') << setw(4) << sync.default_size
|
||||
<< ", ControlRegister 0x"
|
||||
<< hex << setfill('0') << setw(2)
|
||||
<< (unsigned int) sync.control_register
|
||||
<< ", Enable " << dec << (unsigned int) sync.enable
|
||||
<< endl;
|
||||
|
||||
for (j = 0; j < sync.pdo_count; j++) {
|
||||
getPdo(&pdo, slavePosition, i, j);
|
||||
|
||||
cout << " " << (pdo.dir ? "T" : "R") << "xPdo 0x"
|
||||
<< hex << setfill('0') << setw(4) << pdo.index
|
||||
<< " \"" << pdo.name << "\"" << endl;
|
||||
|
||||
for (k = 0; k < pdo.entry_count; k++) {
|
||||
getPdoEntry(&entry, slavePosition, i, j, k);
|
||||
|
||||
cout << " Pdo entry 0x"
|
||||
<< hex << setfill('0') << setw(4) << entry.index
|
||||
<< ":" << hex << setfill('0') << setw(2)
|
||||
<< (unsigned int) entry.subindex
|
||||
<< ", " << dec << (unsigned int) entry.bit_length
|
||||
<< " bit, \"" << entry.name << "\"" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
unsigned int Master::slaveCount()
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = ioctl(fd, EC_IOCTL_SLAVE_COUNT, 0)) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to get slave: " << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getSlave(ec_ioctl_slave_t *slave, uint16_t slaveIndex)
|
||||
{
|
||||
slave->position = slaveIndex;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_SLAVE, slave)) {
|
||||
stringstream err;
|
||||
err << "Failed to get slave: ";
|
||||
if (errno == EINVAL)
|
||||
err << "Slave " << slaveIndex << " does not exist!";
|
||||
else
|
||||
err << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getSync(
|
||||
ec_ioctl_sync_t *sync,
|
||||
uint16_t slaveIndex,
|
||||
uint8_t syncIndex
|
||||
)
|
||||
{
|
||||
sync->slave_position = slaveIndex;
|
||||
sync->sync_index = syncIndex;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_SYNC, sync)) {
|
||||
stringstream err;
|
||||
err << "Failed to get sync manager: ";
|
||||
if (errno == EINVAL)
|
||||
err << "Either slave " << slaveIndex << " does not exist, "
|
||||
<< "or contains less than " << (unsigned int) syncIndex + 1
|
||||
<< " sync managers!";
|
||||
else
|
||||
err << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getPdo(
|
||||
ec_ioctl_pdo_t *pdo,
|
||||
uint16_t slaveIndex,
|
||||
uint8_t syncIndex,
|
||||
uint8_t pdoPos
|
||||
)
|
||||
{
|
||||
pdo->slave_position = slaveIndex;
|
||||
pdo->sync_index = syncIndex;
|
||||
pdo->pdo_pos = pdoPos;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_PDO, pdo)) {
|
||||
stringstream err;
|
||||
err << "Failed to get Pdo: ";
|
||||
if (errno == EINVAL)
|
||||
err << "Either slave " << slaveIndex << " does not exist, "
|
||||
<< "or contains less than " << (unsigned int) syncIndex + 1
|
||||
<< " sync managers, or sync manager "
|
||||
<< (unsigned int) syncIndex << " contains less than "
|
||||
<< pdoPos + 1 << " Pdos!" << endl;
|
||||
else
|
||||
err << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getPdoEntry(
|
||||
ec_ioctl_pdo_entry_t *entry,
|
||||
uint16_t slaveIndex,
|
||||
uint8_t syncIndex,
|
||||
uint8_t pdoPos,
|
||||
uint8_t entryPos
|
||||
)
|
||||
{
|
||||
entry->slave_position = slaveIndex;
|
||||
entry->sync_index = syncIndex;
|
||||
entry->pdo_pos = pdoPos;
|
||||
entry->entry_pos = entryPos;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_PDO_ENTRY, entry)) {
|
||||
stringstream err;
|
||||
err << "Failed to get Pdo entry: ";
|
||||
if (errno == EINVAL)
|
||||
err << "Either slave " << slaveIndex << " does not exist, "
|
||||
<< "or 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
|
||||
<< " contains less than " << (unsigned int) entryPos + 1
|
||||
<< " entries!" << endl;
|
||||
else
|
||||
err << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
string Master::slaveState(uint8_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case 1: return "INIT";
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include <stdexcept>
|
||||
using namespace std;
|
||||
|
||||
#include "../master/ioctl.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
class MasterException:
|
||||
|
|
@ -38,11 +40,19 @@ class Master
|
|||
void open(unsigned int);
|
||||
void close();
|
||||
|
||||
unsigned int slaveCount();
|
||||
void listSlaves();
|
||||
void listPdos(int);
|
||||
|
||||
protected:
|
||||
string slaveState(uint8_t) const;
|
||||
unsigned int slaveCount();
|
||||
void slaveSyncs(uint16_t);
|
||||
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);
|
||||
void getPdoEntry(ec_ioctl_pdo_entry_t *, uint16_t, uint8_t, uint8_t,
|
||||
uint8_t);
|
||||
|
||||
static string slaveState(uint8_t);
|
||||
|
||||
private:
|
||||
unsigned int index;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ using namespace std;
|
|||
#define DEFAULT_SLAVESPEC ""
|
||||
|
||||
static unsigned int masterIndex = DEFAULT_MASTER;
|
||||
static string slaveSpec = DEFAULT_SLAVESPEC;
|
||||
static int slavePosition = -1;
|
||||
static string command = DEFAULT_COMMAND;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -30,10 +30,11 @@ void printUsage()
|
|||
<< "Usage: ethercat <COMMAND> [OPTIONS]" << endl
|
||||
<< "Commands:" << endl
|
||||
<< " list (ls, slaves) List all slaves (former 'lsec')." << endl
|
||||
<< " pdos List Pdo mapping of given slaves." << endl
|
||||
<< "Global options:" << endl
|
||||
<< " --master -m <master> Index of the master to use. Default: "
|
||||
<< DEFAULT_MASTER << endl
|
||||
<< " --slave -s <slave> Slave specification. Default: All "
|
||||
<< " --slave -s <slave> Numerical ring position. Default: All "
|
||||
"slaves." << endl
|
||||
<< " --help -h Show this help." << endl;
|
||||
}
|
||||
|
|
@ -68,7 +69,14 @@ void getOptions(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 's':
|
||||
slaveSpec = optarg;
|
||||
number = strtoul(optarg, &remainder, 0);
|
||||
if (remainder == optarg || *remainder
|
||||
|| number < 0 || number > 0xFFFF) {
|
||||
cerr << "Invalid slave position " << optarg << "!" << endl;
|
||||
printUsage();
|
||||
exit(1);
|
||||
}
|
||||
slavePosition = number;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
|
|
@ -101,13 +109,21 @@ int main(int argc, char **argv)
|
|||
|
||||
getOptions(argc, argv);
|
||||
|
||||
master.open(masterIndex);
|
||||
try {
|
||||
master.open(masterIndex);
|
||||
|
||||
if (command == "list" || command == "ls" || command == "slaves") {
|
||||
master.listSlaves();
|
||||
} else {
|
||||
cerr << "Unknown command " << command << "!" << endl;
|
||||
printUsage();
|
||||
if (command == "list" || command == "ls" || command == "slaves") {
|
||||
master.listSlaves();
|
||||
|
||||
} else if (command == "pdos") {
|
||||
master.listPdos(slavePosition);
|
||||
} else {
|
||||
cerr << "Unknown command " << command << "!" << endl;
|
||||
printUsage();
|
||||
exit(1);
|
||||
}
|
||||
} catch (MasterException &e) {
|
||||
cerr << e.what() << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue