Implemented Sdo timeout.
authorFlorian Pose <fp@igh-essen.com>
Thu, 03 Apr 2008 14:08:08 +0000
changeset 880 f6212c54a5e3
parent 879 9b395c5646ab
child 881 c5ac0ab2d6cf
Implemented Sdo timeout.
examples/mini/mini.c
include/ecrt.h
master/fsm_master.c
master/sdo_request.c
master/sdo_request.h
--- a/examples/mini/mini.c	Thu Apr 03 13:34:13 2008 +0000
+++ b/examples/mini/mini.c	Thu Apr 03 14:08:08 2008 +0000
@@ -170,6 +170,7 @@
 {
     switch (ecrt_sdo_request_state(sdo)) {
         case EC_SDO_REQUEST_UNUSED: // request was not used yet
+            ecrt_sdo_request_timeout(sdo, 500); // ms
             ecrt_sdo_request_read(sdo); // trigger first read
             break;
         case EC_SDO_REQUEST_BUSY:
--- a/include/ecrt.h	Thu Apr 03 13:34:13 2008 +0000
+++ b/include/ecrt.h	Thu Apr 03 14:08:08 2008 +0000
@@ -683,12 +683,11 @@
  *
  * If the request cannot be processed in the specified time, if will be marked
  * as failed.
- *
- * \todo The timeout functionality is not yet implemented.
  */
 void ecrt_sdo_request_timeout(
         ec_sdo_request_t *req, /**< Sdo request. */
-        uint32_t timeout /**< Timeout in milliseconds. */
+        uint32_t timeout /**< Timeout in milliseconds. Zero means no
+                           timeout. */
         );
 
 /** Access to the Sdo request's data.
--- a/master/fsm_master.c	Thu Apr 03 13:34:13 2008 +0000
+++ b/master/fsm_master.c	Thu Apr 03 14:08:08 2008 +0000
@@ -386,7 +386,14 @@
             continue;
         list_for_each_entry(req, &slave->config->sdo_requests, list) {
             if (req->state == EC_REQUEST_QUEUED) {
-                req->state = EC_REQUEST_BUSY;
+
+                if (ec_sdo_request_timed_out(req)) {
+                    req->state = EC_REQUEST_FAILURE;
+                    if (master->debug_level)
+                        EC_DBG("Sdo request for slave %u timed out...\n",
+                                slave->ring_position);
+                    continue;
+                }
 
                 if (slave->current_state == EC_SLAVE_STATE_INIT ||
                         slave->error_flag) {
@@ -394,6 +401,7 @@
                     continue;
                 }
 
+                req->state = EC_REQUEST_BUSY;
                 if (master->debug_level)
                     EC_DBG("Processing Sdo request for slave %u...\n",
                             slave->ring_position);
--- a/master/sdo_request.c	Thu Apr 03 13:34:13 2008 +0000
+++ b/master/sdo_request.c	Thu Apr 03 14:08:08 2008 +0000
@@ -69,6 +69,7 @@
     req->mem_size = 0;
     req->data_size = 0;
     req->dir = EC_DIR_OUTPUT;
+    req->timeout = 0; // no timeout
     req->state = EC_REQUEST_INIT;
 }
 
@@ -160,12 +161,25 @@
     return 0;
 }
 
+/*****************************************************************************/
+
+/** Checks, if the timeout was exceeded.
+ *
+ * \return non-zero if the timeout was exceeded, else zero.
+ */
+int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< Sdo request. */)
+{
+    return req->timeout
+        && jiffies - req->start_jiffies > HZ * req->timeout / 1000;
+}
+
 /*****************************************************************************
  * Realtime interface.
  ****************************************************************************/
 
 void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
 {
+    req->timeout = timeout;
 }
 
 /*****************************************************************************/
@@ -195,6 +209,7 @@
 {
     req->dir = EC_DIR_INPUT;
     req->state = EC_REQUEST_QUEUED;
+    req->start_jiffies = jiffies;
 }
 
 /*****************************************************************************/
@@ -203,6 +218,7 @@
 {
     req->dir = EC_DIR_OUTPUT;
     req->state = EC_REQUEST_QUEUED;
+    req->start_jiffies = jiffies;
 }
 
 /*****************************************************************************/
--- a/master/sdo_request.h	Thu Apr 03 13:34:13 2008 +0000
+++ b/master/sdo_request.h	Thu Apr 03 14:08:08 2008 +0000
@@ -58,10 +58,12 @@
     uint8_t *data; /**< Pointer to Sdo data. */
     size_t mem_size; /**< Size of Sdo data memory. */
     size_t data_size; /**< Size of Sdo data. */
+    uint32_t timeout; /**< Timeout in ms. */
     ec_direction_t dir; /**< Direction. EC_DIR_OUTPUT means downloading to
                           the slave, EC_DIR_INPUT means uploading from the
                           slave. */
     ec_request_state_t state; /**< Sdo request state. */
+    unsigned long start_jiffies; /**< Jiffies, when the request was issued. */
 };
 
 /*****************************************************************************/
@@ -72,6 +74,7 @@
 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 *);
 
 /*****************************************************************************/