Implemented Sdo dictionary info via 'ethercat sdos'.
This commit is contained in:
parent
fea56d5aa6
commit
9329e1727e
2
TODO
2
TODO
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
105
tools/Master.cpp
105
tools/Master.cpp
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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") {
|
||||
|
|
|
|||
Loading…
Reference in New Issue