Separated master requesting into open and reserve for userspace library.
authorFlorian Pose <fp@igh-essen.com>
Fri, 10 Jul 2009 10:07:48 +0000
changeset 1497 c9308eb34c0e
parent 1496 f98f89d0d778
child 1498 58532f81a456
Separated master requesting into open and reserve for userspace library.
(thanks to Martin Troxler).
NEWS
include/ecrt.h
lib/common.c
lib/master.c
--- a/NEWS	Fri Jul 10 09:38:37 2009 +0000
+++ b/NEWS	Fri Jul 10 10:07:48 2009 +0000
@@ -28,6 +28,10 @@
   O. Zarges.
 * 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.
 * SDO entry access rights are shown in 'ethercat sdos'.
 * Added 64-bit data access macros to application header.
--- a/include/ecrt.h	Fri Jul 10 09:38:37 2009 +0000
+++ b/include/ecrt.h	Fri Jul 10 10:07:48 2009 +0000
@@ -47,6 +47,10 @@
  *   ecrt_master_sync_reference_clock() and  ecrt_master_sync_slave_clocks()
  *   for offset and drift compensation. The EC_TIMEVAL2NANO() macro can be
  *   used for epoch time conversion.
+ * - Added ecrt_open_master() and ecrt_master_reserve() separation for
+ *   userspace.
+ * - Added ecrt_master() userspace interface, to get information about a
+ *   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
@@ -192,6 +196,22 @@
 
 /*****************************************************************************/
 
+#ifndef __KERNEL__
+
+/** Master information.
+ *
+ * This is used as an output parameter of ecrt_master().
+ *
+ * \see ecrt_master().
+ */
+typedef struct {
+   unsigned int slave_count; /**< Number of slaves in the bus. */
+   unsigned int link_up : 1; /**< \a true, if the network link is up. */
+   uint64_t app_time; /**< Application time. */
+} ec_master_info_t;
+
+/*****************************************************************************/
+
 /** Slave information.
  *
  * This is used as an output parameter of ecrt_master_slave().
@@ -213,6 +233,8 @@
     char name[EC_MAX_STRING_LENGTH]; /**< Name of the slave. */
 } ec_slave_info_t;
 
+#endif // #ifndef __KERNEL__
+
 /*****************************************************************************/
 
 /** Domain working counter interpretation.
@@ -354,6 +376,9 @@
  * Before an application can access an EtherCAT master, it has to reserve one
  * for exclusive use.
  *
+ * In userspace, this is a convenience function for ecrt_open_master() and
+ * ecrt_master_reserve().
+ *
  * This function has to be the first function an application has to call to
  * use EtherCAT. The function takes the index of the master as its argument.
  * The first master has index 0, the n-th master has index n - 1. The number
@@ -365,6 +390,25 @@
         unsigned int master_index /**< Index of the master to request. */
         );
 
+#ifndef __KERNEL__
+
+/** Opens an EtherCAT master for userspace access.
+ *
+ * This function has to be the first function an application has to call to
+ * use EtherCAT. The function takes the index of the master as its argument.
+ * The first master has index 0, the n-th master has index n - 1. The number
+ * of masters has to be specified when loading the master module.
+ *
+ * For convenience, the function ecrt_request_master() can be used.
+ *
+ * \return Pointer to the opened master, otherwise \a NULL.
+ */
+ec_master_t *ecrt_open_master(
+		unsigned int master_index /**< Index of the master to request. */
+		);
+
+#endif // #ifndef __KERNEL__
+
 /** Releases a requested EtherCAT master.
  *
  * After use, a master it has to be released to make it available for other
@@ -378,6 +422,22 @@
  * Master methods
  *****************************************************************************/
 
+#ifndef __KERNEL__
+
+/** Reserves an EtherCAT master for realtime operation.
+ *
+ * Before an application can use PDO/domain registration functions or SDO
+ * request functions on the master, it has to reserve one for exclusive use.
+ *
+ * \return 0 in case of success, else < 0
+ *
+ */
+int ecrt_master_reserve(
+		ec_master_t *master /**< EtherCAT master */
+		);
+
+#endif // #ifndef __KERNEL__
+
 #ifdef __KERNEL__
 
 /** Sets the locking callbacks.
@@ -451,6 +511,21 @@
 
 #ifndef __KERNEL__
 
+/** Obtains master information.
+ *
+ * No memory is allocated on the heap in
+ * this function.
+ *
+ * \attention The pointer to this structure must point to a valid variable.
+ *
+ * \return 0 in case of success, else < 0
+ */
+int ecrt_master(
+		ec_master_t *master, /**< EtherCAT master */
+		ec_master_info_t *master_info /**< Structure that will output the
+									  information */
+		);
+
 /** Obtains slave information.
  *
  * Tries to find the slave with the given ring position. The obtained
@@ -468,7 +543,7 @@
                                       information */
         );
 
