First version of userspace library with requesting/releasing.
authorFlorian Pose <fp@igh-essen.com>
Wed, 01 Oct 2008 14:42:28 +0000
changeset 1242 632a6b91f8e4
parent 1241 794cbccdcd00
child 1243 13cb18b91627
First version of userspace library with requesting/releasing.
Makefile.am
bootstrap
configure.ac
examples/Makefile.am
examples/user/Makefile.am
examples/user/main.c
lib/Makefile.am
lib/common.c
master/cdev.c
master/ioctl.h
--- a/Makefile.am	Wed Oct 01 14:37:34 2008 +0000
+++ b/Makefile.am	Wed Oct 01 14:42:28 2008 +0000
@@ -38,10 +38,15 @@
     script \
     tool
 
+if ENABLE_USERLIB
+SUBDIRS += lib
+endif
+
 DIST_SUBDIRS = \
     devices \
     examples \
     include \
+    lib \
     master \
     script \
     tool
@@ -80,21 +85,25 @@
 
 mrproper: clean cleandoc
 	rm -rf \
+		*~ \
 		aclocal.m4 \
 		autoconf \
 		autom4te.cache \
+		ChangeLog \
 		config.h \
 		config.h.in \
 		config.log \
 		config.status \
+		configure \
 		configure.in \
-		configure \
+		Doxyfile \
+		Kbuild \
+		libtool \
 		Makefile \
 		Makefile.in \
+		Module.symvers \
 		stamp-h1 \
-		ChangeLog \
-        Kbuild \
-		*~
+		TAGS
 
 doc:
 	doxygen Doxyfile
--- a/bootstrap	Wed Oct 01 14:37:34 2008 +0000
+++ b/bootstrap	Wed Oct 01 14:42:28 2008 +0000
@@ -3,9 +3,5 @@
 # $Id$
 
 set -x
-mkdir -p autoconf
-aclocal -I autoconf
-autoheader
 touch ChangeLog
-automake --add-missing --copy
-autoconf
+autoreconf -i
--- a/configure.ac	Wed Oct 01 14:37:34 2008 +0000
+++ b/configure.ac	Wed Oct 01 14:42:28 2008 +0000
@@ -15,6 +15,7 @@
 #------------------------------------------------------------------------------
 
 AC_PROG_CXX
+AC_PROG_LIBTOOL
 
 #------------------------------------------------------------------------------
 # Linux sources
@@ -369,6 +370,28 @@
 fi
 
 #------------------------------------------------------------------------------
