Slave information via 'ethercat slave'.

This commit is contained in:
Florian Pose 2008-06-11 13:01:21 +00:00
parent 322845b160
commit bc3c6f320a
8 changed files with 195 additions and 67 deletions

1
TODO
View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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();

View File

@ -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") {