Improved bus information API.
authorFlorian Pose <fp@igh-essen.com>
Tue, 28 Jul 2009 15:42:00 +0000
changeset 1510 88b608a1a7f3
parent 1509 a864688e7de5
child 1511 53bf35f7b6ea
Improved bus information API.
NEWS
include/ecrt.h
lib/master.c
--- a/NEWS	Mon Jul 27 10:48:52 2009 +0000
+++ b/NEWS	Tue Jul 28 15:42:00 2009 +0000
@@ -35,10 +35,15 @@
 * Going to the Bootstrap state is now supported by the state machines and the
   command-line tool.
 * Added ecrt_open_master() and ecrt_master_reserve() separation for
-  the userspace libary (thanks to Martin Troxler).
-* Added ecrt_master() userspace interface, to get information about a
-  master (thanks to Martin Troxler).
-* Introduced ecrt_master_slave() to get information about a certain slave.
+  the userspace library (thanks to Martin Troxler).
+* Added bus information interface (methods ecrt_master(),
+  ecrt_master_get_slave(), ecrt_master_get_sync_manager(),
+  ecrt_master_get_pdo() and ecrt_master_get_pdo_entry()) to get information
+  about the currently connected slaves and the PDO entries provided (thanks to
+  Martin Troxler and Stefan Weiser).
+* Added ecrt_master_sdo_download() and ecrt_master_sdo_upload()
+  methods to let an application transfer SDOs before activating the master
+  (thanks to Stefan Weiser).
 * Fixed SDO upload segment response (thanks to Christoph Peter).
 * SDO entry access rights are shown in 'ethercat sdos'.
 * Added 64-bit data access macros to application header.
@@ -48,9 +53,6 @@
 * Output device link state in 'ethercat master'.
 * Added 'ethercat graph' command which outputs the bus topology in
   DOT language.
-* Added ecrt_slave_sdo_upload() and ecrt_slave_sdo_download() methods to let
-  an application transfer SDOs before activating the master. Thanks to Stefan
-  Weiser.
 * Changed EC_MAX_SII_SIZE to 4096.
 * 'ethercat xml' creates valid XML <EtherCATInfoList> for more than one slave
   (thanks to E. Burgstaller).
--- a/include/ecrt.h	Mon Jul 27 10:48:52 2009 +0000
+++ b/include/ecrt.h	Tue Jul 28 15:42:00 2009 +0000
@@ -55,11 +55,12 @@
  *   ecrt_slave_config_sync_manager()).
  * - Added ecrt_open_master() and ecrt_master_reserve() separation for
  *   userspace.
- * - Added ecrt_master() userspace interface, to get information about a
- *   master.
- * - Added ecrt_master_slave() to get information about a certain slave.
- * - Added ecrt_slave_sdo_upload() and ecrt_slave_sdo_download() methods to
- *   let an application transfer SDOs before activating the master.
+ * - Added bus information interface (methods ecrt_master(),
+ *   ecrt_master_get_slave(), ecrt_master_get_sync_manager(),
+ *   ecrt_master_get_pdo() and ecrt_master_get_pdo_entry()) to get information
+ *   about the currently connected slaves and the PDO entries provided.
+ * - Added ecrt_master_sdo_download() and ecrt_master_sdo_upload()
+ *   methods to let an application transfer SDOs before activating the master.
  * - Changed the meaning of the negative return values of
  *   ecrt_slave_config_reg_pdo_entry() and ecrt_slave_config_sdo*().
  * - Imlemented the Vendor-specific over EtherCAT mailbox protocol. See
