From da1c5588de40ec7482fd9129c114519539894da0 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 8 Apr 2009 08:13:33 +0000 Subject: [PATCH] Read SDO entry access rights. --- NEWS | 1 + master/cdev.c | 12 ++++++++++++ master/fsm_coe.c | 12 +++++++++++- master/globals.h | 11 +++++++++++ master/ioctl.h | 2 ++ master/sdo_entry.c | 6 ++++++ master/sdo_entry.h | 2 ++ tool/CommandSdos.cpp | 20 +++++++++++++++++--- 8 files changed, 62 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 8836b0fa..c432c6f3 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,7 @@ Changes since 1.4.0: * Going to the Bootstrap state is now supported by the state machines and the command-line tool. * Introduced ecrt_master_slave() to get information about a certain slave. +* SDO entry access rights are shown in 'ethercat sdos'. Changes in 1.4.0: diff --git a/master/cdev.c b/master/cdev.c index c6aeb50c..679269e2 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -720,6 +720,18 @@ int ec_cdev_ioctl_slave_sdo_entry( data.data_type = entry->data_type; data.bit_length = entry->bit_length; + data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] = + entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP]; + data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = + entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP]; + data.read_access[EC_SDO_ENTRY_ACCESS_OP] = + entry->read_access[EC_SDO_ENTRY_ACCESS_OP]; + data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] = + entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP]; + data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = + entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP]; + data.write_access[EC_SDO_ENTRY_ACCESS_OP] = + entry->write_access[EC_SDO_ENTRY_ACCESS_OP]; ec_cdev_strcpy(data.description, entry->description); up(&master->master_sem); diff --git a/master/fsm_coe.c b/master/fsm_coe.c index 1a559359..d72d0d6c 100644 --- a/master/fsm_coe.c +++ b/master/fsm_coe.c @@ -773,7 +773,7 @@ void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *fsm EC_WRITE_U16(data + 4, 0x0000); EC_WRITE_U16(data + 6, sdo->index); // SDO index EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex - EC_WRITE_U8 (data + 9, 0x00); // value info (no values) + EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only) fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_entry_request; @@ -886,6 +886,7 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm uint8_t *data, mbox_prot; size_t rec_size, data_size; ec_sdo_entry_t *entry; + u16 word; if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) return; // FIXME: request again? @@ -987,6 +988,15 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm entry->data_type = EC_READ_U16(data + 10); entry->bit_length = EC_READ_U16(data + 12); + // read access rights + word = EC_READ_U16(data + 14); + entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001; + entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 1) & 0x0001; + entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001; + entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001; + entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 4) & 0x0001; + entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001; + if (data_size) { uint8_t *desc; if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) { diff --git a/master/globals.h b/master/globals.h index 0afe2cfe..3444f150 100644 --- a/master/globals.h +++ b/master/globals.h @@ -174,6 +174,17 @@ typedef enum { port 0 receive time. */ } ec_slave_dc_range_t; +/** Access states for SDO entries. + * + * The access rights are managed per AL state. + */ +enum { + EC_SDO_ENTRY_ACCESS_PREOP, /**< Access rights in PREOP. */ + EC_SDO_ENTRY_ACCESS_SAFEOP, /**< Access rights in SAFEOP. */ + EC_SDO_ENTRY_ACCESS_OP, /**< Access rights in OP. */ + EC_SDO_ENTRY_ACCESS_COUNT /**< Number of states. */ +}; + /*****************************************************************************/ /** Convenience macro for printing EtherCAT-specific information to syslog. diff --git a/master/ioctl.h b/master/ioctl.h index c8001eb6..7877b8e2 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -288,6 +288,8 @@ typedef struct { // outputs uint16_t data_type; uint16_t bit_length; + uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]; + uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]; int8_t description[EC_IOCTL_STRING_SIZE]; } ec_ioctl_slave_sdo_entry_t; diff --git a/master/sdo_entry.c b/master/sdo_entry.c index fa383635..acb3364e 100644 --- a/master/sdo_entry.c +++ b/master/sdo_entry.c @@ -52,6 +52,12 @@ void ec_sdo_entry_init( entry->subindex = subindex; entry->data_type = 0x0000; entry->bit_length = 0; + entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = 0; + entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = 0; + entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = 0; + entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = 0; + entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = 0; + entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = 0; entry->description = NULL; } diff --git a/master/sdo_entry.h b/master/sdo_entry.h index 13f24591..b461f3e6 100644 --- a/master/sdo_entry.h +++ b/master/sdo_entry.h @@ -57,6 +57,8 @@ typedef struct { uint8_t subindex; /**< Subindex. */ uint16_t data_type; /**< Data type. */ uint16_t bit_length; /**< Data size in bit. */ + uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]; /**< Read access. */ + uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]; /**< Write access. */ char *description; /**< Description. */ } ec_sdo_entry_t; diff --git a/tool/CommandSdos.cpp b/tool/CommandSdos.cpp index f241cd9d..c1de78aa 100644 --- a/tool/CommandSdos.cpp +++ b/tool/CommandSdos.cpp @@ -58,11 +58,18 @@ string CommandSdos::helpString() const << " SDO 0x1018, \"Identity object\"" << endl << endl << "2) SDO entries - SDO index and SDO entry subindex (both" << endl - << " hexadecimal) followed by the data type, the length in" << endl - << " bit, and the description. Example:" << endl + << " hexadecimal) followed by the access rights (see" << endl + << " below), the data type, the length in bit, and the" << endl + << " description. Example:" << endl << endl - << " 0x1018:01, uint32, 32 bit, \"Vendor id\"" << endl + << " 0x1018:01, rwrwrw, uint32, 32 bit, \"Vendor id\"" << endl << endl + << "The access rights are specified for the AL states PREOP," << endl + << "SAFEOP and OP. An 'r' means, that the entry is readable" << endl + << "in the corresponding state, an 'w' means writable," << endl + << "respectively. If a right is not granted, a dash '-' is" << endl + << "shown." << endl + << endl << "If the --quiet option is given, only the SDOs are output." << endl << endl << "Command-specific options:" << endl @@ -133,6 +140,13 @@ void CommandSdos::listSlaveSdos( cout << " 0x" << hex << setfill('0') << setw(4) << sdo.sdo_index << ":" << setw(2) << (unsigned int) entry.sdo_entry_subindex + << ", " + << (entry.read_access[EC_SDO_ENTRY_ACCESS_PREOP] ? "r" : "-") + << (entry.write_access[EC_SDO_ENTRY_ACCESS_PREOP] ? "w" : "-") + << (entry.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] ? "r" : "-") + << (entry.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] ? "w" : "-") + << (entry.read_access[EC_SDO_ENTRY_ACCESS_OP] ? "r" : "-") + << (entry.write_access[EC_SDO_ENTRY_ACCESS_OP] ? "w" : "-") << ", "; if ((d = findDataType(entry.data_type))) {