Implemented Sdo timeout.
--- 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 *);
/*****************************************************************************/