Added ecrt_sdo_request_index() method to change index and subindex. stable-1.5
authorFlorian Pose <fp@igh-essen.com>
Thu, 04 Oct 2012 10:07:52 +0200
branchstable-1.5
changeset 2434 fa52128477f6
parent 2433 3bdd7a747fae
child 2435 4151f6f4c3e1
Added ecrt_sdo_request_index() method to change index and subindex.
include/ecrt.h
lib/sdo_request.c
master/fsm_pdo.c
master/fsm_pdo_entry.c
master/ioctl.c
master/ioctl.h
master/master.c
master/sdo_request.c
master/sdo_request.h
master/slave_config.c
--- a/include/ecrt.h	Thu Sep 20 15:28:25 2012 +0200
+++ b/include/ecrt.h	Thu Oct 04 10:07:52 2012 +0200
@@ -46,6 +46,8 @@
  *   the state of a redundant link.
  * - Added the EC_HAVE_REDUNDANCY define, to check, if the interface contains
  *   redundancy features.
+ * - Added ecrt_sdo_request_index() to change SDO index and subindex after
+ *   handler creation.
  *
  * Changes in version 1.5:
  *
@@ -1447,6 +1449,18 @@
  * SDO request methods.
  ****************************************************************************/
 
+/** Set the SDO index and subindex.
+ *
+ * \attention If the SDO index and/or subindex is changed while
+ * ecrt_sdo_request_state() returns EC_SDO_REQUEST_BUSY, this may lead to
+ * unexpected results.
+ */
+void ecrt_sdo_request_index(
+        ec_sdo_request_t *req, /**< SDO request. */
+        uint16_t index, /**< SDO index. */
+        uint8_t subindex /**< SDO subindex. */
+        );
+
 /** Set the timeout for an SDO request.
  *
  * If the request cannot be processed in the specified time, if will be marked
--- a/lib/sdo_request.c	Thu Sep 20 15:28:25 2012 +0200
+++ b/lib/sdo_request.c	Thu Oct 04 10:07:52 2012 +0200
@@ -55,6 +55,26 @@
  * Application interface.
  ****************************************************************************/
 
+void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index,
+        uint8_t subindex)
+{
+    ec_ioctl_sdo_request_t data;
+    int ret;
+
+    data.config_index = req->config->index;
+    data.request_index = req->index;
+    data.sdo_index = index;
+    data.sdo_subindex = subindex;
+
+    ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_INDEX, &data);
+    if (EC_IOCTL_IS_ERROR(ret)) {
+        fprintf(stderr, "Failed to set SDO request index/subindex: %s\n",
+                strerror(EC_IOCTL_ERRNO(ret)));
+    }
+}
+
+/*****************************************************************************/
+
 void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
 {
     ec_ioctl_sdo_request_t data;
--- a/master/fsm_pdo.c	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/fsm_pdo.c	Thu Oct 04 10:07:52 2012 +0200
@@ -218,7 +218,7 @@
 
         ec_pdo_list_clear_pdos(&fsm->pdos);
 
-        ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync_index, 0);
+        ecrt_sdo_request_index(&fsm->request, 0x1C10 + fsm->sync_index, 0);
         ecrt_sdo_request_read(&fsm->request);
         fsm->state = ec_fsm_pdo_read_state_pdo_count;
         ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
