# HG changeset patch # User Wilhelm Hagemeister # Date 1134720921 0 # Node ID 801dc7eabf517539215fc50f3cdf7087d559f215 # Parent d75ef6b46e331cc832ba763e1268bf296d7b6821 IPIPE,floatpoint,rtlib diff -r d75ef6b46e33 -r 801dc7eabf51 mini/ec_mini.c --- a/mini/ec_mini.c Fri Dec 02 15:35:21 2005 +0000 +++ b/mini/ec_mini.c Fri Dec 16 08:15:21 2005 +0000 @@ -255,9 +255,6 @@ #ifdef ECAT_CYCLIC_DATA printk("Starting cyclic sample thread.\n"); - schedule(); - mdelay(1000); - schedule(); init_timer(&timer); timer.function = run; diff -r d75ef6b46e33 -r 801dc7eabf51 rt/Makefile --- a/rt/Makefile Fri Dec 02 15:35:21 2005 +0000 +++ b/rt/Makefile Fri Dec 16 08:15:21 2005 +0000 @@ -1,64 +1,81 @@ -#---------------------------------------------------------------- -# -# Makefile -# -# EtherCAT-RT-Modul -# -# $Id$ -# -#---------------------------------------------------------------- +# Comment/uncomment the following line to disable/enable debugging +#DEBUG = y -CONFIG_FILE = ../ethercat.conf -ifeq ($(CONFIG_FILE),$(wildcard $(CONFIG_FILE))) -include $(CONFIG_FILE) +# Add your debugging flag (or not) to CFLAGS +ifeq ($(DEBUG),y) + DEBFLAGS = -O -g -DSHORT_DEBUG # "-O" is needed to expand inlines else -KERNELDIR = /vol/projekte/msr_messen_steuern_regeln/linux/kernel/2.4.20/include/linux-2.4.20.CX1100-rthal5 -RTAIDIR = /vol/projekte/msr_messen_steuern_regeln/linux/kernel/2.4.20/include/rtai-24.1.13 -RTLIBDIR = rt_lib + DEBFLAGS = -O2 endif -CFLAGS = -O2 -Wall -Wuninitialized -D__KERNEL__ -DMODULE -DSERIALDEBUG -DMSR_NO_PROC -I$(KERNELDIR)/include -D_RTAI -I$(RTAIDIR)/include -I$(RTLIBDIR)/msr-include +CFLAGS += $(DEBFLAGS) +CFLAGS += -I.. + +RTLIB = /vol/projekte/msr_messen_steuern_regeln/linux/kernel_space/rt_lib-4.0.0-2.6krnl #Suchpfad für die Dateien aus dem RT-Lib-Verzeichnis -VPATH = $(RTLIBDIR)/msr-core:$(RTLIBDIR)/msr-control:$(RTLIBDIR)/msr-math:$(RTLIBDIR)/msr-misc:$(RTLIBDIR)/msr-utils +VPATH := $(RTLIB)/msr-core:$(RTLIB)/msr-control:$(RTLIB)/msr-hwdriver:$(RTLIB)/msr-math:$(RTLIB)/msr-misc:$(RTLIB)/msr-utils -MODULE = msr_modul.o -SRC = msr_io.c -RTSRC = msr_main.c msr_lists.c msr_charbuf.c msr_reg.c msr_interpreter.c \ - msr_utils.c msr_messages.c msr_base64.c msr_proc.c msr_error_reg.c -ALLSRC = $(SRC) $(RTSRC) -OBJ = $(ALLSRC:.c=.o) +#Datei aus dem RT-Libverzeichnis für dies Projekt +RTSRC := msr_main.o msr_lists.o msr_charbuf.o msr_reg.o msr_interpreter.o msr_utils.o msr_messages.o msr_functiongen.o msr_base64.o msr_watchdog.o msr_proc.o msr_error_reg.o -#---------------------------------------------------------------- +ifneq ($(KERNELRELEASE),) +# call from kernel build system -all: .output_dirs .depend $(MODULE) Makefile -$(MODULE): $(OBJ) - @echo "Making module" - $(LD) -r $(OBJ) -o $@ +EXTRA_CFLAGS := -I$(RTLIB)/msr-include -D_SIMULATION -I/usr/include -mhard-float -.c.o: - @echo "Making obj $@" - $(CC) -c $(CFLAGS) $< -o $@ +#EXTRA_LDFLAGS := -L/usr/lib -lm -.output_dirs: - @echo "x-- Directories -------------" - @echo "| Kernel $(KERNELDIR)" - @echo "| RTAI $(RTAIDIR)" - @echo "| RT_lib $(RTLIBDIR)" - @echo "x----------------------------" +msr_modul-y := msr_module.o \ + msr_jitter.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-math/msr_base64.o \ + libm.o + + +obj-m := msr_modul.o + + + +else + + +KERNELDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) + + + + +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +endif + + +clean: + rm -f core .depend + rm -rf .tmp_versions + find -L -maxdepth 3 -name "*.o" -exec rm {} \; + find -L -maxdepth 3 -name "*~" -exec rm {} \; + find -L -maxdepth 3 -name "*.cmd" -exec rm {} \; + find -L -maxdepth 3 -name "*.ko" -exec rm {} \; + find -L -maxdepth 3 -name "*.mod.c" -exec rm {} \; depend .depend dep: - $(CC) $(CFLAGS) -M $(SRC) > .depend + $(CC) $(CFLAGS) -M *.c > .depend -clean: - rm -f *.o *~ core .depend -#---------------------------------------------------------------- ifeq (.depend,$(wildcard .depend)) include .depend endif - -#---------------------------------------------------------------- diff -r d75ef6b46e33 -r 801dc7eabf51 rt/msr_jitter.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/msr_jitter.c Fri Dec 16 08:15:21 2005 +0000 @@ -0,0 +1,185 @@ +/************************************************************************************************** +* +* msr_jitter.c +* +* +* Autor: Wilhelm Hagemeister +* +* (C) Copyright IgH 2002 +* Ingenieurgemeinschaft IgH +* Heinz-Bäcker Str. 34 +* D-45356 Essen +* Tel.: +49 201/61 99 31 +* Fax.: +49 201/61 98 36 +* E-mail: hm@igh-essen.com +* +* +* $RCSfile: msr_adeos_latency.c,v $ +* $Revision: 1.3 $ +* $Author: hm $ +* $Date: 2005/12/07 20:13:53 $ +* $State: Exp $ +* +* +* $Log: msr_adeos_latency.c,v $ +* Revision 1.3 2005/12/07 20:13:53 hm +* *** empty log message *** +* +* Revision 1.2 2005/12/07 15:56:13 hm +* *** empty log message *** +* +* Revision 1.1 2005/12/07 08:43:40 hm +* Initial revision +* +* Revision 1.5 2005/11/14 20:28:09 hm +* *** empty log message *** +* +* Revision 1.4 2005/11/13 10:34:07 hm +* *** empty log message *** +* +* Revision 1.3 2005/11/12 20:52:46 hm +* *** empty log message *** +* +* Revision 1.2 2005/11/12 20:51:27 hm +* *** empty log message *** +* +* Revision 1.1 2005/11/12 19:16:02 hm +* Initial revision +* +* Revision 1.13 2005/06/17 11:35:13 hm +* *** empty log message *** +* +* +* +* +**************************************************************************************************/ + +#ifndef __KERNEL__ +# define __KERNEL__ +#endif +#ifndef MODULE +# define MODULE +#endif + +#include +#include +#include +#include +#include /* maschine-specific registers */ +#include /* fuer HZ */ + +#include +#include "msr_jitter.h" + +/*--includes-------------------------------------------------------------------------------------*/ + + +/*--external functions---------------------------------------------------------------------------*/ + +/*--external data--------------------------------------------------------------------------------*/ + +/*--public data----------------------------------------------------------------------------------*/ + +/*--local data-----------------------------------------------------------------------------------*/ + +#define NUMCLASSES 16 + +static int jittime[NUMCLASSES]={0,1,2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000}; //in usec +static int jitcount[NUMCLASSES]; +static double jitpercent[NUMCLASSES]; + +static unsigned int tcount = 1; + + + +static void msr_jit_read(void) +{ + int i; + for(i=0;i100) { + jitpercent[i] = jitcount[i]*100.0/tcount; + } + } +} + +void msr_jitter_init(void) +{ + msr_reg_int_list("/Taskinfo/Jitter/Classes","usec",&jittime[0],MSR_R,NUMCLASSES,NULL,NULL,NULL); + msr_reg_int_list("/Taskinfo/Jitter/Count","",&jitcount[0],MSR_R,NUMCLASSES,NULL,NULL,NULL); + msr_reg_dbl_list("/Taskinfo/Jitter/percent","%",&jitpercent[0],MSR_R,NUMCLASSES,NULL,NULL,&msr_jit_read); +} + +/* +*************************************************************************************************** +* +* Function: msr_jitter_run +* +* Beschreibung: +* +* +* Parameter: Zeiger auf msr_data +* +* Rückgabe: +* +* Status: exp +* +*************************************************************************************************** +*/ + +void msr_jitter_run(unsigned int hz) { + + int i,hit; + static int firstrun = 1; + static int counter = 0; + static unsigned long k,j = 0; + unsigned int dt,jitter; + + + rdtscl(k); + + tcount++; + + //Zeitabstand zwischen zwei Interrupts in usec + + dt = ((unsigned long)(100000/HZ)*((unsigned long)(k-j)))/(current_cpu_data.loops_per_jiffy/10); + + jitter = (unsigned int)abs((int)dt-(int)1000000/hz); //jitter errechnet zum Sollabtastrate + + //in die Klassen einsortieren + if(!firstrun) { //das erste mal nicht einsortieren + hit = 0; + for(i=0;i=jittime[i] && jitter +#include + +#include +#include +#include +#include /* everything... */ +#include +#include +#include +#include /* fuer get_cycles */ +#include /* error codes */ +#include /* maschine-specific registers */ +#include /* fuer HZ */ +#include + +#include "msr_param.h" //wird im Projektverzeichnis erwartet + +//#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include "../drivers/ec_master.h" +#include "../drivers/ec_device.h" +#include "../drivers/ec_types.h" +#include "../drivers/ec_module.h" + +#include "msr_jitter.h" + +MODULE_AUTHOR("Wilhelm Hagemeister, Ingenieurgemeinschaft IgH"); +MODULE_LICENSE("GPL"); + +/*--external functions---------------------------------------------------------------------------*/ + +/*--external data--------------------------------------------------------------------------------*/ + +#define HZREDUCTION (MSR_ABTASTFREQUENZ/HZ) + +extern wait_queue_head_t msr_read_waitqueue; + +extern struct msr_char_buf *msr_kanal_puffer; + +extern int proc_abtastfrequenz; + +/*--public data----------------------------------------------------------------------------------*/ +/*--local data-----------------------------------------------------------------------------------*/ +//struct timer_list timer; + +extern struct timeval process_time; +struct timeval msr_time_increment; // Increment per Interrupt + +//adeos + +static struct ipipe_domain this_domain; + +static struct ipipe_sysinfo sys_info; + +static EtherCAT_master_t *ecat_master = NULL; + +static EtherCAT_slave_t ecat_slaves[] = +{ + + +#if 1 + // Block 1 + ECAT_INIT_SLAVE(Beckhoff_EK1100), + ECAT_INIT_SLAVE(Beckhoff_EL4102), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL3162), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL3102), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + + // Block 2 + ECAT_INIT_SLAVE(Beckhoff_EK1100), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL2004), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL1014), + ECAT_INIT_SLAVE(Beckhoff_EL1014) +#endif + +#if 1 + // Block 3 + ,ECAT_INIT_SLAVE(Beckhoff_EK1100), + ECAT_INIT_SLAVE(Beckhoff_EL3162), + ECAT_INIT_SLAVE(Beckhoff_EL3162), + ECAT_INIT_SLAVE(Beckhoff_EL3162), + ECAT_INIT_SLAVE(Beckhoff_EL3162), + ECAT_INIT_SLAVE(Beckhoff_EL3102), + ECAT_INIT_SLAVE(Beckhoff_EL3102), + ECAT_INIT_SLAVE(Beckhoff_EL3102), + ECAT_INIT_SLAVE(Beckhoff_EL3102), + + ECAT_INIT_SLAVE(Beckhoff_EL4102), + ECAT_INIT_SLAVE(Beckhoff_EL4102), + ECAT_INIT_SLAVE(Beckhoff_EL4102), + ECAT_INIT_SLAVE(Beckhoff_EL4102) + + +#endif +}; + +#define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t)) + +#define USE_MSR_LIB + +#ifdef USE_MSR_LIB +double value; +int dig1; +#endif + +/****************************************************************************** + * + * Function: next2004 + * + *****************************************************************************/ + + + +static int next2004(int *wrap) +{ + static int i = 0; + unsigned int j = 0; + + *wrap = 0; + + for (j = 0; j < ECAT_SLAVES_COUNT; j++) + { + i++; + + i %= ECAT_SLAVES_COUNT; + + if (i == 0) *wrap = 1; + + if (ecat_slaves[i].desc == Beckhoff_EL2004) + { + return i; + } + } + + return -1; +} + + +/****************************************************************************** + * + * Function: msr_controller_run() + * + *****************************************************************************/ + +static void msr_controller_run(void) +{ + static int ms = 0; + static int cnt = 0; + static unsigned long int k = 0; + static int firstrun = 1; + + static int klemme = 0; + static int kanal = 0; + static int up_down = 0; + int wrap = 0; + + + // Prozessdaten lesen + msr_jitter_run(MSR_ABTASTFREQUENZ); + + if (!firstrun) + { + EtherCAT_read_process_data(ecat_master); + + // Daten lesen und skalieren +#ifdef USE_MSR_LIB + value = EtherCAT_read_value(&ecat_master->slaves[5], 0) / 3276.0; + dig1 = EtherCAT_read_value(&ecat_master->slaves[2], 0); +#endif + } + else + klemme = next2004(&wrap); + + + ms++; + ms %= 1000; + if (cnt++ > 20) + { + cnt = 0; + + if (++kanal > 3) + { + kanal = 0; + klemme = next2004(&wrap); + + if (wrap == 1) + { + if (up_down == 1) up_down = 0; + else up_down = 1; + } + } + } + + if (klemme >= 0) { + EtherCAT_write_value(&ecat_master->slaves[klemme], kanal,up_down); + //printk("ECAT write: Klemme: %d, Kanal: %d, Wert: %d\n",klemme,kanal,up_down); + } + +#if 0 + EtherCAT_write_value(&ecat_master->slaves[13], 1, ms > 500 ? 0 : 1); + EtherCAT_write_value(&ecat_master->slaves[14], 2, ms > 500 ? 0 : 1); + EtherCAT_write_value(&ecat_master->slaves[15], 3, ms > 500 ? 1 : 0); +#endif + + // Prozessdaten schreiben + rdtscl(k); + EtherCAT_write_process_data(ecat_master); + firstrun = 0; + +} + +/* +*************************************************************************************************** +* +* Function: msr_run(_interrupt) +* +* Beschreibung: Routine wird zyklisch im Timerinterrupt ausgeführt +* (hier muß alles rein, was Echtzeit ist ...) +* +* Parameter: Zeiger auf msr_data +* +* Rückgabe: +* +* Status: exp +* +*************************************************************************************************** +*/ + + +void msr_run(unsigned irq) +{ + + static int counter = 0; +#ifdef USE_MSR_LIB + + timeval_add(&process_time,&process_time,&msr_time_increment); + + MSR_ADEOS_INTERRUPT_CODE( + msr_controller_run(); + msr_write_kanal_list(); + ); +#else + msr_controller_run(); +#endif + /* und wieder in die Timerliste eintragen */ + /* und neu in die Taskqueue eintragen */ +// timer.expires += 1; +// add_timer(&timer); + + ipipe_control_irq(irq,0,IPIPE_ENABLE_MASK); //nicht weiterreichen + if(counter++ > HZREDUCTION) { + ipipe_propagate_irq(irq); //wie lange braucht der Rest der Pipeline ?? + counter = 0; + } + + +} + +void domain_entry (int iflag) { + 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); + +} + +/* +******************************************************************************* +* +* Function: msr_register_channels +* +* Beschreibung: KanŽäle registrieren +* +* Parameter: +* +* RŽückgabe: +* +* Status: exp +* +******************************************************************************* +*/ + +int msr_globals_register(void) +{ +#ifdef USE_MSR_LIB + msr_reg_kanal("/value", "V", &value, TDBL); + msr_reg_kanal("/dig1", "", &dig1, TINT); +#endif +/* msr_reg_kanal("/Taskinfo/Ecat/TX-Delay","us",&ecat_tx_delay,TUINT); + msr_reg_kanal("/Taskinfo/Ecat/RX-Delay","us",&ecat_rx_delay,TUINT); + msr_reg_kanal("/Taskinfo/Ecat/TX-Cnt","",&tx_intr,TUINT); + msr_reg_kanal("/Taskinfo/Ecat/RX-Cnt","",&rx_intr,TUINT); + msr_reg_kanal("/Taskinfo/Ecat/Total-Cnt","",&total_intr,TUINT); +*/ + return 0; +} + + +/**************************************************************************************************** + * the init/clean material + ****************************************************************************************************/ + + +int __init init_module() +{ + int result = 0; + + struct ipipe_domain_attr attr; //ipipe + + //als allererstes die RT-lib initialisieren +#ifdef USE_MSR_LIB + result = msr_rtlib_init(1,MSR_ABTASTFREQUENZ,10,&msr_globals_register); + + if (result < 0) { + msr_print_warn("msr_modul: can't initialize rtlib!"); + return result; + } +#endif + + msr_jitter_init(); + printk(KERN_INFO "=== Starting EtherCAT environment... ===\n"); + + if ((ecat_master = EtherCAT_master(0)) == NULL) + { + printk(KERN_ERR "No EtherCAT master available!\n"); + msr_rtlib_cleanup(); + return -1; + } + + printk("Checking EtherCAT slaves.\n"); + + if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0) + { + printk(KERN_ERR "EtherCAT: Could not init slaves!\n"); + msr_rtlib_cleanup(); + return -1; + } + + printk("Activating all EtherCAT slaves.\n"); + + if (EtherCAT_activate_all_slaves(ecat_master) != 0) + { + printk(KERN_ERR "EtherCAT: Could not activate slaves!\n"); + msr_rtlib_cleanup(); + return -1; + } + + + do_gettimeofday(&process_time); + msr_time_increment.tv_sec=0; + msr_time_increment.tv_usec=(unsigned int)(1000000/MSR_ABTASTFREQUENZ); + + 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); + + //den Timertakt +/* + init_timer(&timer); + + timer.function = msr_run; + timer.data = 0; + timer.expires = jiffies+10; // Das erste Mal sofort feuern + add_timer(&timer); +*/ + return 0; /* succeed */ +} + + +//**************************************************************************** +void __exit cleanup_module() + +{ + msr_print_info("msk_modul: unloading..."); + + +// del_timer_sync(&timer); + ipipe_tune_timer(1000000000UL/HZ,0); //alten Timertakt wieder herstellen + + ipipe_unregister_domain(&this_domain); + + + + printk(KERN_INFO "=== Stopping EtherCAT environment... ===\n"); + + if (ecat_master) + { + EtherCAT_clear_process_data(ecat_master); + printk(KERN_INFO "Deactivating slaves.\n"); + EtherCAT_deactivate_all_slaves(ecat_master); + } + + printk(KERN_INFO "=== EtherCAT environment stopped. ===\n"); + +// msr_controller_cleanup(); +#ifdef USE_MSR_LIB + msr_rtlib_cleanup(); +#endif +} + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR ("Wilhelm Hagemeister "); +MODULE_DESCRIPTION ("EtherCAT test environment"); + +module_init(init_module); +module_exit(cleanup_module); + + + + + + + + + + + + + + + + diff -r d75ef6b46e33 -r 801dc7eabf51 rt/msr_param.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/msr_param.h Fri Dec 16 08:15:21 2005 +0000 @@ -0,0 +1,7 @@ +#ifndef _MSR_PARAM_H_ +#define _MSR_PARAM_H_ +#define MSR_ABTASTFREQUENZ 5000 //FIXME nur für den Simulator, der virtuelle 10 Mal schneller läuft ....HZ /* Abtastrate der Kan%/1€Œiso8859-15äle in [HZ]*/ + +#endif + + diff -r d75ef6b46e33 -r 801dc7eabf51 rt/msrserv.pl --- a/rt/msrserv.pl Fri Dec 02 15:35:21 2005 +0000 +++ b/rt/msrserv.pl Fri Dec 16 08:15:21 2005 +0000 @@ -1,18 +1,42 @@ #!/usr/bin/perl -w - +#------------------------------------------------------------ +# +# (C) Copyright +# Diese Software ist geistiges Eigentum der +# Ingenieurgemeinschaft IgH. Sie darf von +# Toyota Motorsport GmbH +# beliebig kopiert und veraendert werden. +# Die Weitergabe an Dritte ist untersagt. +# Dieser Urhebrrechtshinweis muss erhalten +# bleiben. +# +# Ingenieurgemeinschaft IgH +# Heinz-Baecker-Strasse 34 +# D-45356 Essen +# Tel.: +49-201/61 99 31 +# Fax.: +49-201/61 98 36 +# WWW: http://www.igh-essen.com +# Email: msr@igh-essen.com +# +#------------------------------------------------------------ +# # 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 # # $Revision: 1.1 $ -# $Date: 2002/07/09 10:10:59 $ +# $Date: 2004/10/01 16:00:42 $ # $RCSfile: msrserv.pl,v $ # +#------------------------------------------------------------ require 5.002; use strict; -BEGIN { $ENV{PATH} = '/usr/bin:/bin' } +BEGIN { $ENV{PATH} = '/opt/msr/bin:/usr/bin:/bin' } use Socket; use Carp; use FileHandle; @@ -23,6 +47,7 @@ use vars qw ( $self $pid $dolog $port $dev %opts $selfbase $len $offset $stream $written $read $log $blksize + $instdir $authfile %authhosts ); @@ -33,13 +58,13 @@ # Prototypes and some little Tools sub spawn; sub logmsg { - my ($level, @text) = @_; - syslog("daemon|$level", @text) if $dolog; + 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", "$waitpid exited"); + logmsg("notice", 2, "$waitpid exited"); unlink "$selfbase.pid"; exit 0; } @@ -68,7 +93,8 @@ $port = $opts{"p"}; $dev = $opts{"d"}; $blksize = 1024; # try to write as much bytes -$authfile = "/opt/kbw/etc/hosts.auth"; +$instdir = "/opt/msr"; +$authfile = "$instdir/etc/hosts.auth"; # Start logging openlog($self, 'pid'); @@ -80,12 +106,12 @@ if ($pid = fork) { # open LOG, ">$log" if $dolog; # close LOG; - logmsg("notice", "forked process: $pid\n"); + logmsg("notice", 2, "forked process: $pid\n"); exit 0; } # Server tells about startup success -open (PID, ">$selfbase.pid"); +open (PID, ">/$instdir/var/run/$selfbase.pid"); print PID "$$\n"; close PID; @@ -107,106 +133,122 @@ %authhosts = (); # get authorized hosts open (AUTH, $authfile) - or logmsg ("notice", "Could not read allowed hosts file: $authfile"); + or logmsg ("notice", 2, "Could not read allowed hosts file: $authfile"); while () { chomp; my $host = lc $_; - logmsg ("notice", "Authorized host: $host"); - $authhosts{$_} = 1 if $host =~ /^[\d\w]/; + if ($host =~ /^[\d\w]/) { + $authhosts{$_} = 1; + logmsg ("notice", 2, "Authorized host: >$host<"); + } } close (AUTH); # tell about open server socket -logmsg ("notice", "Server started at port $port"); - -my $waitpid = 0; +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 { - $waitpid = wait; - $SIG{CHLD} = \&REAPER; - logmsg ("notice", "reaped $waitpid", ($? ? " with exit $?" : "")); + 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 -for ( ; $paddr = accept(Client, Server); close (Client)) { - my ($port, $iaddr) = sockaddr_in($paddr); - my $name = lc gethostbyaddr($iaddr, AF_INET); - my $ipaddr = inet_ntoa($iaddr); - my $n = 0; - +# 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", "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); + 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(); - + Client->autoflush(); + # Open Device - sysopen (DEV, "$dev", O_RDWR | O_NONBLOCK, 0666) or die("can't open $dev"); - + 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; - + $rin = ""; + vec($rin, fileno(Client), 1) = 1; + # check for authorized hosts - my $access = 'allow'; - $access = 'allow' if $authhosts{$ipaddr}; - $line = "\n"; - $len = length $line; - $offset = 0; - while ($len) { + my $access = 'deny'; + $access = 'allow' if $authhosts{$ipaddr}; + $line = "\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 + } + + while ( 1 ) { + $in = select ($rout=$rin, undef, undef, 0.0); # poll client # look for any Input from Client - if ($in) { + if ($in) { # exit on EOF - $len = sysread (Client, $line, $blksize) or exit; - logmsg("info", "got $len bytes: \"$line\""); - $offset = 0; + $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; + 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 } } -# 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", "fork failed: $!"); + logmsg ("notice", 2, "fork failed: $!"); return; } elsif ($pid) { - logmsg ("notice", "Request $pid"); + logmsg ("notice", 2, "Request $pid"); return; # Parent } diff -r d75ef6b46e33 -r 801dc7eabf51 rt/rt_lib --- a/rt/rt_lib Fri Dec 02 15:35:21 2005 +0000 +++ b/rt/rt_lib Fri Dec 16 08:15:21 2005 +0000 @@ -1,1 +1,1 @@ -../../../linux/kernel_space/rt_lib-3.0.1-push \ No newline at end of file +../../../linux/kernel_space/rt_lib-4.0.0-2.6krnl \ No newline at end of file