+# Userspace library generation
+#------------------------------------------------------------------------------
+
+AC_ARG_ENABLE([userlib],
+    AS_HELP_STRING([--enable-userlib],
+                   [Generation of the userspace library (default: yes)]),
+    [
+        case "${enableval}" in
+            yes) userlib=1
+                ;;
+            no) userlib=0
+                ;;
+            *) AC_MSG_ERROR([Invalid value for --enable-userlib])
+                ;;
+        esac
+    ],
+    [userlib=1]
+)
+
+AM_CONDITIONAL(ENABLE_USERLIB, test "x$userlib" = "x1")
+
+#------------------------------------------------------------------------------
 
 AC_CONFIG_FILES([
         Doxyfile
@@ -383,7 +406,9 @@
         examples/mini/Makefile
         examples/rtai/Kbuild
         examples/rtai/Makefile
+        examples/user/Makefile
         include/Makefile
+        lib/Makefile
         master/Kbuild
         master/Makefile
         script/Makefile
--- a/examples/Makefile.am	Wed Oct 01 14:37:34 2008 +0000
+++ b/examples/Makefile.am	Wed Oct 01 14:42:28 2008 +0000
@@ -31,6 +31,9 @@
 #
 #------------------------------------------------------------------------------
 
-DIST_SUBDIRS = mini rtai
+DIST_SUBDIRS = \
+	mini \
+	rtai \
+	user
 
 #------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/user/Makefile.am	Wed Oct 01 14:42:28 2008 +0000
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+AM_CFLAGS = -Wall
+
+noinst_PROGRAMS = ec_user_example
+
+ec_user_example_SOURCES = main.c
+ec_user_example_CFLAGS = -I$(srcdir)/../../include
+ec_user_example_LDFLAGS = -L$(srcdir)/../../lib/.libs -lethercat
+
+#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/user/main.c	Wed Oct 01 14:42:28 2008 +0000
@@ -0,0 +1,25 @@
+/*****************************************************************************
+ *
+ * $Id$
+ *
+ ****************************************************************************/
+
+#include "ecrt.h"
+
+/****************************************************************************/
+
+int main(int argc, char **argv)
+{
+	ec_master_t *master = ecrt_request_master(0);
+
+	if (!master)
+		return -1;
+
+	while (1) {
+		sleep(1);
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/Makefile.am	Wed Oct 01 14:42:28 2008 +0000
@@ -0,0 +1,45 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+AM_CFLAGS = -Wall
+
+lib_LTLIBRARIES = libethercat.la
+
+#------------------------------------------------------------------------------
+
+libethercat_la_LDFLAGS = -version-info 1:0:0
+libethercat_la_CFLAGS = -I$(srcdir)/..
+libethercat_la_SOURCES = \
+	common.c
+
+#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/common.c	Wed Oct 01 14:42:28 2008 +0000
@@ -0,0 +1,102 @@
+/******************************************************************************
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+ *
+ *  This file is part of the IgH EtherCAT Master.
+ *
+ *  The IgH EtherCAT Master is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  The IgH EtherCAT Master is distributed in the hope that it will be
+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with the IgH EtherCAT Master; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *  The right to use EtherCAT Technology is granted and comes free of
+ *  charge under condition of compatibility of product made by
+ *  Licensee. People intending to distribute/sell products based on the
+ *  code, have to sign an agreement to guarantee that products using
+ *  software based on IgH EtherCAT master stay compatible with the actual
+ *  EtherCAT specification (which are released themselves as an open
+ *  standard) as the (only) precondition to have the right to use EtherCAT
+ *  Technology, IP and trade marks.
+ *
+ *****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "include/ecrt.h"
+#include "master/ioctl.h"
+
+struct ec_master {
+    int fd;
+    void *handle;
+};
+
+/*****************************************************************************/
+
+#define MAX_PATH_LEN 64
+
+ec_master_t *ecrt_request_master(unsigned int master_index)
+{
+    char path[MAX_PATH_LEN];
+    ec_master_t *master;
+    ec_ioctl_request_t data;
+
+    master = malloc(sizeof(ec_master_t));
+    if (!master) {
+        fprintf(stderr, "Failed to allocate memory.\n");
+        return 0;
+    }
+
+    snprintf(path, MAX_PATH_LEN - 1, "/dev/EtherCAT%u", master_index);
+
+    master->fd = open(path, O_RDWR);
+    if (master->fd == -1) {
+        fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
+        free(master);
+        return 0;
+    }
+
+    if (ioctl(master->fd, EC_IOCTL_REQUEST, &data) == -1) {
+        fprintf(stderr, "Failed to request master %u: %s\n",
+                master_index, strerror(errno));
+        close(master->fd);
+        free(master);
+        return 0; 
+    }
+
+    master->handle = data.handle;
+    return master;
+}
+
+/*****************************************************************************/
+
+void ecrt_release_master(ec_master_t *master)
+{
+    close(master->fd);
+    free(master);
+}
+
+/*****************************************************************************/
+
+unsigned int ecrt_version_magic(void)
+{
+    return ECRT_VERSION_MAGIC;
+}
+
+/*****************************************************************************/
--- a/master/cdev.c	Wed Oct 01 14:37:34 2008 +0000
+++ b/master/cdev.c	Wed Oct 01 14:42:28 2008 +0000
@@ -66,6 +66,15 @@
 
 /*****************************************************************************/
 
+/** Private data structure for file handles.
+ */
+typedef struct {
+    ec_cdev_t *cdev;
+    unsigned int requested;
+} ec_cdev_priv_t;
+
+/*****************************************************************************/
+
 /** Constructor.
  * 
  * \return 0 in case of success, else < 0
@@ -1354,6 +1363,32 @@
     return 0;
 }
 
+/*****************************************************************************/
+
+/** Request the master from userspace.
+ */
+int ec_cdev_ioctl_request(
+        ec_master_t *master, /**< EtherCAT master. */
+        unsigned long arg, /**< ioctl() argument. */
+        ec_cdev_priv_t *priv /**< Private data structure of file handle. */
+        )
+{
+    ec_ioctl_request_t data;
+    int ret = 0;
+
+    data.handle = ecrt_request_master(master->index);
+
+    if (IS_ERR(data.handle)) {
+        ret = PTR_ERR(data.handle);
+    } else {
+        priv->requested = 1;
+        if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+            ret = -EFAULT;
+    }
+
+    return ret;
+}
+
 /******************************************************************************
  * File operations
  *****************************************************************************/
@@ -1364,8 +1399,18 @@
 {
     ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
     ec_master_t *master = cdev->master;
-
-    filp->private_data = cdev;
+    ec_cdev_priv_t *priv;
+
+    priv = kmalloc(sizeof(ec_cdev_priv_t), GFP_KERNEL);
+    if (!priv) {
+        EC_ERR("Failed to allocate memory for private data structure.\n");
+        return -ENOMEM;
+    }
+
+    priv->cdev = cdev;
+    priv->requested = 0;
+
+    filp->private_data = priv;
     if (master->debug_level)
         EC_DBG("File opened.\n");
     return 0;
@@ -1377,11 +1422,15 @@
  */
 int eccdev_release(struct inode *inode, struct file *filp)
 {
-    ec_cdev_t *cdev = (ec_cdev_t *) filp->private_data;
-    ec_master_t *master = cdev->master;
+    ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data;
+    ec_master_t *master = priv->cdev->master;
+
+    if (priv->requested)
+        ecrt_release_master(master);
 
     if (master->debug_level)
         EC_DBG("File closed.\n");
+    kfree(priv);
     return 0;
 }
 
@@ -1391,8 +1440,8 @@
  */
 long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-    ec_cdev_t *cdev = (ec_cdev_t *) filp->private_data;
-    ec_master_t *master = cdev->master;
+    ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data;
+    ec_master_t *master = priv->cdev->master;
 
     if (master->debug_level)
         EC_DBG("ioctl(filp = %x, cmd = %u (%u), arg = %x)\n",
@@ -1453,6 +1502,10 @@
             return ec_cdev_ioctl_config_pdo_entry(master, arg);
         case EC_IOCTL_CONFIG_SDO:
             return ec_cdev_ioctl_config_sdo(master, arg);
+        case EC_IOCTL_REQUEST:
+            if (!(filp->f_mode & FMODE_WRITE))
+				return -EPERM;
+			return ec_cdev_ioctl_request(master, arg, priv);
         default:
             return -ENOTTY;
     }
--- a/master/ioctl.h	Wed Oct 01 14:37:34 2008 +0000
+++ b/master/ioctl.h	Wed Oct 01 14:42:28 2008 +0000
@@ -78,6 +78,7 @@
 #define EC_IOCTL_CONFIG_PDO           EC_IOWR(0x13, ec_ioctl_config_pdo_t)
 #define EC_IOCTL_CONFIG_PDO_ENTRY     EC_IOWR(0x14, ec_ioctl_config_pdo_entry_t)
 #define EC_IOCTL_CONFIG_SDO           EC_IOWR(0x15, ec_ioctl_config_sdo_t)
+#define EC_IOCTL_REQUEST               EC_IOR(0x16, ec_ioctl_request_t)
 
 #define EC_IOCTL_STRING_SIZE 64
 
@@ -361,6 +362,12 @@
 
 /*****************************************************************************/
 
+typedef struct {
+    ec_master_t *handle;
+} ec_ioctl_request_t;
+
+/*****************************************************************************/
+
 /** \endcond */
 
 #endif