# HG changeset patch # User Florian Pose # Date 1222872148 0 # Node ID 632a6b91f8e45082febac5a66962c4dfb15c0940 # Parent 794cbccdcd00bcce9d6f74611baddb9c213590f6 First version of userspace library with requesting/releasing. diff -r 794cbccdcd00 -r 632a6b91f8e4 Makefile.am --- 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 diff -r 794cbccdcd00 -r 632a6b91f8e4 bootstrap --- 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 diff -r 794cbccdcd00 -r 632a6b91f8e4 configure.ac --- 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 diff -r 794cbccdcd00 -r 632a6b91f8e4 examples/Makefile.am --- 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 #------------------------------------------------------------------------------ diff -r 794cbccdcd00 -r 632a6b91f8e4 examples/user/Makefile.am --- /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 + +#------------------------------------------------------------------------------ diff -r 794cbccdcd00 -r 632a6b91f8e4 examples/user/main.c --- /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; +} + +/****************************************************************************/ diff -r 794cbccdcd00 -r 632a6b91f8e4 lib/Makefile.am --- /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 + +#------------------------------------------------------------------------------ diff -r 794cbccdcd00 -r 632a6b91f8e4 lib/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 +#include +#include +#include +#include +#include +#include + +#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; +} + +/*****************************************************************************/ diff -r 794cbccdcd00 -r 632a6b91f8e4 master/cdev.c --- 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; } diff -r 794cbccdcd00 -r 632a6b91f8e4 master/ioctl.h --- 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