Slave information via 'ethercat slave'.
This commit is contained in:
parent
322845b160
commit
bc3c6f320a
1
TODO
1
TODO
|
|
@ -9,7 +9,6 @@ $Id$
|
|||
Version 1.4.0:
|
||||
|
||||
* Replace all Sysfs files via the new ethercat tool.
|
||||
- Slave info (mailbox, general)
|
||||
- Config info (alias, position, type, Pdos, Sdos)
|
||||
* Slaves as array.
|
||||
* Remove the end state of the master state machine.
|
||||
|
|
|
|||
|
|
@ -192,6 +192,15 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
data.revision_number = slave->sii.revision_number;
|
||||
data.serial_number = slave->sii.serial_number;
|
||||
data.alias = slave->sii.alias;
|
||||
data.rx_mailbox_offset = slave->sii.rx_mailbox_offset;
|
||||
data.rx_mailbox_size = slave->sii.rx_mailbox_size;
|
||||
data.tx_mailbox_offset = slave->sii.tx_mailbox_offset;
|
||||
data.tx_mailbox_size = slave->sii.tx_mailbox_size;
|
||||
data.mailbox_protocols = slave->sii.mailbox_protocols;
|
||||
data.has_general_category = slave->sii.has_general;
|
||||
data.coe_details = slave->sii.coe_details;
|
||||
data.general_flags = slave->sii.general_flags;
|
||||
data.current_on_ebus = slave->sii.current_on_ebus;
|
||||
data.state = slave->current_state;
|
||||
data.error_flag = slave->error_flag;
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,59 @@
|
|||
/** Size of an FMMU configuration page. */
|
||||
#define EC_FMMU_PAGE_SIZE 16
|
||||
|
||||
/** Slave state mask.
|
||||
*
|
||||
* Apply this mask to a slave state byte to get the slave state without
|
||||
* the error flag.
|
||||
*/
|
||||
#define EC_SLAVE_STATE_MASK 0x0F
|
||||
|
||||
/** State of an EtherCAT slave.
|
||||
*/
|
||||
typedef enum {
|
||||
EC_SLAVE_STATE_UNKNOWN = 0x00,
|
||||
/**< unknown state */
|
||||
EC_SLAVE_STATE_INIT = 0x01,
|
||||
/**< INIT state (no mailbox communication, no IO) */
|
||||
EC_SLAVE_STATE_PREOP = 0x02,
|
||||
/**< PREOP state (mailbox communication, no IO) */
|
||||
EC_SLAVE_STATE_SAFEOP = 0x04,
|
||||
/**< SAFEOP (mailbox communication and input update) */
|
||||
EC_SLAVE_STATE_OP = 0x08,
|
||||
/**< OP (mailbox communication and input/output update) */
|
||||
EC_SLAVE_STATE_ACK_ERR = 0x10
|
||||
/**< Acknowledge/Error bit (no actual state) */
|
||||
} ec_slave_state_t;
|
||||
|
||||
/** Supported mailbox protocols.
|
||||
*/
|
||||
enum {
|
||||
EC_MBOX_AOE = 0x01, /**< ADS-over-EtherCAT */
|
||||
EC_MBOX_EOE = 0x02, /**< Ethernet-over-EtherCAT */
|
||||
EC_MBOX_COE = 0x04, /**< CANopen-over-EtherCAT */
|
||||
EC_MBOX_FOE = 0x08, /**< File-Access-over-EtherCAT */
|
||||
EC_MBOX_SOE = 0x10, /**< Servo-Profile-over-EtherCAT */
|
||||
EC_MBOX_VOE = 0x20 /**< Vendor specific */
|
||||
};
|
||||
|
||||
/** Slave information interface CANopen-over-EtherCAT details flags.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t enable_sdo : 1; /**< Enable Sdo access. */
|
||||
uint8_t enable_sdo_info : 1; /**< SDO information service available. */
|
||||
uint8_t enable_pdo_assign : 1; /**< Pdo mapping configurable. */
|
||||
uint8_t enable_pdo_configuration : 1; /**< Pdo configuration possible. */
|
||||
uint8_t enable_upload_at_startup : 1; /**< ?. */
|
||||
uint8_t enable_sdo_complete_access : 1; /**< Complete access possible. */
|
||||
} ec_sii_coe_details_t;
|
||||
|
||||
/** Slave information interface general flags.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t enable_safeop : 1; /**< ?. */
|
||||
uint8_t enable_not_lrw : 1; /**< Slave does not support LRW. */
|
||||
} ec_sii_general_flags_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Convenience macro for printing EtherCAT-specific information to syslog.
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_TYPE 0xa4
|
||||
|
|
@ -85,7 +87,7 @@ typedef struct {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_SLAVE_NAME_SIZE 99
|
||||
#define EC_IOCTL_SLAVE_NAME_SIZE 77
|
||||
|
||||
typedef struct {
|
||||
// input
|
||||
|
|
@ -97,6 +99,15 @@ typedef struct {
|
|||
uint32_t revision_number;
|
||||
uint32_t serial_number;
|
||||
uint16_t alias;
|
||||
uint16_t rx_mailbox_offset;
|
||||
uint16_t rx_mailbox_size;
|
||||
uint16_t tx_mailbox_offset;
|
||||
uint16_t tx_mailbox_size;
|
||||
uint16_t mailbox_protocols;
|
||||
uint8_t has_general_category;
|
||||
ec_sii_coe_details_t coe_details;
|
||||
ec_sii_general_flags_t general_flags;
|
||||
int16_t current_on_ebus;
|
||||
uint8_t state;
|
||||
uint8_t error_flag;
|
||||
uint8_t sync_count;
|
||||
|
|
|
|||
|
|
@ -54,69 +54,6 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave state mask.
|
||||
*
|
||||
* Apply this mask to a slave state byte to get the slave state without
|
||||
* the error flag.
|
||||
*/
|
||||
#define EC_SLAVE_STATE_MASK 0x0F
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** State of an EtherCAT slave.
|
||||
*/
|
||||
typedef enum {
|
||||
EC_SLAVE_STATE_UNKNOWN = 0x00,
|
||||
/**< unknown state */
|
||||
EC_SLAVE_STATE_INIT = 0x01,
|
||||
/**< INIT state (no mailbox communication, no IO) */
|
||||
EC_SLAVE_STATE_PREOP = 0x02,
|
||||
/**< PREOP state (mailbox communication, no IO) */
|
||||
EC_SLAVE_STATE_SAFEOP = 0x04,
|
||||
/**< SAFEOP (mailbox communication and input update) */
|
||||
EC_SLAVE_STATE_OP = 0x08,
|
||||
/**< OP (mailbox communication and input/output update) */
|
||||
EC_SLAVE_STATE_ACK_ERR = 0x10
|
||||
/**< Acknowledge/Error bit (no actual state) */
|
||||
} ec_slave_state_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Supported mailbox protocols.
|
||||
*/
|
||||
enum {
|
||||
EC_MBOX_AOE = 0x01, /**< ADS-over-EtherCAT */
|
||||
EC_MBOX_EOE = 0x02, /**< Ethernet-over-EtherCAT */
|
||||
EC_MBOX_COE = 0x04, /**< CANopen-over-EtherCAT */
|
||||
EC_MBOX_FOE = 0x08, /**< File-Access-over-EtherCAT */
|
||||
EC_MBOX_SOE = 0x10, /**< Servo-Profile-over-EtherCAT */
|
||||
EC_MBOX_VOE = 0x20 /**< Vendor specific */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave information interface CANopen-over-EtherCAT details flags.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t enable_sdo : 1; /**< Enable Sdo access. */
|
||||
uint8_t enable_sdo_info : 1; /**< SDO information service available. */
|
||||
uint8_t enable_pdo_assign : 1; /**< Pdo mapping configurable. */
|
||||
uint8_t enable_pdo_configuration : 1; /**< Pdo configuration possible. */
|
||||
uint8_t enable_upload_at_startup : 1; /**< ?. */
|
||||
uint8_t enable_sdo_complete_access : 1; /**< Complete access possible. */
|
||||
} ec_sii_coe_details_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave information interface general flags.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t enable_safeop : 1; /**< ?. */
|
||||
uint8_t enable_not_lrw : 1; /**< Slave does not support LRW. */
|
||||
} ec_sii_general_flags_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave information interface data.
|
||||
*/
|
||||
typedef struct {
|
||||
|
|
|
|||
114
tools/Master.cpp
114
tools/Master.cpp
|
|
@ -713,6 +713,23 @@ void Master::sdoUpload(
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::showSlaves(int slavePosition)
|
||||
{
|
||||
open(Read);
|
||||
|
||||
if (slavePosition == -1) {
|
||||
unsigned int numSlaves = slaveCount(), i;
|
||||
|
||||
for (i = 0; i < numSlaves; i++) {
|
||||
showSlave(i);
|
||||
}
|
||||
} else {
|
||||
showSlave(slavePosition);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::siiRead(int slavePosition)
|
||||
{
|
||||
ec_ioctl_sii_t data;
|
||||
|
|
@ -1199,6 +1216,103 @@ void Master::listSlaveSdos(
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::showSlave(uint16_t slavePosition)
|
||||
{
|
||||
ec_ioctl_slave_t slave;
|
||||
list<string> protoList;
|
||||
list<string>::const_iterator protoIter;
|
||||
|
||||
getSlave(&slave, slavePosition);
|
||||
|
||||
cout << "Slave " << dec << slavePosition << endl
|
||||
<< "Alias: 0x" << hex << setfill('0') << setw(4) << slave.alias << endl
|
||||
<< "State: " << slaveState(slave.state) << endl
|
||||
<< "Flag: " << (slave.error_flag ? 'E' : '+') << endl
|
||||
<< "Identity:" << endl
|
||||
<< " Vendor Id: 0x"
|
||||
<< hex << setfill('0') << setw(8) << slave.vendor_id << endl
|
||||
<< " Product code: 0x"
|
||||
<< setw(8) << slave.product_code << endl
|
||||
<< " Revision number: 0x"
|
||||
<< setw(8) << slave.revision_number << endl
|
||||
<< " Serial number: 0x"
|
||||
<< setw(8) << slave.serial_number << endl;
|
||||
|
||||
if (slave.mailbox_protocols) {
|
||||
cout << "Mailboxes:" << endl
|
||||
<< " RX: 0x"
|
||||
<< hex << setw(4) << slave.rx_mailbox_offset << "/"
|
||||
<< dec << slave.rx_mailbox_size
|
||||
<< ", TX: 0x"
|
||||
<< hex << setw(4) << slave.tx_mailbox_offset << "/"
|
||||
<< dec << slave.tx_mailbox_size << endl
|
||||
<< " Supported protocols: ";
|
||||
|
||||
if (slave.mailbox_protocols & EC_MBOX_AOE) {
|
||||
protoList.push_back("AoE");
|
||||
}
|
||||
if (slave.mailbox_protocols & EC_MBOX_EOE) {
|
||||
protoList.push_back("EoE");
|
||||
}
|
||||
if (slave.mailbox_protocols & EC_MBOX_COE) {
|
||||
protoList.push_back("CoE");
|
||||
}
|
||||
if (slave.mailbox_protocols & EC_MBOX_FOE) {
|
||||
protoList.push_back("FoE");
|
||||
}
|
||||
if (slave.mailbox_protocols & EC_MBOX_SOE) {
|
||||
protoList.push_back("SoE");
|
||||
}
|
||||
if (slave.mailbox_protocols & EC_MBOX_VOE) {
|
||||
protoList.push_back("VoE");
|
||||
}
|
||||
|
||||
for (protoIter = protoList.begin(); protoIter != protoList.end();
|
||||
protoIter++) {
|
||||
if (protoIter != protoList.begin())
|
||||
cout << ", ";
|
||||
cout << *protoIter;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
if (slave.has_general_category) {
|
||||
cout << "General:" << endl
|
||||
<< " Name: " << slave.name << endl;
|
||||
|
||||
if (slave.mailbox_protocols & EC_MBOX_COE) {
|
||||
cout << " CoE details:" << endl
|
||||
<< " Enable Sdo: "
|
||||
<< (slave.coe_details.enable_sdo ? "yes" : "no") << endl
|
||||
<< " Enable Sdo Info: "
|
||||
<< (slave.coe_details.enable_sdo_info ? "yes" : "no") << endl
|
||||
<< " Enable Pdo Assign: "
|
||||
<< (slave.coe_details.enable_pdo_assign
|
||||
? "yes" : "no") << endl
|
||||
<< " Enable Pdo Configuration: "
|
||||
<< (slave.coe_details.enable_pdo_configuration
|
||||
? "yes" : "no") << endl
|
||||
<< " Enable Upload at startup: "
|
||||
<< (slave.coe_details.enable_upload_at_startup
|
||||
? "yes" : "no") << endl
|
||||
<< " Enable Sdo complete access: "
|
||||
<< (slave.coe_details.enable_sdo_complete_access
|
||||
? "yes" : "no") << endl;
|
||||
}
|
||||
|
||||
cout << " Flags:" << endl
|
||||
<< " Enable SafeOp: "
|
||||
<< (slave.general_flags.enable_safeop ? "yes" : "no") << endl
|
||||
<< " Enable notLRW: "
|
||||
<< (slave.general_flags.enable_not_lrw ? "yes" : "no") << endl
|
||||
<< " Current consumption: "
|
||||
<< dec << slave.current_on_ebus << " mA" << endl << sizeof(slave);
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::generateSlaveXml(uint16_t slavePosition)
|
||||
{
|
||||
ec_ioctl_slave_t slave;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ class Master
|
|||
void listSdos(int, bool = false);
|
||||
void sdoDownload(int, const string &, const vector<string> &);
|
||||
void sdoUpload(int, const string &, const vector<string> &);
|
||||
void showSlaves(int);
|
||||
void siiRead(int);
|
||||
void siiWrite(int, bool, const vector<string> &);
|
||||
void requestStates(int, const vector<string> &);
|
||||
|
|
@ -66,6 +67,7 @@ class Master
|
|||
void showDomain(unsigned int);
|
||||
void listSlavePdos(uint16_t, bool = false, bool = false);
|
||||
void listSlaveSdos(uint16_t, bool = false, bool = false);
|
||||
void showSlave(uint16_t);
|
||||
void generateSlaveXml(uint16_t);
|
||||
unsigned int domainCount();
|
||||
unsigned int slaveCount();
|
||||
|
|
|
|||
|
|
@ -37,12 +37,13 @@ void printUsage()
|
|||
<< " data Output binary domain process data." << endl
|
||||
<< " debug Set the master debug level." << endl
|
||||
<< " domain Show domain information." << endl
|
||||
<< " list (ls, slaves) List all slaves (former 'lsec')." << endl
|
||||
<< " list (ls) List all slaves (former 'lsec')." << endl
|
||||
<< " master Show master information." << endl
|
||||
<< " pdos List Pdo mapping." << endl
|
||||
<< " sdos List Sdo dictionaries." << endl
|
||||
<< " sdo_download (sd) Write an Sdo entry." << endl
|
||||
<< " sdo_upload (su) Read an Sdo entry." << endl
|
||||
<< " slave Show slave information." << endl
|
||||
<< " sii_read (sr) Output a slave's SII contents." << endl
|
||||
<< " sii_write (sw) Write slave's SII contents." << endl
|
||||
<< " state Request slave states." << endl
|
||||
|
|
@ -183,7 +184,7 @@ int main(int argc, char **argv)
|
|||
master.setDebug(commandArgs);
|
||||
} else if (command == "domain") {
|
||||
master.showDomains(domainIndex);
|
||||
} else if (command == "list" || command == "ls" || command == "slaves") {
|
||||
} else if (command == "list" || command == "ls") {
|
||||
master.listSlaves();
|
||||
} else if (command == "master") {
|
||||
master.showMaster();
|
||||
|
|
@ -195,6 +196,8 @@ int main(int argc, char **argv)
|
|||
master.sdoDownload(slavePosition, dataTypeStr, commandArgs);
|
||||
} else if (command == "sdo_upload" || command == "su") {
|
||||
master.sdoUpload(slavePosition, dataTypeStr, commandArgs);
|
||||
} else if (command == "slave") {
|
||||
master.showSlaves(slavePosition);
|
||||
} else if (command == "sii_read" || command == "sr") {
|
||||
master.siiRead(slavePosition);
|
||||
} else if (command == "sii_write" || command == "sw") {
|
||||
|
|
|
|||
Loading…
Reference in New Issue