@@ -274,7 +274,7 @@
         )
 {
     if (fsm->pdo_pos <= fsm->pdo_count) {
-        ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync_index,
+        ecrt_sdo_request_index(&fsm->request, 0x1C10 + fsm->sync_index,
                 fsm->pdo_pos);
         ecrt_sdo_request_read(&fsm->request);
         fsm->state = ec_fsm_pdo_read_state_pdo;
@@ -597,7 +597,7 @@
         // set mapped PDO count to zero
         EC_WRITE_U8(fsm->request.data, 0); // zero PDOs mapped
         fsm->request.data_size = 1;
-        ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync_index, 0);
+        ecrt_sdo_request_index(&fsm->request, 0x1C10 + fsm->sync_index, 0);
         ecrt_sdo_request_write(&fsm->request);
 
         EC_SLAVE_DBG(fsm->slave, 1, "Setting number of assigned"
@@ -663,7 +663,7 @@
 {
     EC_WRITE_U16(fsm->request.data, fsm->pdo->index);
     fsm->request.data_size = 2;
-    ec_sdo_request_address(&fsm->request,
+    ecrt_sdo_request_index(&fsm->request,
             0x1C10 + fsm->sync_index, fsm->pdo_pos);
     ecrt_sdo_request_write(&fsm->request);
 
@@ -700,7 +700,7 @@
         // no more PDOs to assign, set PDO count
         EC_WRITE_U8(fsm->request.data, fsm->pdo_pos);
         fsm->request.data_size = 1;
-        ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync_index, 0);
+        ecrt_sdo_request_index(&fsm->request, 0x1C10 + fsm->sync_index, 0);
         ecrt_sdo_request_write(&fsm->request);
 
         EC_SLAVE_DBG(fsm->slave, 1,
--- a/master/fsm_pdo_entry.c	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/fsm_pdo_entry.c	Thu Oct 04 10:07:52 2012 +0200
@@ -190,7 +190,7 @@
         ec_fsm_pdo_entry_t *fsm /**< PDO mapping state machine. */
         )
 {
-    ec_sdo_request_address(&fsm->request, fsm->target_pdo->index, 0);
+    ecrt_sdo_request_index(&fsm->request, fsm->target_pdo->index, 0);
     ecrt_sdo_request_read(&fsm->request);
 
     fsm->state = ec_fsm_pdo_entry_read_state_count;
@@ -243,7 +243,8 @@
         )
 {
     if (fsm->entry_pos <= fsm->entry_count) {
-        ec_sdo_request_address(&fsm->request, fsm->target_pdo->index, fsm->entry_pos);
+        ecrt_sdo_request_index(&fsm->request, fsm->target_pdo->index,
+                fsm->entry_pos);
         ecrt_sdo_request_read(&fsm->request);
         fsm->state = ec_fsm_pdo_entry_read_state_entry;
         ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
@@ -336,7 +337,7 @@
     // set mapped PDO entry count to zero
     EC_WRITE_U8(fsm->request.data, 0);
     fsm->request.data_size = 1;
-    ec_sdo_request_address(&fsm->request, fsm->source_pdo->index, 0);
+    ecrt_sdo_request_index(&fsm->request, fsm->source_pdo->index, 0);
     ecrt_sdo_request_write(&fsm->request);
 
     EC_SLAVE_DBG(fsm->slave, 1, "Setting entry count to zero.\n");
@@ -413,7 +414,8 @@
         | fsm->entry->subindex << 8 | fsm->entry->bit_length;
     EC_WRITE_U32(fsm->request.data, value);
     fsm->request.data_size = 4;
-    ec_sdo_request_address(&fsm->request, fsm->source_pdo->index, fsm->entry_pos);
+    ecrt_sdo_request_index(&fsm->request, fsm->source_pdo->index,
+            fsm->entry_pos);
     ecrt_sdo_request_write(&fsm->request);
 
     fsm->state = ec_fsm_pdo_entry_conf_state_map_entry;
@@ -448,7 +450,7 @@
         // No more entries to add. Write entry count.
         EC_WRITE_U8(fsm->request.data, fsm->entry_pos);
         fsm->request.data_size = 1;
-        ec_sdo_request_address(&fsm->request, fsm->source_pdo->index, 0);
+        ecrt_sdo_request_index(&fsm->request, fsm->source_pdo->index, 0);
         ecrt_sdo_request_write(&fsm->request);
 
         EC_SLAVE_DBG(fsm->slave, 1, "Setting number of PDO entries to %u.\n",
--- a/master/ioctl.c	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/ioctl.c	Thu Oct 04 10:07:52 2012 +0200
@@ -2580,6 +2580,41 @@
 
 /*****************************************************************************/
 
+/** Sets an SDO request's SDO index and subindex.
+ */
+static int ec_ioctl_sdo_request_index(
+        ec_master_t *master, /**< EtherCAT master. */
+        void *arg, /**< ioctl() argument. */
+        ec_ioctl_context_t *ctx /**< Private data structure of file handle. */
+        )
+{
+    ec_ioctl_sdo_request_t data;
+    ec_slave_config_t *sc;
+    ec_sdo_request_t *req;
+
+    if (unlikely(!ctx->requested))
+        return -EPERM;
+
+    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+        return -EFAULT;
+
+    /* no locking of master_sem needed, because neither sc nor req will not be
+     * deleted in the meantime. */
+
+    if (!(sc = ec_master_get_config(master, data.config_index))) {
+        return -ENOENT;
+    }
+
+    if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
+        return -ENOENT;
+    }
+
+    ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
+    return 0;
+}
+
+/*****************************************************************************/
+
 /** Sets an SDO request's timeout.
  */
 static int ec_ioctl_sdo_request_timeout(
@@ -3686,6 +3721,13 @@
         case EC_IOCTL_DOMAIN_STATE:
             ret = ec_ioctl_domain_state(master, arg, ctx);
             break;
+        case EC_IOCTL_SDO_REQUEST_INDEX:
+            if (!ctx->writable) {
+                ret = -EPERM;
+                break;
+            }
+            ret = ec_ioctl_sdo_request_index(master, arg, ctx);
+            break;
         case EC_IOCTL_SDO_REQUEST_TIMEOUT:
             if (!ctx->writable) {
                 ret = -EPERM;
--- a/master/ioctl.h	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/ioctl.h	Thu Oct 04 10:07:52 2012 +0200
@@ -56,7 +56,7 @@
  *
  * Increment this when changing the ioctl interface!
  */
-#define EC_IOCTL_VERSION_MAGIC 18
+#define EC_IOCTL_VERSION_MAGIC 19
 
 // Command-line tool
 #define EC_IOCTL_MODULE                EC_IOR(0x00, ec_ioctl_module_t)
@@ -111,7 +111,7 @@
 #define EC_IOCTL_SC_SYNC               EC_IOW(0x2d, ec_ioctl_config_t)
 #define EC_IOCTL_SC_WATCHDOG           EC_IOW(0x2e, ec_ioctl_config_t)
 #define EC_IOCTL_SC_ADD_PDO            EC_IOW(0x2f, ec_ioctl_config_pdo_t)
-#define EC_IOCTL_SC_CLEAR_PDOS         EC_IOW(0x20, ec_ioctl_config_pdo_t)
+#define EC_IOCTL_SC_CLEAR_PDOS         EC_IOW(0x30, ec_ioctl_config_pdo_t)
 #define EC_IOCTL_SC_ADD_ENTRY          EC_IOW(0x31, ec_ioctl_add_pdo_entry_t)
 #define EC_IOCTL_SC_CLEAR_ENTRIES      EC_IOW(0x32, ec_ioctl_config_pdo_t)
 #define EC_IOCTL_SC_REG_PDO_ENTRY     EC_IOWR(0x33, ec_ioctl_reg_pdo_entry_t)
@@ -125,19 +125,20 @@
 #define EC_IOCTL_DOMAIN_PROCESS         EC_IO(0x3b)
 #define EC_IOCTL_DOMAIN_QUEUE           EC_IO(0x3c)
 #define EC_IOCTL_DOMAIN_STATE         EC_IOWR(0x3d, ec_ioctl_domain_state_t)
-#define EC_IOCTL_SDO_REQUEST_TIMEOUT  EC_IOWR(0x3e, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_STATE    EC_IOWR(0x3f, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_READ     EC_IOWR(0x30, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_WRITE    EC_IOWR(0x41, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_DATA     EC_IOWR(0x42, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_VOE_SEND_HEADER       EC_IOW(0x43, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_REC_HEADER       EC_IOWR(0x44, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_READ              EC_IOW(0x45, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_READ_NOSYNC       EC_IOW(0x46, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_WRITE            EC_IOWR(0x47, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_EXEC             EC_IOWR(0x48, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_DATA             EC_IOWR(0x49, ec_ioctl_voe_t)
-#define EC_IOCTL_SET_SEND_INTERVAL     EC_IOW(0x4a, size_t)
+#define EC_IOCTL_SDO_REQUEST_INDEX    EC_IOWR(0x3e, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_TIMEOUT  EC_IOWR(0x3f, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_STATE    EC_IOWR(0x40, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_READ     EC_IOWR(0x41, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_WRITE    EC_IOWR(0x42, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_DATA     EC_IOWR(0x43, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_VOE_SEND_HEADER       EC_IOW(0x44, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_REC_HEADER       EC_IOWR(0x45, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_READ              EC_IOW(0x46, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_READ_NOSYNC       EC_IOW(0x47, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_WRITE            EC_IOWR(0x48, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_EXEC             EC_IOWR(0x49, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_DATA             EC_IOWR(0x4a, ec_ioctl_voe_t)
+#define EC_IOCTL_SET_SEND_INTERVAL     EC_IOW(0x4b, size_t)
 
 /*****************************************************************************/
 
--- a/master/master.c	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/master.c	Thu Oct 04 10:07:52 2012 +0200
@@ -2608,7 +2608,7 @@
     }
 
     ec_sdo_request_init(&request.req);
-    ec_sdo_request_address(&request.req, index, subindex);
+    ecrt_sdo_request_index(&request.req, index, subindex);
     if (ec_sdo_request_alloc(&request.req, data_size)) {
         ec_sdo_request_clear(&request.req);
         return -ENOMEM;
@@ -2687,7 +2687,7 @@
     }
 
     ec_sdo_request_init(&request.req);
-    ec_sdo_request_address(&request.req, index, 0);
+    ecrt_sdo_request_index(&request.req, index, 0);
     if (ec_sdo_request_alloc(&request.req, data_size)) {
         ec_sdo_request_clear(&request.req);
         return -ENOMEM;
@@ -2766,7 +2766,7 @@
             target, target_size, result_size, abort_code);
 
     ec_sdo_request_init(&request.req);
-    ec_sdo_request_address(&request.req, index, subindex);
+    ecrt_sdo_request_index(&request.req, index, subindex);
     ecrt_sdo_request_read(&request.req);
 
     if (down_interruptible(&master->master_sem)) {
--- a/master/sdo_request.c	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/sdo_request.c	Thu Oct 04 10:07:52 2012 +0200
@@ -116,20 +116,6 @@
 
 /*****************************************************************************/
 
-/** Set the SDO address.
- */
-void ec_sdo_request_address(
-        ec_sdo_request_t *req, /**< SDO request. */
-        uint16_t index, /**< SDO index. */
-        uint8_t subindex /**< SDO subindex. */
-        )
-{
-    req->index = index;
-    req->subindex = subindex;
-}
-
-/*****************************************************************************/
-
 /** Pre-allocates the data memory.
  *
  * If the \a mem_size is already bigger than \a size, nothing is done.
@@ -196,6 +182,15 @@
  * Application interface.
  ****************************************************************************/
 
+void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index,
+        uint8_t subindex)
+{
+    req->index = index;
+    req->subindex = subindex;
+}
+
+/*****************************************************************************/
+
 void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
 {
     req->issue_timeout = timeout;
@@ -248,6 +243,7 @@
 
 /** \cond */
 
+EXPORT_SYMBOL(ecrt_sdo_request_index);
 EXPORT_SYMBOL(ecrt_sdo_request_timeout);
 EXPORT_SYMBOL(ecrt_sdo_request_data);
 EXPORT_SYMBOL(ecrt_sdo_request_data_size);
--- a/master/sdo_request.h	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/sdo_request.h	Thu Oct 04 10:07:52 2012 +0200
@@ -74,7 +74,6 @@
 void ec_sdo_request_clear(ec_sdo_request_t *);
 
 int ec_sdo_request_copy(ec_sdo_request_t *, const ec_sdo_request_t *);
-void ec_sdo_request_address(ec_sdo_request_t *, uint16_t, uint8_t);
 int ec_sdo_request_alloc(ec_sdo_request_t *, size_t);
 int ec_sdo_request_copy_data(ec_sdo_request_t *, const uint8_t *, size_t);
 int ec_sdo_request_timed_out(const ec_sdo_request_t *);
--- a/master/slave_config.c	Thu Sep 20 15:28:25 2012 +0200
+++ b/master/slave_config.c	Thu Oct 04 10:07:52 2012 +0200
@@ -779,7 +779,7 @@
     }
 
     ec_sdo_request_init(req);
-    ec_sdo_request_address(req, index, subindex);
+    ecrt_sdo_request_index(req, index, subindex);
 
     ret = ec_sdo_request_copy_data(req, data, size);
     if (ret < 0) {
@@ -863,7 +863,7 @@
     }
 
     ec_sdo_request_init(req);
-    ec_sdo_request_address(req, index, 0);
+    ecrt_sdo_request_index(req, index, 0);
     req->complete_access = 1;
 
     ret = ec_sdo_request_copy_data(req, data, size);
@@ -901,7 +901,7 @@
     }
 
     ec_sdo_request_init(req);
-    ec_sdo_request_address(req, index, subindex);
+    ecrt_sdo_request_index(req, index, subindex);
 
     ret = ec_sdo_request_alloc(req, size);
     if (ret < 0) {