Renamed rt example to msr.
authorFlorian Pose <fp@igh-essen.com>
Wed, 10 May 2006 07:58:41 +0000
changeset 224 4828e5e419bf
parent 223 daa5e5656b35
child 225 9e8150db6fc8
Renamed rt example to msr.
examples/msr/Makefile
examples/msr/install.sh
examples/msr/libm.o_shipped
examples/msr/msr_load
examples/msr/msr_param.h
examples/msr/msr_rt.c
examples/msr/msr_unload
examples/msr/msrserv.pl
examples/msr/rt.conf.tmpl
examples/rt/Makefile
examples/rt/install.sh
examples/rt/libm.o_shipped
examples/rt/msr_load
examples/rt/msr_param.h
examples/rt/msr_rt.c
examples/rt/msr_unload
examples/rt/msrserv.pl
examples/rt/rt.conf.tmpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/Makefile	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,87 @@
+#------------------------------------------------------------------------------
+#
+#  Makefile
+#
+#  $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; version 2 of the License.
+#
+#  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
+#
+#------------------------------------------------------------------------------
+
+ifneq ($(KERNELRELEASE),)
+
+#------------------------------------------------------------------------------
+#  kbuild section
+#------------------------------------------------------------------------------
+
+ifneq ($(wildcard $(src)/rt.conf),)
+include $(src)/rt.conf
+else
+MODULENAME := rt
+endif
+
+obj-m := $(MODULENAME).o
+
+$(MODULENAME)-objs := msr_rt.o \
+			rt_lib/msr-core/msr_lists.o \
+			rt_lib/msr-core/msr_main.o \
+			rt_lib/msr-core/msr_charbuf.o \
+			rt_lib/msr-core/msr_reg.o \
+			rt_lib/msr-core/msr_interpreter.o \
+			rt_lib/msr-core/msr_messages.o \
+			rt_lib/msr-core/msr_proc.o \
+			rt_lib/msr-core/msr_error_reg.o \
+			rt_lib/msr-utils/msr_utils.o \
+			rt_lib/msr-utils/msr_time.o \
+			rt_lib/msr-math/msr_base64.o \
+			rt_lib/msr-math/msr_hex_bin.o \
+			libm.o
+
+EXTRA_CFLAGS := -I$(src)/rt_lib/msr-include -D_SIMULATION \
+		-I/usr/include -mhard-float \
+		-DSVNREV=$(shell svnversion $(src)) -DUSER=$(USER)
+
+#------------------------------------------------------------------------------
+
+else
+
+#------------------------------------------------------------------------------
+#  default section
+#------------------------------------------------------------------------------
+
+ifneq ($(wildcard rt.conf),)
+include rt.conf
+else
+MODULENAME := msr_rt
+KERNEL := $(shell uname -r)
+endif
+
+KERNELDIR := /lib/modules/$(KERNEL)/build
+
+modules:
+	$(MAKE) -C $(KERNELDIR) M=`pwd`
+
+clean:
+	$(MAKE) -C $(KERNELDIR) M=`pwd` clean
+
+install:
+	@./install.sh $(MODULENAME) $(KERNEL)
+
+#------------------------------------------------------------------------------
+
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/install.sh	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+#------------------------------------------------------------------------------
+#
+#  Realtime module install script
+#
+#  $Id: install.sh 5 2006-04-07 13:49:10Z fp $
+#
+#  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; version 2 of the License.
+#
+#  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
+#
+#------------------------------------------------------------------------------
+
+# Fetch parameters
+
+if [ $# -ne 2 ]; then
+    echo "Usage: $0 <MODULENAME> <KERNEL>"
+    exit 1
+fi
+
+MODULENAME=$1
+KERNEL=$2
+
+MODULESDIR=/lib/modules/$KERNEL/kernel/drivers/rt
+
+echo "Realtime installer"
+echo "  target: $MODULENAME"
+echo "  kernel: $KERNEL"
+
+# Create target directory
+
+if [ ! -d $MODULESDIR ]; then
+    echo "  creating $MODULESDIR..."
+    mkdir $MODULESDIR || exit 1
+fi
+
+# Install files
+
+echo "  installing $MODULENAME..."
+if ! cp $MODULENAME.ko $MODULESDIR/$MODULENAME.ko; then exit 1; fi
+
+# Calculate dependencies
+
+echo "  building module dependencies..."
+depmod
+
+# Finish
+
+echo "done."
+exit 0
+
+#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/libm.o_shipped	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,1 @@
+/usr/lib/libm.a
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/msr_load	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh 
+module="msr_rt"
+device="msr"
+mode="664"
+
+# Group: since distributions do it differently, look for wheel or use staff
+if grep '^staff:' /etc/group > /dev/null; then
+    group="staff"
+else
+    group="wheel"
+fi
+
+# invoke insmod with all arguments we got
+# and use a pathname, as newer modutils don't look in . by default
+/sbin/insmod -f ./$module.ko $* || exit 1
+
+major=`cat /proc/devices | awk "\\$2==\"$device\" {print \\$1}"`
+
+echo $major
+# Remove stale nodes and replace them, then give gid and perms
+# Usually the script is shorter, it's scull that has several devices in it.
+
+rm -f /dev/${device}
+mknod /dev/${device} c $major 0
+# ln -sf ${device}0 /dev/${device}
+chgrp users /dev/${device}
+chmod $mode  /dev/${device}
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/msr_param.h	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,31 @@
+/******************************************************************************
+ *
+ *  $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; version 2 of the License.
+ *
+ *  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
+ *
+ *****************************************************************************/
+
+#ifndef _MSR_PARAM_H_
+#define _MSR_PARAM_H_
+
+#define  MSR_ABTASTFREQUENZ 1000
+
+#endif
+
+/*****************************************************************************/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/msr_rt.c	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,296 @@
+/******************************************************************************
+ *
+ *  m s r _ r t . c
+ *
+ *  Kernelmodul für 2.6 Kernel zur Meßdatenerfassung, Steuerung und Regelung.
+ *
+ *  $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; version 2 of the License.
+ *
+ *  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
+ *
+ *****************************************************************************/
+
+// Linux
+#include <linux/module.h>
+#include <linux/ipipe.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+// RT_lib
+#include <msr_main.h>
+#include <msr_utils.h>
+#include <msr_messages.h>
+#include <msr_float.h>
+#include <msr_reg.h>
+#include <msr_time.h>
+#include "msr_param.h"
+
+// EtherCAT
+#include "../../include/ecrt.h"
+
+#define ASYNC
+
+// Defines/Makros
+#define HZREDUCTION (MSR_ABTASTFREQUENZ / HZ)
+
+/*****************************************************************************/
+/* Globale Variablen */
+
+// Adeos
+static struct ipipe_domain this_domain;
+static struct ipipe_sysinfo sys_info;
+
+// EtherCAT
+ec_master_t *master = NULL;
+ec_domain_t *domain1 = NULL;
+
+// Prozessdaten
+void *r_ssi;
+void *r_ssi_st;
+
+// KanŽäle
+uint32_t k_ssi;
+uint32_t k_ssi_st;
+
+ec_field_init_t domain1_fields[] = {
+    {&r_ssi,    "0:3", "Beckhoff", "EL5001", "InputValue", 0},
+    {&r_ssi_st, "0:3", "Beckhoff", "EL5001", "Status",     0},
+    {}
+};
+
+/*****************************************************************************/
+
+static void msr_controller_run(void)
+{
+#ifdef ASYNC
+    // Empfangen
+    ecrt_master_async_receive(master);
+    ecrt_domain_process(domain1);
+#else
+    // Senden und empfangen
+    ecrt_domain_queue(domain1);
+    ecrt_master_run(master);
+    ecrt_master_sync_io(master);
+    ecrt_domain_process(domain1);
+#endif
+
+    // Prozessdaten verarbeiten
+    k_ssi =    EC_READ_U32(r_ssi);
+    k_ssi_st = EC_READ_U8 (r_ssi_st);
+
+#ifdef ASYNC
+    // Senden
+    ecrt_domain_queue(domain1);
+    ecrt_master_run(master);
+    ecrt_master_async_send(master);
+#endif
+}
+
+/*****************************************************************************/
+
+int msr_globals_register(void)
+{
+    msr_reg_kanal("/ssi_position", "", &k_ssi,    TUINT);
+    msr_reg_kanal("/ssi_status",   "", &k_ssi_st, TUINT);
+    return 0;
+}
+
+/*****************************************************************************/
+
+void msr_run(unsigned irq)
+{
+    static int counter = 0;
+
+    MSR_ADEOS_INTERRUPT_CODE(msr_controller_run(); msr_write_kanal_list(););
+
+    ipipe_control_irq(irq, 0, IPIPE_ENABLE_MASK); // Interrupt bestŽätigen
+    if (++counter >= HZREDUCTION) {
+	ipipe_propagate_irq(irq);  // und weiterreichen
+	counter = 0;
+    }
+}
+
+/*****************************************************************************/
+
+void domain_entry(void)
+{
+    printk("Domain %s started.\n", ipipe_current_domain->name);
+
+    ipipe_get_sysinfo(&sys_info);
+    ipipe_virtualize_irq(ipipe_current_domain,sys_info.archdep.tmirq,
+			 &msr_run, NULL, IPIPE_HANDLE_MASK);
+
+    ipipe_tune_timer(1000000000UL / MSR_ABTASTFREQUENZ, 0);
+}
+
+/*****************************************************************************/
+
+int __init init_rt_module(void)
+{
+    struct ipipe_domain_attr attr; //ipipe
+#if 1
+    ec_slave_t *slave;
+#endif
+
+    // Als allererstes die RT-Lib initialisieren
+    if (msr_rtlib_init(1, MSR_ABTASTFREQUENZ, 10, &msr_globals_register) < 0) {
+        printk(KERN_ERR "Failed to initialize rtlib!\n");
+        goto out_return;
+    }
+
+    if ((master = ecrt_request_master(0)) == NULL) {
+        printk(KERN_ERR "Failed to request master 0!\n");
+        goto out_msr_cleanup;
+    }
+
+    //ecrt_master_print(master, 2);
+
+    printk(KERN_INFO "Creating domains...\n");
+    if (!(domain1 = ecrt_master_create_domain(master))) {
+        printk(KERN_ERR "Failed to create domains!\n");
+        goto out_release_master;
+    }
+
+    printk(KERN_INFO "Registering domain fields...\n");
+    if (ecrt_domain_register_field_list(domain1, domain1_fields)) {
+        printk(KERN_ERR "Failed to register domain fields.\n");
+        goto out_release_master;
+    }
+
+    printk(KERN_INFO "Activating master...\n");
+    if (ecrt_master_activate(master)) {
+        printk(KERN_ERR "Could not activate master!\n");
+        goto out_release_master;
+    }
+
+#if 0
+    if (ecrt_master_start_eoe(master)) {
+        printk(KERN_ERR "Failed to start EoE processing!\n");
+        goto out_deactivate;
+    }
+#endif
+
+#if 0
+    if (ecrt_master_fetch_sdo_lists(master)) {
+        printk(KERN_ERR "Failed to fetch SDO lists!\n");
+        goto out_deactivate;
+    }
+    ecrt_master_print(master, 2);
+#else
+    ecrt_master_print(master, 0);
+#endif
+
+#if 1
+    if (!(slave = ecrt_master_get_slave(master, "0:3"))) {
+        printk(KERN_ERR "Failed to get slave!\n");
+        goto out_deactivate;
+    }
+
+    if (
+        ecrt_slave_sdo_write_exp8(slave, 0x4061, 1,  1) || // disable frame error bit
+        ecrt_slave_sdo_write_exp8(slave, 0x4061, 2,  0) || // power failure bit
+        ecrt_slave_sdo_write_exp8(slave, 0x4061, 3,  1) || // inhibit time
+        ecrt_slave_sdo_write_exp8(slave, 0x4061, 4,  0) || // test mode
+        ecrt_slave_sdo_write_exp8(slave, 0x4066, 0,  1) || // dualcode
+        ecrt_slave_sdo_write_exp8(slave, 0x4067, 0,  5) || // 125kbaud
+        ecrt_slave_sdo_write_exp8(slave, 0x4068, 0,  0) || // single-turn
+        ecrt_slave_sdo_write_exp8(slave, 0x4069, 0, 25) || // frame size
+        ecrt_slave_sdo_write_exp8(slave, 0x406A, 0, 25) || // data length
+        ecrt_slave_sdo_write_exp16(slave, 0x406B, 0, 30000) // inhibit time in us
+        ) {
+        printk(KERN_ERR "Failed to configure SSI slave!\n");
+        goto out_deactivate;
+    }
+#endif
+
+#if 0
+    if (!(slave = ecrt_master_get_slave(master, "1:0"))) {
+        printk(KERN_ERR "Failed to get slave!\n");
+        goto out_deactivate;
+    }
+    if (ecrt_slave_write_alias(slave, 0x5678)) {
+        printk(KERN_ERR "Failed to write alias!\n");
+        goto out_deactivate;
+    }
+#endif
+
+#ifdef ASYNC
+    // Einmal senden und warten...
+    ecrt_master_prepare_async_io(master);
+#endif
+
+    ipipe_init_attr(&attr);
+    attr.name = "IPIPE-MSR-MODULE";
+    attr.priority = IPIPE_ROOT_PRIO + 1;
+    attr.entry = &domain_entry;
+    ipipe_register_domain(&this_domain, &attr);
+    return 0;
+
+#if 1
+ out_deactivate:
+    ecrt_master_deactivate(master);
+#endif
+ out_release_master:
+    ecrt_release_master(master);
+ out_msr_cleanup:
+    msr_rtlib_cleanup();
+ out_return:
+    return -1;
+}
+
+/*****************************************************************************/
+
+void __exit cleanup_rt_module(void)
+{
+    printk(KERN_INFO "Cleanign up rt module...\n");
+
+    ipipe_tune_timer(1000000000UL / HZ, 0); // Alten Timertakt wiederherstellen
+    ipipe_unregister_domain(&this_domain);
+
+    printk(KERN_INFO "=== Stopping EtherCAT environment... ===\n");
+    ecrt_master_deactivate(master);
+    ecrt_release_master(master);
+    printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");
+
+    msr_rtlib_cleanup();
+}
+
+/*****************************************************************************/
+
+#define EC_LIT(X) #X
+#define EC_STR(X) EC_LIT(X)
+#define COMPILE_INFO "Revision " EC_STR(SVNREV) \
+                     ", compiled by " EC_STR(USER) \
+                     " at " __DATE__ " " __TIME__
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
+MODULE_DESCRIPTION ("EtherCAT real-time test environment");
+MODULE_VERSION(COMPILE_INFO);
+
+module_init(init_rt_module);
+module_exit(cleanup_rt_module);
+
+/*****************************************************************************/
+
+/* Emacs-Konfiguration
+;;; Local Variables: ***
+;;; c-basic-offset:4 ***
+;;; End: ***
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/msr_unload	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,9 @@
+#!/bin/sh
+module="msr_rt"
+device="msr"
+
+# invoke rmmod with all arguments we got
+/sbin/rmmod $module $* || exit 1
+
+# Remove stale nodes
+rm -f /dev/${device} /dev/${device}0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/msrserv.pl	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,257 @@
+#!/usr/bin/perl -w
+
+#------------------------------------------------------------------------------
+#
+#  Copyright (C) 2006  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; version 2 of the License.
+#
+#  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
+#
+#------------------------------------------------------------------------------
+#
+#  Multithreaded Server
+#  according to the example from "Programming Perl"
+#  this code is improved according to the example from
+#  perldoc perlipc, so now safely being usable under Perl 5.8
+#  (see note (*))
+#
+#  works with read/write on a device-file
+#
+#------------------------------------------------------------------------------
+
+require 5.002;
+use strict;
+BEGIN { $ENV{PATH} = '/opt/msr/bin:/usr/bin:/bin' }
+use Socket;
+use Carp;
+use FileHandle;
+use Getopt::Std;
+
+use Sys::Syslog qw(:DEFAULT setlogsock);
+
+use vars qw (
+	     $self $pid $dolog $port $dev %opts $selfbase
+	     $len $offset $stream $written $read $log $blksize
+	     $instdir
+	     $authfile %authhosts
+	     );
+
+
+# Do logging to local syslogd by unix-domain socket instead of inetd
+setlogsock("unix");
+
+# Prototypes and some little Tools
+sub spawn;
+sub logmsg {
+  my ($level, $debug, @text) = @_;
+  syslog("daemon|$level", @text) if $debug > $dolog;
+#  print STDERR "daemon|$level", @text, "\n" if $dolog;
+}
+sub out {
+  my $waitpid = wait;
+  logmsg("notice", 2, "$waitpid exited");
+  unlink "$selfbase.pid";
+  exit 0;
+}
+
+sub help {
+  print "\n  usage: $0 [-l og] [-h elp] [-p port] [-d device]\n";
+  exit;
+}
+
+# Process Options
+%opts = (
+	 "l" => 1,
+	 "h" => 0,
+	 "p" => 2345,
+	 "d" => "/dev/msr"
+	 );
+
+getopts("lhp:d:", \%opts);
+
+help if $opts{"h"};
+
+( $self =  $0 ) =~ s+.*/++ ;
+( $selfbase = $self ) =~ s/\..*//;
+$log = "$selfbase.log";
+$dolog = $opts{"l"};
+$port = $opts{"p"};
+$dev = $opts{"d"};
+$blksize = 1024; # try to write as much bytes
+$instdir = "/opt/msr";
+$authfile = "$instdir/etc/hosts.auth";
+
+# Start logging
+openlog($self, 'pid');
+
+# Flush Output, dont buffer
+$| = 1;
+
+# first fork and run in background
+if ($pid = fork) {
+#  open LOG, ">$log" if $dolog;
+#  close LOG;
+  logmsg("notice", 2, "forked process: $pid\n");
+  exit 0;
+}
+
+# Server tells about startup success
+open (PID, ">/$instdir/var/run/$selfbase.pid");
+print PID "$$\n";
+close PID;
+
+# Cleanup on exit (due to kill -TERM signal)
+$SIG{TERM} = \&out;
+
+# We use streams
+my $proto = getprotobyname('tcp');
+
+# Open Server socket
+socket(Server, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
+setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
+  or die "setsocketopt: $!";
+bind (Server, sockaddr_in($port, INADDR_ANY))
+  or die "bind: $!";
+listen (Server, SOMAXCONN)
+  or die "listen: $!";
+
+%authhosts = ();
+# get authorized hosts
+open (AUTH, $authfile)
+  or logmsg ("notice", 2, "Could not read allowed hosts file: $authfile");
+while (<AUTH>) {
+    chomp;
+    my $host = lc $_;
+     if ($host =~ /^[\d\w]/) {
+	 $authhosts{$_} = 1;
+	 logmsg ("notice", 2, "Authorized host: >$host<");
+     }
+}
+close (AUTH);
+
+# tell about open server socket
+logmsg ("notice", 2, "Server started at port $port");
+
+my $waitedpid = 0;
+my $paddr;
+
+# wait for children to return, thus avoiding zombies
+# improvement (*)
+use POSIX ":sys_wait_h";
+sub REAPER {
+  my $child;
+  while (($waitedpid = waitpid(-1,WNOHANG)) > 0) {
+    logmsg ("notice", 2, "reaped $waitedpid", ($? ? " with exit $?" : ""));
+  }
+  $SIG{CHLD} = \&REAPER;  # loathe sysV
+}
+
+# also all sub-processes should wait for their children
+$SIG{CHLD} = \&REAPER;
+
+# start a new server for every incoming request
+# improvement (*) -- loop forever
+
+while ( 1 ) {
+  for ( $waitedpid = 0;
+	($paddr = accept(Client,Server)) || $waitedpid;
+	$waitedpid = 0, close Client ) {
+    next if $waitedpid and not $paddr;
+    my ($port, $iaddr) = sockaddr_in($paddr);
+    my $name = lc gethostbyaddr($iaddr, AF_INET);
+    my $ipaddr = inet_ntoa($iaddr);
+    my $n = 0;
+
+# tell about the requesting client
+    logmsg ("info", 2, "Connection from >$ipaddr< ($name) at port $port");
+
+    spawn sub {
+      my ($head, $hlen, $pos, $pegel, $typ, $siz, $nch, $nrec, $dat, $i, $j, $n, $llen); 
+      my ($watchpegel, $shmpegel);
+      my ($rin, $rout, $in, $line, $data_requested, $oversample);
+      my (@channels);
+
+#   to use stdio on writing to Client
+      Client->autoflush();
+
+#   Open Device
+      sysopen (DEV, "$dev", O_RDWR | O_NONBLOCK, 0666) or die("can't open $dev");
+
+#   Bitmask to check for input on stdin
+      $rin = "";
+      vec($rin, fileno(Client), 1) = 1;
+
+#   check for authorized hosts
+      my $access = 'deny';
+      $access = 'allow' if $authhosts{$ipaddr};
+      $line = "<remote_host host=\"$ipaddr\" access=\"$access\">\n";
+      logmsg ("info", 2, $line);
+      $len = length $line;
+      $offset = 0;
+      while ($len) {
+	$written = syswrite (DEV, $line, $len, $offset);
+	$len -= $written;
+	$offset += $written;
+      }
+
+      while ( 1 ) {
+	$in = select ($rout=$rin, undef, undef, 0.0); # poll client
+#     look for any Input from Client
+	if ($in) {
+#       exit on EOF
+	  $len = sysread (Client, $line, $blksize) or exit;
+	  logmsg("info", 0, "got $len bytes: \"$line\"");
+	  $offset = 0;
+#       copy request to device
+	  while ($len) {
+	    $written = syswrite (DEV, $line, $len, $offset);
+	    $len -= $written;
+	    $offset += $written;
+	  }
+	}
+#     look for some output from device
+	if ($len = sysread DEV, $stream, $blksize) {
+	  print Client $stream;
+	} else {
+	  select undef, undef, undef, 0.1; # calm down if nothing on device
+	}
+      }
+    };
+    logmsg("info", 2, "spawned\n");
+  }
+  logmsg("info", 2, "server loop\n");
+}
+
+sub spawn {
+  my $coderef = shift;
+
+  unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
+    confess "usage: spawn CODEREF";
+  }
+  my $pid;
+  if (!defined($pid = fork)) {
+    logmsg ("notice", 2, "fork failed: $!");
+    return;
+  } elsif ($pid) {
+    logmsg ("notice", 2, "Request $pid");
+    return; # Parent
+  }
+
+# do not use fdup as in the original example
+# open (STDIN, "<&Client") or die "Can't dup client to stdin";
+# open (STDOUT, ">&Client") or die "Can't dup client to stdout";
+# STDOUT->autoflush();
+  exit &$coderef();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/rt.conf.tmpl	Wed May 10 07:58:41 2006 +0000
@@ -0,0 +1,18 @@
+#------------------------------------------------------------------------------
+#
+#  Configuration file for msr realtime modules
+#
+#  $Id$
+#
+#  This file is a versioned template configuration. Copy it to "rt.conf"
+#  (which is ignored by Subversion) and adjust it to your needs.
+#
+#------------------------------------------------------------------------------
+
+# Module name (without extension)
+MODULENAME := ec_rt_sample
+
+# The kernel to compile the EtherCAT sources against
+KERNEL := `uname -r`
+
+#------------------------------------------------------------------------------
--- a/examples/rt/Makefile	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  Makefile
-#
-#  $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; version 2 of the License.
-#
-#  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
-#
-#------------------------------------------------------------------------------
-
-ifneq ($(KERNELRELEASE),)
-
-#------------------------------------------------------------------------------
-#  kbuild section
-#------------------------------------------------------------------------------
-
-ifneq ($(wildcard $(src)/rt.conf),)
-include $(src)/rt.conf
-else
-MODULENAME := rt
-endif
-
-obj-m := $(MODULENAME).o
-
-$(MODULENAME)-objs := msr_rt.o \
-			rt_lib/msr-core/msr_lists.o \
-			rt_lib/msr-core/msr_main.o \
-			rt_lib/msr-core/msr_charbuf.o \
-			rt_lib/msr-core/msr_reg.o \
-			rt_lib/msr-core/msr_interpreter.o \
-			rt_lib/msr-core/msr_messages.o \
-			rt_lib/msr-core/msr_proc.o \
-			rt_lib/msr-core/msr_error_reg.o \
-			rt_lib/msr-utils/msr_utils.o \
-			rt_lib/msr-utils/msr_time.o \
-			rt_lib/msr-math/msr_base64.o \
-			rt_lib/msr-math/msr_hex_bin.o \
-			libm.o
-
-EXTRA_CFLAGS := -I$(src)/rt_lib/msr-include -D_SIMULATION \
-		-I/usr/include -mhard-float \
-		-DSVNREV=$(shell svnversion $(src)) -DUSER=$(USER)
-
-#------------------------------------------------------------------------------
-
-else
-
-#------------------------------------------------------------------------------
-#  default section
-#------------------------------------------------------------------------------
-
-ifneq ($(wildcard rt.conf),)
-include rt.conf
-else
-MODULENAME := msr_rt
-KERNEL := $(shell uname -r)
-endif
-
-KERNELDIR := /lib/modules/$(KERNEL)/build
-
-modules:
-	$(MAKE) -C $(KERNELDIR) M=`pwd`
-
-clean:
-	$(MAKE) -C $(KERNELDIR) M=`pwd` clean
-
-install:
-	@./install.sh $(MODULENAME) $(KERNEL)
-
-#------------------------------------------------------------------------------
-
-endif
--- a/examples/rt/install.sh	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-#!/bin/sh
-
-#------------------------------------------------------------------------------
-#
-#  Realtime module install script
-#
-#  $Id: install.sh 5 2006-04-07 13:49:10Z fp $
-#
-#  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; version 2 of the License.
-#
-#  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
-#
-#------------------------------------------------------------------------------
-
-# Fetch parameters
-
-if [ $# -ne 2 ]; then
-    echo "Usage: $0 <MODULENAME> <KERNEL>"
-    exit 1
-fi
-
-MODULENAME=$1
-KERNEL=$2
-
-MODULESDIR=/lib/modules/$KERNEL/kernel/drivers/rt
-
-echo "Realtime installer"
-echo "  target: $MODULENAME"
-echo "  kernel: $KERNEL"
-
-# Create target directory
-
-if [ ! -d $MODULESDIR ]; then
-    echo "  creating $MODULESDIR..."
-    mkdir $MODULESDIR || exit 1
-fi
-
-# Install files
-
-echo "  installing $MODULENAME..."
-if ! cp $MODULENAME.ko $MODULESDIR/$MODULENAME.ko; then exit 1; fi
-
-# Calculate dependencies
-
-echo "  building module dependencies..."
-depmod
-
-# Finish
-
-echo "done."
-exit 0
-
-#------------------------------------------------------------------------------
--- a/examples/rt/libm.o_shipped	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-/usr/lib/libm.a
\ No newline at end of file
--- a/examples/rt/msr_load	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#!/bin/sh 
-module="msr_rt"
-device="msr"
-mode="664"
-
-# Group: since distributions do it differently, look for wheel or use staff
-if grep '^staff:' /etc/group > /dev/null; then
-    group="staff"
-else
-    group="wheel"
-fi
-
-# invoke insmod with all arguments we got
-# and use a pathname, as newer modutils don't look in . by default
-/sbin/insmod -f ./$module.ko $* || exit 1
-
-major=`cat /proc/devices | awk "\\$2==\"$device\" {print \\$1}"`
-
-echo $major
-# Remove stale nodes and replace them, then give gid and perms
-# Usually the script is shorter, it's scull that has several devices in it.
-
-rm -f /dev/${device}
-mknod /dev/${device} c $major 0
-# ln -sf ${device}0 /dev/${device}
-chgrp users /dev/${device}
-chmod $mode  /dev/${device}
-
-
-
-
-
-
-
-
-
--- a/examples/rt/msr_param.h	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/******************************************************************************
- *
- *  $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; version 2 of the License.
- *
- *  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
- *
- *****************************************************************************/
-
-#ifndef _MSR_PARAM_H_
-#define _MSR_PARAM_H_
-
-#define  MSR_ABTASTFREQUENZ 1000
-
-#endif
-
-/*****************************************************************************/
--- a/examples/rt/msr_rt.c	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/******************************************************************************
- *
- *  m s r _ r t . c
- *
- *  Kernelmodul für 2.6 Kernel zur Meßdatenerfassung, Steuerung und Regelung.
- *
- *  $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; version 2 of the License.
- *
- *  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
- *
- *****************************************************************************/
-
-// Linux
-#include <linux/module.h>
-#include <linux/ipipe.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-
-// RT_lib
-#include <msr_main.h>
-#include <msr_utils.h>
-#include <msr_messages.h>
-#include <msr_float.h>
-#include <msr_reg.h>
-#include <msr_time.h>
-#include "msr_param.h"
-
-// EtherCAT
-#include "../../include/ecrt.h"
-
-#define ASYNC
-
-// Defines/Makros
-#define HZREDUCTION (MSR_ABTASTFREQUENZ / HZ)
-
-/*****************************************************************************/
-/* Globale Variablen */
-
-// Adeos
-static struct ipipe_domain this_domain;
-static struct ipipe_sysinfo sys_info;
-
-// EtherCAT
-ec_master_t *master = NULL;
-ec_domain_t *domain1 = NULL;
-
-// Prozessdaten
-void *r_ssi;
-void *r_ssi_st;
-
-// KanŽäle
-uint32_t k_ssi;
-uint32_t k_ssi_st;
-
-ec_field_init_t domain1_fields[] = {
-    {&r_ssi,    "0:3", "Beckhoff", "EL5001", "InputValue", 0},
-    {&r_ssi_st, "0:3", "Beckhoff", "EL5001", "Status",     0},
-    {}
-};
-
-/*****************************************************************************/
-
-static void msr_controller_run(void)
-{
-#ifdef ASYNC
-    // Empfangen
-    ecrt_master_async_receive(master);
-    ecrt_domain_process(domain1);
-#else
-    // Senden und empfangen
-    ecrt_domain_queue(domain1);
-    ecrt_master_run(master);
-    ecrt_master_sync_io(master);
-    ecrt_domain_process(domain1);
-#endif
-
-    // Prozessdaten verarbeiten
-    k_ssi =    EC_READ_U32(r_ssi);
-    k_ssi_st = EC_READ_U8 (r_ssi_st);
-
-#ifdef ASYNC
-    // Senden
-    ecrt_domain_queue(domain1);
-    ecrt_master_run(master);
-    ecrt_master_async_send(master);
-#endif
-}
-
-/*****************************************************************************/
-
-int msr_globals_register(void)
-{
-    msr_reg_kanal("/ssi_position", "", &k_ssi,    TUINT);
-    msr_reg_kanal("/ssi_status",   "", &k_ssi_st, TUINT);
-    return 0;
-}
-
-/*****************************************************************************/
-
-void msr_run(unsigned irq)
-{
-    static int counter = 0;
-
-    MSR_ADEOS_INTERRUPT_CODE(msr_controller_run(); msr_write_kanal_list(););
-
-    ipipe_control_irq(irq, 0, IPIPE_ENABLE_MASK); // Interrupt bestŽätigen
-    if (++counter >= HZREDUCTION) {
-	ipipe_propagate_irq(irq);  // und weiterreichen
-	counter = 0;
-    }
-}
-
-/*****************************************************************************/
-
-void domain_entry(void)
-{
-    printk("Domain %s started.\n", ipipe_current_domain->name);
-
-    ipipe_get_sysinfo(&sys_info);
-    ipipe_virtualize_irq(ipipe_current_domain,sys_info.archdep.tmirq,
-			 &msr_run, NULL, IPIPE_HANDLE_MASK);
-
-    ipipe_tune_timer(1000000000UL / MSR_ABTASTFREQUENZ, 0);
-}
-
-/*****************************************************************************/
-
-int __init init_rt_module(void)
-{
-    struct ipipe_domain_attr attr; //ipipe
-#if 1
-    ec_slave_t *slave;
-#endif
-
-    // Als allererstes die RT-Lib initialisieren
-    if (msr_rtlib_init(1, MSR_ABTASTFREQUENZ, 10, &msr_globals_register) < 0) {
-        printk(KERN_ERR "Failed to initialize rtlib!\n");
-        goto out_return;
-    }
-
-    if ((master = ecrt_request_master(0)) == NULL) {
-        printk(KERN_ERR "Failed to request master 0!\n");
-        goto out_msr_cleanup;
-    }
-
-    //ecrt_master_print(master, 2);
-
-    printk(KERN_INFO "Creating domains...\n");
-    if (!(domain1 = ecrt_master_create_domain(master))) {
-        printk(KERN_ERR "Failed to create domains!\n");
-        goto out_release_master;
-    }
-
-    printk(KERN_INFO "Registering domain fields...\n");
-    if (ecrt_domain_register_field_list(domain1, domain1_fields)) {
-        printk(KERN_ERR "Failed to register domain fields.\n");
-        goto out_release_master;
-    }
-
-    printk(KERN_INFO "Activating master...\n");
-    if (ecrt_master_activate(master)) {
-        printk(KERN_ERR "Could not activate master!\n");
-        goto out_release_master;
-    }
-
-#if 0
-    if (ecrt_master_start_eoe(master)) {
-        printk(KERN_ERR "Failed to start EoE processing!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#if 0
-    if (ecrt_master_fetch_sdo_lists(master)) {
-        printk(KERN_ERR "Failed to fetch SDO lists!\n");
-        goto out_deactivate;
-    }
-    ecrt_master_print(master, 2);
-#else
-    ecrt_master_print(master, 0);
-#endif
-
-#if 1
-    if (!(slave = ecrt_master_get_slave(master, "0:3"))) {
-        printk(KERN_ERR "Failed to get slave!\n");
-        goto out_deactivate;
-    }
-
-    if (
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 1,  1) || // disable frame error bit
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 2,  0) || // power failure bit
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 3,  1) || // inhibit time
-        ecrt_slave_sdo_write_exp8(slave, 0x4061, 4,  0) || // test mode
-        ecrt_slave_sdo_write_exp8(slave, 0x4066, 0,  1) || // dualcode
-        ecrt_slave_sdo_write_exp8(slave, 0x4067, 0,  5) || // 125kbaud
-        ecrt_slave_sdo_write_exp8(slave, 0x4068, 0,  0) || // single-turn
-        ecrt_slave_sdo_write_exp8(slave, 0x4069, 0, 25) || // frame size
-        ecrt_slave_sdo_write_exp8(slave, 0x406A, 0, 25) || // data length
-        ecrt_slave_sdo_write_exp16(slave, 0x406B, 0, 30000) // inhibit time in us
-        ) {
-        printk(KERN_ERR "Failed to configure SSI slave!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#if 0
-    if (!(slave = ecrt_master_get_slave(master, "1:0"))) {
-        printk(KERN_ERR "Failed to get slave!\n");
-        goto out_deactivate;
-    }
-    if (ecrt_slave_write_alias(slave, 0x5678)) {
-        printk(KERN_ERR "Failed to write alias!\n");
-        goto out_deactivate;
-    }
-#endif
-
-#ifdef ASYNC
-    // Einmal senden und warten...
-    ecrt_master_prepare_async_io(master);
-#endif
-
-    ipipe_init_attr(&attr);
-    attr.name = "IPIPE-MSR-MODULE";
-    attr.priority = IPIPE_ROOT_PRIO + 1;
-    attr.entry = &domain_entry;
-    ipipe_register_domain(&this_domain, &attr);
-    return 0;
-
-#if 1
- out_deactivate:
-    ecrt_master_deactivate(master);
-#endif
- out_release_master:
-    ecrt_release_master(master);
- out_msr_cleanup:
-    msr_rtlib_cleanup();
- out_return:
-    return -1;
-}
-
-/*****************************************************************************/
-
-void __exit cleanup_rt_module(void)
-{
-    printk(KERN_INFO "Cleanign up rt module...\n");
-
-    ipipe_tune_timer(1000000000UL / HZ, 0); // Alten Timertakt wiederherstellen
-    ipipe_unregister_domain(&this_domain);
-
-    printk(KERN_INFO "=== Stopping EtherCAT environment... ===\n");
-    ecrt_master_deactivate(master);
-    ecrt_release_master(master);
-    printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");
-
-    msr_rtlib_cleanup();
-}
-
-/*****************************************************************************/
-
-#define EC_LIT(X) #X
-#define EC_STR(X) EC_LIT(X)
-#define COMPILE_INFO "Revision " EC_STR(SVNREV) \
-                     ", compiled by " EC_STR(USER) \
-                     " at " __DATE__ " " __TIME__
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
-MODULE_DESCRIPTION ("EtherCAT real-time test environment");
-MODULE_VERSION(COMPILE_INFO);
-
-module_init(init_rt_module);
-module_exit(cleanup_rt_module);
-
-/*****************************************************************************/
-
-/* Emacs-Konfiguration
-;;; Local Variables: ***
-;;; c-basic-offset:4 ***
-;;; End: ***
-*/
--- a/examples/rt/msr_unload	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#!/bin/sh
-module="msr_rt"
-device="msr"
-
-# invoke rmmod with all arguments we got
-/sbin/rmmod $module $* || exit 1
-
-# Remove stale nodes
-rm -f /dev/${device} /dev/${device}0
--- a/examples/rt/msrserv.pl	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-#!/usr/bin/perl -w
-
-#------------------------------------------------------------------------------
-#
-#  Copyright (C) 2006  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; version 2 of the License.
-#
-#  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
-#
-#------------------------------------------------------------------------------
-#
-#  Multithreaded Server
-#  according to the example from "Programming Perl"
-#  this code is improved according to the example from
-#  perldoc perlipc, so now safely being usable under Perl 5.8
-#  (see note (*))
-#
-#  works with read/write on a device-file
-#
-#------------------------------------------------------------------------------
-
-require 5.002;
-use strict;
-BEGIN { $ENV{PATH} = '/opt/msr/bin:/usr/bin:/bin' }
-use Socket;
-use Carp;
-use FileHandle;
-use Getopt::Std;
-
-use Sys::Syslog qw(:DEFAULT setlogsock);
-
-use vars qw (
-	     $self $pid $dolog $port $dev %opts $selfbase
-	     $len $offset $stream $written $read $log $blksize
-	     $instdir
-	     $authfile %authhosts
-	     );
-
-
-# Do logging to local syslogd by unix-domain socket instead of inetd
-setlogsock("unix");
-
-# Prototypes and some little Tools
-sub spawn;
-sub logmsg {
-  my ($level, $debug, @text) = @_;
-  syslog("daemon|$level", @text) if $debug > $dolog;
-#  print STDERR "daemon|$level", @text, "\n" if $dolog;
-}
-sub out {
-  my $waitpid = wait;
-  logmsg("notice", 2, "$waitpid exited");
-  unlink "$selfbase.pid";
-  exit 0;
-}
-
-sub help {
-  print "\n  usage: $0 [-l og] [-h elp] [-p port] [-d device]\n";
-  exit;
-}
-
-# Process Options
-%opts = (
-	 "l" => 1,
-	 "h" => 0,
-	 "p" => 2345,
-	 "d" => "/dev/msr"
-	 );
-
-getopts("lhp:d:", \%opts);
-
-help if $opts{"h"};
-
-( $self =  $0 ) =~ s+.*/++ ;
-( $selfbase = $self ) =~ s/\..*//;
-$log = "$selfbase.log";
-$dolog = $opts{"l"};
-$port = $opts{"p"};
-$dev = $opts{"d"};
-$blksize = 1024; # try to write as much bytes
-$instdir = "/opt/msr";
-$authfile = "$instdir/etc/hosts.auth";
-
-# Start logging
-openlog($self, 'pid');
-
-# Flush Output, dont buffer
-$| = 1;
-
-# first fork and run in background
-if ($pid = fork) {
-#  open LOG, ">$log" if $dolog;
-#  close LOG;
-  logmsg("notice", 2, "forked process: $pid\n");
-  exit 0;
-}
-
-# Server tells about startup success
-open (PID, ">/$instdir/var/run/$selfbase.pid");
-print PID "$$\n";
-close PID;
-
-# Cleanup on exit (due to kill -TERM signal)
-$SIG{TERM} = \&out;
-
-# We use streams
-my $proto = getprotobyname('tcp');
-
-# Open Server socket
-socket(Server, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
-setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
-  or die "setsocketopt: $!";
-bind (Server, sockaddr_in($port, INADDR_ANY))
-  or die "bind: $!";
-listen (Server, SOMAXCONN)
-  or die "listen: $!";
-
-%authhosts = ();
-# get authorized hosts
-open (AUTH, $authfile)
-  or logmsg ("notice", 2, "Could not read allowed hosts file: $authfile");
-while (<AUTH>) {
-    chomp;
-    my $host = lc $_;
-     if ($host =~ /^[\d\w]/) {
-	 $authhosts{$_} = 1;
-	 logmsg ("notice", 2, "Authorized host: >$host<");
-     }
-}
-close (AUTH);
-
-# tell about open server socket
-logmsg ("notice", 2, "Server started at port $port");
-
-my $waitedpid = 0;
-my $paddr;
-
-# wait for children to return, thus avoiding zombies
-# improvement (*)
-use POSIX ":sys_wait_h";
-sub REAPER {
-  my $child;
-  while (($waitedpid = waitpid(-1,WNOHANG)) > 0) {
-    logmsg ("notice", 2, "reaped $waitedpid", ($? ? " with exit $?" : ""));
-  }
-  $SIG{CHLD} = \&REAPER;  # loathe sysV
-}
-
-# also all sub-processes should wait for their children
-$SIG{CHLD} = \&REAPER;
-
-# start a new server for every incoming request
-# improvement (*) -- loop forever
-
-while ( 1 ) {
-  for ( $waitedpid = 0;
-	($paddr = accept(Client,Server)) || $waitedpid;
-	$waitedpid = 0, close Client ) {
-    next if $waitedpid and not $paddr;
-    my ($port, $iaddr) = sockaddr_in($paddr);
-    my $name = lc gethostbyaddr($iaddr, AF_INET);
-    my $ipaddr = inet_ntoa($iaddr);
-    my $n = 0;
-
-# tell about the requesting client
-    logmsg ("info", 2, "Connection from >$ipaddr< ($name) at port $port");
-
-    spawn sub {
-      my ($head, $hlen, $pos, $pegel, $typ, $siz, $nch, $nrec, $dat, $i, $j, $n, $llen); 
-      my ($watchpegel, $shmpegel);
-      my ($rin, $rout, $in, $line, $data_requested, $oversample);
-      my (@channels);
-
-#   to use stdio on writing to Client
-      Client->autoflush();
-
-#   Open Device
-      sysopen (DEV, "$dev", O_RDWR | O_NONBLOCK, 0666) or die("can't open $dev");
-
-#   Bitmask to check for input on stdin
-      $rin = "";
-      vec($rin, fileno(Client), 1) = 1;
-
-#   check for authorized hosts
-      my $access = 'deny';
-      $access = 'allow' if $authhosts{$ipaddr};
-      $line = "<remote_host host=\"$ipaddr\" access=\"$access\">\n";
-      logmsg ("info", 2, $line);
-      $len = length $line;
-      $offset = 0;
-      while ($len) {
-	$written = syswrite (DEV, $line, $len, $offset);
-	$len -= $written;
-	$offset += $written;
-      }
-
-      while ( 1 ) {
-	$in = select ($rout=$rin, undef, undef, 0.0); # poll client
-#     look for any Input from Client
-	if ($in) {
-#       exit on EOF
-	  $len = sysread (Client, $line, $blksize) or exit;
-	  logmsg("info", 0, "got $len bytes: \"$line\"");
-	  $offset = 0;
-#       copy request to device
-	  while ($len) {
-	    $written = syswrite (DEV, $line, $len, $offset);
-	    $len -= $written;
-	    $offset += $written;
-	  }
-	}
-#     look for some output from device
-	if ($len = sysread DEV, $stream, $blksize) {
-	  print Client $stream;
-	} else {
-	  select undef, undef, undef, 0.1; # calm down if nothing on device
-	}
-      }
-    };
-    logmsg("info", 2, "spawned\n");
-  }
-  logmsg("info", 2, "server loop\n");
-}
-
-sub spawn {
-  my $coderef = shift;
-
-  unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
-    confess "usage: spawn CODEREF";
-  }
-  my $pid;
-  if (!defined($pid = fork)) {
-    logmsg ("notice", 2, "fork failed: $!");
-    return;
-  } elsif ($pid) {
-    logmsg ("notice", 2, "Request $pid");
-    return; # Parent
-  }
-
-# do not use fdup as in the original example
-# open (STDIN, "<&Client") or die "Can't dup client to stdin";
-# open (STDOUT, ">&Client") or die "Can't dup client to stdout";
-# STDOUT->autoflush();
-  exit &$coderef();
-}
--- a/examples/rt/rt.conf.tmpl	Wed May 10 07:57:26 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  Configuration file for msr realtime modules
-#
-#  $Id$
-#
-#  This file is a versioned template configuration. Copy it to "rt.conf"
-#  (which is ignored by Subversion) and adjust it to your needs.
-#
-#------------------------------------------------------------------------------
-
-# Module name (without extension)
-MODULENAME := ec_rt_sample
-
-# The kernel to compile the EtherCAT sources against
-KERNEL := `uname -r`
-
-#------------------------------------------------------------------------------