Implemented Sdo dictionary info via 'ethercat sdos'.

This commit is contained in:
Florian Pose 2008-06-06 09:27:24 +00:00
parent fea56d5aa6
commit 9329e1727e
6 changed files with 247 additions and 8 deletions

2
TODO
View File

@ -10,8 +10,6 @@ Version 1.4.0:
* Slaves as array.
* Replace all Sysfs files via the new ethercat tool.
- Sdo info
- Sdo entry info
- Sdo entry value read
- Sdo entry value write
- Slave alias write

View File

@ -195,6 +195,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
data.state = slave->current_state;
data.sync_count = slave->sii.sync_count;
data.sdo_count = ec_slave_sdo_count(slave);
if (slave->sii.name) {
strncpy(data.name, slave->sii.name,
@ -499,6 +500,104 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
break;
}
case EC_IOCTL_SDO:
{
ec_ioctl_sdo_t data;
const ec_slave_t *slave;
const ec_sdo_t *sdo;
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 (!(sdo = ec_slave_get_sdo_by_pos_const(
slave, data.sdo_position))) {
EC_ERR("Sdo %u does not exist in slave %u!\n",
data.sdo_position, data.slave_position);
retval = -EINVAL;
break;
}
data.sdo_index = sdo->index;
data.max_subindex = sdo->max_subindex;
if (sdo->name) {
strncpy(data.name, sdo->name, EC_IOCTL_SDO_NAME_SIZE);
data.name[EC_IOCTL_SDO_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_SDO_ENTRY:
{
ec_ioctl_sdo_entry_t data;
const ec_slave_t *slave;
const ec_sdo_t *sdo;
const ec_sdo_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 (!(sdo = ec_slave_get_sdo_by_pos_const(
slave, data.sdo_position))) {
EC_ERR("Sdo %u does not exist in slave %u!\n",
data.sdo_position, data.slave_position);
retval = -EINVAL;
break;
}
if (!(entry = ec_sdo_get_entry_const(
sdo, data.sdo_entry_subindex))) {
EC_ERR("Sdo entry %u does not exist in Sdo %u "
"in slave %u!\n", data.sdo_entry_subindex,
data.sdo_position, data.slave_position);
retval = -EINVAL;
break;
}
data.data_type = entry->data_type;
data.bit_length = entry->bit_length;
if (entry->description) {
strncpy(data.description, entry->description,
EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE);
data.description[EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE - 1]
= 0;
} else {
data.description[0] = 0;
}
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
retval = -EFAULT;
break;
}
break;
}
default:
retval = -ENOIOCTLCMD;
}

View File

@ -55,6 +55,8 @@ enum {
EC_IOCTL_DATA,
EC_IOCTL_SET_DEBUG,
EC_IOCTL_SLAVE_STATE,
EC_IOCTL_SDO,
EC_IOCTL_SDO_ENTRY,
};
/*****************************************************************************/
@ -72,7 +74,7 @@ typedef struct {
/*****************************************************************************/
#define EC_IOCTL_SLAVE_NAME_SIZE 114
#define EC_IOCTL_SLAVE_NAME_SIZE 104
typedef struct {
// input
@ -86,6 +88,7 @@ typedef struct {
uint16_t alias;
uint8_t state;
uint8_t sync_count;
uint16_t sdo_count;
char name[EC_IOCTL_SLAVE_NAME_SIZE];
} ec_ioctl_slave_t;
@ -188,4 +191,35 @@ typedef struct {
/*****************************************************************************/
#define EC_IOCTL_SDO_NAME_SIZE 121
typedef struct {
// inputs
uint16_t slave_position;
uint16_t sdo_position;
// outputs
uint16_t sdo_index;
uint8_t max_subindex;
char name[EC_IOCTL_SDO_NAME_SIZE];
} ec_ioctl_sdo_t;
/*****************************************************************************/
#define EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE 120
typedef struct {
// inputs
uint16_t slave_position;
uint16_t sdo_position;
uint8_t sdo_entry_subindex;
// outputs
uint16_t data_type;
uint16_t bit_length;
char description[EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE];
} ec_ioctl_sdo_entry_t;
/*****************************************************************************/
#endif

View File

@ -224,6 +224,21 @@ void Master::listPdos(int slavePosition)
/****************************************************************************/
void Master::listSdos(int slavePosition)
{
if (slavePosition == -1) {
unsigned int numSlaves = slaveCount(), i;
for (i = 0; i < numSlaves; i++) {
listSlaveSdos(i, true);
}
} else {
listSlaveSdos(slavePosition, false);
}
}
/****************************************************************************/
void Master::requestStates(
int slavePosition,
const vector<string> &commandArgs
@ -375,7 +390,7 @@ void Master::showDomain(unsigned int domainIndex)
/****************************************************************************/
void Master::listSlavePdos(uint16_t slavePosition, bool printSlave)
void Master::listSlavePdos(uint16_t slavePosition, bool withHeader)
{
ec_ioctl_slave_t slave;
ec_ioctl_sync_t sync;
@ -385,7 +400,7 @@ void Master::listSlavePdos(uint16_t slavePosition, bool printSlave)
getSlave(&slave, slavePosition);
if (printSlave)
if (withHeader)
cout << "=== Slave " << slavePosition << " ===" << endl;
for (i = 0; i < slave.sync_count; i++) {
@ -425,6 +440,40 @@ void Master::listSlavePdos(uint16_t slavePosition, bool printSlave)
/****************************************************************************/
void Master::listSlaveSdos(uint16_t slavePosition, bool withHeader)
{
ec_ioctl_slave_t slave;
ec_ioctl_sdo_t sdo;
ec_ioctl_sdo_entry_t entry;
unsigned int i, j, k;
getSlave(&slave, slavePosition);
if (withHeader)
cout << "=== Slave " << slavePosition << " ===" << endl;
for (i = 0; i < slave.sdo_count; i++) {
getSdo(&sdo, slavePosition, i);
cout << "Sdo 0x"
<< hex << setfill('0') << setw(4) << sdo.sdo_index
<< ", \"" << sdo.name << "\"" << endl;
for (j = 0; j <= sdo.max_subindex; j++) {
getSdoEntry(&entry, slavePosition, i, j);
cout << " Entry 0x"
<< hex << setfill('0') << setw(2)
<< (unsigned int) entry.sdo_entry_subindex
<< ", type 0x" << setw(4) << entry.data_type
<< ", " << dec << entry.bit_length << " bit, \""
<< entry.description << "\"" << endl;
}
}
}
/****************************************************************************/
void Master::generateSlaveXml(uint16_t slavePosition)
{
ec_ioctl_slave_t slave;
@ -717,6 +766,58 @@ void Master::getPdoEntry(
/****************************************************************************/
void Master::getSdo(
ec_ioctl_sdo_t *sdo,
uint16_t slaveIndex,
uint16_t sdoPosition
)
{
sdo->slave_position = slaveIndex;
sdo->sdo_position = sdoPosition;
if (ioctl(fd, EC_IOCTL_SDO, sdo)) {
stringstream err;
err << "Failed to get Sdo: ";
if (errno == EINVAL)
err << "Either slave " << slaveIndex << " does not exist, "
<< "or it contains less than " << sdoPosition + 1 << " Sdos!"
<< endl;
else
err << strerror(errno);
throw MasterException(err.str());
}
}
/****************************************************************************/
void Master::getSdoEntry(
ec_ioctl_sdo_entry_t *entry,
uint16_t slaveIndex,
uint16_t sdoPosition,
uint8_t entrySubindex
)
{
entry->slave_position = slaveIndex;
entry->sdo_position = sdoPosition;
entry->sdo_entry_subindex = entrySubindex;
if (ioctl(fd, EC_IOCTL_SDO_ENTRY, entry)) {
stringstream err;
err << "Failed to get Sdo entry: ";
if (errno == EINVAL)
err << "Either slave " << slaveIndex << " does not exist, "
<< "or it contains less than " << sdoPosition + 1
<< " Sdos, or the Sdo at position " << sdoPosition
<< " contains less than " << (unsigned int) entrySubindex + 1
<< " entries!" << endl;
else
err << strerror(errno);
throw MasterException(err.str());
}
}
/****************************************************************************/
void Master::requestState(
uint16_t slavePosition,
uint8_t state

View File

@ -48,6 +48,7 @@ class Master
void listSlaves();
void showMaster();
void listPdos(int);
void listSdos(int);
void requestStates(int, const vector<string> &);
void generateXml(int);
@ -55,6 +56,7 @@ class Master
void outputDomainData(unsigned int);
void showDomain(unsigned int);
void listSlavePdos(uint16_t, bool = false);
void listSlaveSdos(uint16_t, bool = false);
void generateSlaveXml(uint16_t);
unsigned int domainCount();
unsigned int slaveCount();
@ -69,6 +71,8 @@ class Master
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);
void getSdo(ec_ioctl_sdo_t *, uint16_t, uint16_t);
void getSdoEntry(ec_ioctl_sdo_entry_t *, uint16_t, uint16_t, uint8_t);
void requestState(uint16_t, uint8_t);
static string slaveState(uint8_t);

View File

@ -38,9 +38,10 @@ void printUsage()
<< " domain Show domain information." << endl
<< " list (ls, slaves) List all slaves (former 'lsec')." << endl
<< " master Show master information." << endl
<< " pdos List Pdo mapping of given slaves." << endl
<< " state Request slave state(s)." << endl
<< " xml Generate slave information xml." << endl
<< " pdos List Pdo mapping." << endl
<< " sdos List Sdo dictionaries." << endl
<< " state Request slave states." << endl
<< " xml Generate slave information xmls." << endl
<< "Global options:" << endl
<< " --master -m <master> Index of the master to use. Default: "
<< DEFAULT_MASTER << endl
@ -163,6 +164,8 @@ int main(int argc, char **argv)
master.showMaster();
} else if (command == "pdos") {
master.listPdos(slavePosition);
} else if (command == "sdos") {
master.listSdos(slavePosition);
} else if (command == "state") {
master.requestStates(slavePosition, commandArgs);
} else if (command == "xml") {