Renamed rt example to msr.
--- /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`
-
-#------------------------------------------------------------------------------