-#endif /* ifndef __KERNEL__ */
+#endif /* #ifndef __KERNEL__ */
 
 /** Finishes the configuration phase and prepares for cyclic operation.
  *
@@ -603,7 +678,7 @@
         uint32_t *abort_code /**< Abort code of the SDO upload. */
         );
 
-#endif /* ifndef __KERNEL__ */
+#endif /* #ifndef __KERNEL__ */
 
 /******************************************************************************
  * Slave configuration methods
--- a/lib/common.c	Fri Jul 10 09:38:37 2009 +0000
+++ b/lib/common.c	Fri Jul 10 10:07:48 2009 +0000
@@ -50,9 +50,25 @@
 
 /*****************************************************************************/
 
+ec_master_t *ecrt_request_master(unsigned int master_index)
+{
+    ec_master_t *master = ecrt_open_master(master_index);
+    if (master) {
+        if (ecrt_master_reserve(master) < 0) {
+            close(master->fd);
+            free(master);
+            master = 0;
+        }
+    }
+
+    return master;
+}
+
+/*****************************************************************************/
+
 #define MAX_PATH_LEN 64
 
-ec_master_t *ecrt_request_master(unsigned int master_index)
+ec_master_t *ecrt_open_master(unsigned int master_index)
 {
     char path[MAX_PATH_LEN];
     ec_master_t *master;
@@ -75,14 +91,6 @@
         return 0;
     }
 
-    if (ioctl(master->fd, EC_IOCTL_REQUEST, NULL) == -1) {
-        fprintf(stderr, "Failed to request master %u: %s\n",
-                master_index, strerror(errno));
-        close(master->fd);
-        free(master);
-        return 0; 
-    }
-
     return master;
 }
 
--- a/lib/master.c	Fri Jul 10 09:38:37 2009 +0000
+++ b/lib/master.c	Fri Jul 10 10:07:48 2009 +0000
@@ -42,6 +42,17 @@
 
 /*****************************************************************************/
 
+int ecrt_master_reserve(ec_master_t *master)
+{
+    if (ioctl(master->fd, EC_IOCTL_REQUEST, NULL) == -1) {
+        fprintf(stderr, "Failed to reserve master: %s\n",
+                strerror(errno));
+        return -1;
+    }
+}
+
+/*****************************************************************************/
+
 ec_domain_t *ecrt_master_create_domain(ec_master_t *master)
 {
     ec_domain_t *domain;
@@ -103,6 +114,23 @@
 
 /*****************************************************************************/
 
+int ecrt_master(ec_master_t* master, ec_master_info_t *master_info)
+{
+	ec_ioctl_master_t data;
+
+	if (ioctl(master->fd, EC_IOCTL_MASTER, &data) < 0) {
+        fprintf(stderr, "Failed to get master info: %s\n", strerror(errno));
+		return -1;
+	}
+
+	master_info->slave_count = data.slave_count;
+	master_info->link_up = data.devices[0].link_state;
+	master_info->app_time = data.app_time;
+	return 0;
+}
+
+/*****************************************************************************/
+
 int ecrt_master_slave(ec_master_t *master, uint16_t position,
         ec_slave_info_t *slave_info)
 {
@@ -112,8 +140,7 @@
     data.position = position;
 
     if (ioctl(master->fd, EC_IOCTL_SLAVE, &data) == -1) {
-        fprintf(stderr, "Failed to get slave info: %s\n",
-                strerror(errno));
+        fprintf(stderr, "Failed to get slave info: %s\n", strerror(errno));
         return -1;
     }
 
@@ -129,7 +156,6 @@
     slave_info->sync_count = data.sync_count;
     slave_info->sdo_count = data.sdo_count;
     strncpy(slave_info->name, data.name, EC_IOCTL_STRING_SIZE);
-
     return 0;
 }