@@ -220,9 +221,9 @@
 
 /** Slave information.
  *
- * This is used as an output parameter of ecrt_master_slave().
- *
- * \see ecrt_master_slave().
+ * This is used as an output parameter of ecrt_master_get_slave().
+ *
+ * \see ecrt_master_get_slave().
  */
 typedef struct {
     uint16_t position; /**< Offset of the slave in the ring. */
@@ -557,13 +558,104 @@
  *
  * \return 0 in case of success, else < 0
  */
-int ecrt_master_slave(
+int ecrt_master_get_slave(
         ec_master_t *master, /**< EtherCAT master */
-        uint16_t position, /**< Slave position. */
+        uint16_t slave_position, /**< Slave position. */
         ec_slave_info_t *slave_info /**< Structure that will output the
                                       information */
         );
 
+/** Returns the proposed configuration of a slave's sync manager.
+ *
+ * Fills a given ec_sync_info_t structure with the attributes of a sync
+ * manager. The \a pdos field of the return value is left empty. Use
+ * ecrt_master_get_pdo() to get the PDO information.
+ *
+ * \return zero on success, else non-zero
+ */
+int ecrt_master_get_sync_manager(
+        ec_master_t *master, /**< EtherCAT master. */
+        uint16_t slave_position, /**< Slave position. */
+        uint8_t sync_index, /**< Sync manager index. Must be less
+                                than #EC_MAX_SYNC_MANAGERS. */
+        ec_sync_info_t *sync /**< Pointer to output structure. */
+        );
+
+/** Returns information about a currently assigned PDO.
+ *
+ * Fills a given ec_pdo_info_t structure with the attributes of a currently
+ * assigned PDO of the given sync manager. The \a entries field of the return
+ * value is left empty. Use ecrt_master_get_pdo_entry() to get the PDO
+ * entry information.
+ *
+ * \retval zero on success, else non-zero
+ */
+int ecrt_master_get_pdo(
+        ec_master_t *master, /**< EtherCAT master. */
+        uint16_t slave_position, /**< Slave position. */
+        uint8_t sync_index, /**< Sync manager index. Must be less
+                                 than #EC_MAX_SYNC_MANAGERS. */
+        uint16_t pos, /**< Zero-based PDO position. */
+        ec_pdo_info_t *pdo /**< Pointer to output structure. */
+        );
+
+/** Returns information about a currently mapped PDO entry.
+ *
+ * Fills a given ec_pdo_entry_info_t structure with the attributes of a
+ * currently mapped PDO entry of the given PDO.
+ *
+ * \retval zero on success, else non-zero
+ */
+int ecrt_master_get_pdo_entry(
+        ec_master_t *master, /**< EtherCAT master. */
+        uint16_t slave_position, /**< Slave position. */
+        uint8_t sync_index, /**< Sync manager index. Must be less
+                                 than #EC_MAX_SYNC_MANAGERS. */
+        uint16_t pdo_pos, /**< Zero-based PDO position. */
+        uint16_t entry_pos, /**< Zero-based PDO entry position. */
+        ec_pdo_entry_info_t *entry /**< Pointer to output structure. */
+        );
+
+/** Executes an SDO write request to download data.
+ *
+ * This function operates aside of the normal way to request SDOs. Before the
+ * activation of the master, these requests are processed by the master state
+ * machine itself. After activation the user has to ensure cyclic processing.
+ *
+ * \retval  0 Success.
+ * \retval -1 An error occured.
+ */
+int ecrt_master_sdo_download(
+        ec_master_t *master, /**< EtherCAT master. */
+        uint16_t slave_position, /**< Slave position. */
+        uint16_t index, /**< Index of the SDO. */
+        uint8_t subindex, /**< Subindex of the SDO. */
+        uint8_t *data, /**< Data buffer to download. */
+        size_t data_size, /**< Size of the data buffer. */
+        uint32_t *abort_code /**< Abort code of the SDO download. */
+        );
+
+/** Executes a SDO read request to upload data.
+ *
+ * This function operates aside of the normal way to request SDOs. Before the
+ * activation of the master, these requests are processed by the master state
+ * machine itself. After activation the user have to ensure cyclic
+ * processing.
+ *
+ * \retval  0 Success.
+ * \retval -1 Error occured.
+ */
+int ecrt_master_sdo_upload(
+        ec_master_t *master, /**< EtherCAT master. */
+        uint16_t slave_position, /**< Slave position. */
+        uint16_t index, /**< Index of the SDO. */
+        uint8_t subindex, /**< Subindex of the SDO. */
+        uint8_t *target, /**< Target buffer for the upload. */
+        size_t target_size, /**< Size of the target buffer. */
+        size_t *result_size, /**< Uploaded data size. */
+        uint32_t *abort_code /**< Abort code of the SDO upload. */
+        );
+
 #endif /* #ifndef __KERNEL__ */
 
 /** Finishes the configuration phase and prepares for cyclic operation.
@@ -666,50 +758,6 @@
         ec_master_t *master /**< EtherCAT master. */
         );
 
-#ifndef __KERNEL__
-
-/** Executes an SDO write request to download data.
- *
- * This function operates aside of the normal way to request SDOs. Before the
- * activation of the master, these requests are processed by the master state
- * machine itself. After activation the user has to ensure cyclic processing.
- *
- * \retval  0 Success.
- * \retval -1 An error occured.
- */
-int ecrt_slave_sdo_download(
-        ec_master_t* master, /**< EtherCAT master. */
-        uint16_t slave_position, /**< Slave position. */
-        uint16_t index, /**< Index of the SDO. */
-        uint8_t subindex, /**< Subindex of the SDO. */
-        uint8_t *data, /**< Data buffer to download. */
-        size_t data_size, /**< Size of the data buffer. */
-        uint32_t *abort_code /**< Abort code of the SDO download. */
-        );
-
-/** Executes a SDO read request to upload data.
- *
- * This function operates aside of the normal way to request SDOs. Before the
- * activation of the master, these requests are processed by the master state
- * machine itself. After activation the user have to ensure cyclic
- * processing.
- *
- * \retval  0 Success.
- * \retval -1 Error occured.
- */
-int ecrt_slave_sdo_upload(
-        ec_master_t* master, /**< EtherCAT master. */
-        uint16_t slave_position, /**< Slave position. */
-        uint16_t index, /**< Index of the SDO. */
-        uint8_t subindex, /**< Subindex of the SDO. */
-        uint8_t *target, /**< Target buffer for the upload. */
-        size_t target_size, /**< Size of the target buffer. */
-        size_t *result_size, /**< Uploaded data size. */
-        uint32_t *abort_code /**< Abort code of the SDO upload. */
-        );
-
-#endif /* #ifndef __KERNEL__ */
-
 /******************************************************************************
  * Slave configuration methods
  *****************************************************************************/
--- a/lib/master.c	Mon Jul 27 10:48:52 2009 +0000
+++ b/lib/master.c	Tue Jul 28 15:42:00 2009 +0000
@@ -131,13 +131,13 @@
 
 /*****************************************************************************/
 
-int ecrt_master_slave(ec_master_t *master, uint16_t position,
+int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
         ec_slave_info_t *slave_info)
 {
     ec_ioctl_slave_t data;
     int index;
 
-    data.position = position;
+    data.position = slave_position;
 
     if (ioctl(master->fd, EC_IOCTL_SLAVE, &data) == -1) {
         fprintf(stderr, "Failed to get slave info: %s\n", strerror(errno));
@@ -161,6 +161,152 @@
 
 /*****************************************************************************/
 
+int ecrt_master_get_sync_manager(ec_master_t *master, uint16_t slave_position,
+        uint8_t sync_index, ec_sync_info_t *sync)
+{
+	ec_ioctl_slave_sync_t data;
+
+    if (sync_index >= EC_MAX_SYNC_MANAGERS)
+        return -ENOENT;
+
+    memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_t));
+    data.slave_position = slave_position;
+    data.sync_index = sync_index;
+
+    if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC, &data) == -1) {
+        fprintf(stderr, "Failed to get sync manager information: %s\n",
+                strerror(errno));
+        return -1; // FIXME
+    }
+
+    sync->index = sync_index;
+	sync->dir = EC_READ_BIT(&data.control_register, 2) ?
+        EC_DIR_OUTPUT : EC_DIR_INPUT;
+    sync->n_pdos = data.pdo_count;
+    sync->pdos = NULL;
+    sync->watchdog_mode = EC_READ_BIT(&data.control_register, 6) ?
+        EC_WD_ENABLE : EC_WD_DISABLE;
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+int ecrt_master_get_pdo(ec_master_t *master, uint16_t slave_position,
+        uint8_t sync_index, uint16_t pos, ec_pdo_info_t *pdo)
+{
+	ec_ioctl_slave_sync_pdo_t data;
+
+    if (sync_index >= EC_MAX_SYNC_MANAGERS)
+        return -ENOENT;
+
+    memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_t));
+    data.slave_position = slave_position;
+    data.sync_index = sync_index;
+    data.pdo_pos = pos;
+
+    if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO, &data) == -1) {
+        fprintf(stderr, "Failed to get pdo information: %s\n",
+                strerror(errno));
+        return -1; // FIXME
+    }
+
+    pdo->index = data.index;
+    pdo->n_entries = data.entry_count;
+    pdo->entries = NULL;
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+int ecrt_master_get_pdo_entry(ec_master_t *master, uint16_t slave_position,
+        uint8_t sync_index, uint16_t pdo_pos, uint16_t entry_pos,
+        ec_pdo_entry_info_t *entry)
+{
+	ec_ioctl_slave_sync_pdo_entry_t data;
+
+    if (sync_index >= EC_MAX_SYNC_MANAGERS)
+        return -ENOENT;
+
+    memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_entry_t));
+    data.slave_position = slave_position;
+    data.sync_index = sync_index;
+    data.pdo_pos = pdo_pos;
+    data.entry_pos = entry_pos;
+
+    if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO_ENTRY, &data) == -1) {
+        fprintf(stderr, "Failed to get pdo entry information: %s\n",
+                strerror(errno));
+        return -1; // FIXME
+    }
+
+    entry->index = data.index;
+    entry->subindex = data.subindex;
+    entry->bit_length = data.bit_length;
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
+        uint16_t index, uint8_t subindex, uint8_t *data,
+        size_t data_size, uint32_t *abort_code)
+{
+    ec_ioctl_slave_sdo_download_t download;
+
+    download.slave_position = slave_position;
+    download.sdo_index = index;
+    download.sdo_entry_subindex = subindex;
+    download.data_size = data_size;
+    download.data = data;
+
+    if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download) == -1) {
+        if (errno == -EIO) {
+            if (abort_code) {
+                *abort_code = download.abort_code;
+            }
+        }
+        fprintf(stderr, "Failed to execute SDO download: %s\n",
+            strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
+        uint16_t index, uint8_t subindex, uint8_t *target,
+        size_t target_size, size_t *result_size, uint32_t *abort_code)
+{
+    ec_ioctl_slave_sdo_upload_t upload;
+
+    upload.slave_position = slave_position;
+    upload.sdo_index = index;
+    upload.sdo_entry_subindex = subindex;
+    upload.target_size = target_size;
+    upload.target = target;
+
+    if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_UPLOAD, &upload) == -1) {
+        if (errno == -EIO) {
+            if (abort_code) {
+                *abort_code = upload.abort_code;
+            }
+        }
+        fprintf(stderr, "Failed to execute SDO upload: %s\n",
+                strerror(errno));
+        return -1;
+    }
+
+    *result_size = upload.data_size;
+    return 0;
+}
+
+/*****************************************************************************/
+
 int ecrt_master_activate(ec_master_t *master)
 {
     if (ioctl(master->fd, EC_IOCTL_ACTIVATE,
@@ -248,60 +394,3 @@
 }
 
 /*****************************************************************************/
-
-int ecrt_slave_sdo_download(ec_master_t* master, uint16_t slave_position,
-        uint16_t index, uint8_t subindex, uint8_t *data,
-        size_t data_size, uint32_t *abort_code)
-{
-    ec_ioctl_slave_sdo_download_t download;
-
-    download.slave_position = slave_position;
-    download.sdo_index = index;
-    download.sdo_entry_subindex = subindex;
-    download.data_size = data_size;
-    download.data = data;
-
-    if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download) == -1) {
-        if (errno == -EIO) {
-            if (abort_code) {
-                *abort_code = download.abort_code;
-            }
-        }
-        fprintf(stderr, "Failed to execute SDO download: %s\n",
-            strerror(errno));
-        return -1;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************/
-
-int ecrt_slave_sdo_upload(ec_master_t* master, uint16_t slave_position,
-        uint16_t index, uint8_t subindex, uint8_t *target,
-        size_t target_size, size_t *result_size, uint32_t *abort_code)
-{
-    ec_ioctl_slave_sdo_upload_t upload;
-
-    upload.slave_position = slave_position;
-    upload.sdo_index = index;
-    upload.sdo_entry_subindex = subindex;
-    upload.target_size = target_size;
-    upload.target = target;
-
-    if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_UPLOAD, &upload) == -1) {
-        if (errno == -EIO) {
-            if (abort_code) {
-                *abort_code = upload.abort_code;
-            }
-        }
-        fprintf(stderr, "Failed to execute SDO upload: %s\n",
-                strerror(errno));
-        return -1;
-    }
-
-    *result_size = upload.data_size;
-    return 0;
-}
-
-/*****************************************************************************/