From 7f0f17ccfa44279e0f795e2a9974e3b76cda1edb Mon Sep 17 00:00:00 2001 From: "Hadaq@CountingHouse" Date: Tue, 29 Oct 2013 11:52:30 +0100 Subject: [PATCH] added main dir --- README.txt | 4 +- control/gui/call_programs_local.sh | 2 +- control/gui/daq/10_Start_DAQ | 2 +- main/address_range.db | 26 + main/data_sources.db | 34 + main/designfiles.db | 28 + main/main_hades.script | 212 +++ main/new_startup.pl | 2035 ++++++++++++++++++++++++ main/restartEB.sh | 5 + main/serials_trb.db | 30 + main/startup.pl | 2305 ++++++++++++++++++++++++++++ main/startup_briccolage.sh | 362 +++++ main/subevtids.db | 35 + 13 files changed, 5076 insertions(+), 4 deletions(-) create mode 100644 main/address_range.db create mode 100644 main/data_sources.db create mode 100644 main/designfiles.db create mode 100644 main/main_hades.script create mode 100755 main/new_startup.pl create mode 100755 main/restartEB.sh create mode 100644 main/serials_trb.db create mode 100755 main/startup.pl create mode 100755 main/startup_briccolage.sh create mode 100644 main/subevtids.db diff --git a/README.txt b/README.txt index 83b9fe5..be2002f 100644 --- a/README.txt +++ b/README.txt @@ -8,13 +8,13 @@ tools control cts evtbuild +hub +main Directories to check: -hub -main mdc monitor oracle diff --git a/control/gui/call_programs_local.sh b/control/gui/call_programs_local.sh index 48966c3..0eeacd2 100755 --- a/control/gui/call_programs_local.sh +++ b/control/gui/call_programs_local.sh @@ -1,6 +1,6 @@ #!/bin/bash cd /home/hadaq/trbsoft/hadesdaq/control/gui/ -/home/hadaq/trbsoft/hadesdaqdaq/control/gui/call_programs2.pl -geometry -0-0 & +/home/hadaq/trbsoft/hadesdaq/control/gui/call_programs2.pl -geometry -0-0 & #cd /home/hadaq/trbsoft/daq/control/gui/ #/home/hadaq/trbsoft/daq/control/gui/call_programs.pl -geometry -0-0 diff --git a/control/gui/daq/10_Start_DAQ b/control/gui/daq/10_Start_DAQ index 7e72d28..4d716ac 100755 --- a/control/gui/daq/10_Start_DAQ +++ b/control/gui/daq/10_Start_DAQ @@ -11,7 +11,7 @@ xterm -geometry 80x24 -bg orange -fg black -e bash --login -c ' source /home/hadaq/.bash_profile echo \" Connected to lxhadesdaq...\" echo \" Starting DAQ with default settings...\" - cd /home/hadaq/trbsoft/hadesdaq/main/ + cd /home/hadaq/trbsoft/daq/main/ time bash ./startup_briccolage.sh sleep 10 " diff --git a/main/address_range.db b/main/address_range.db new file mode 100644 index 0000000..0eb5656 --- /dev/null +++ b/main/address_range.db @@ -0,0 +1,26 @@ +#System Min Max Type + +CTS 0x0001 0x00FF TRB +SCS 0x0100 0x01FF TRB +MDC-AddOn 0x1000 0x17FF MDC-AddOn +MDC-OEP 0x2000 0x2FFF MDC-OEP +RICH-ADCM 0x3000 0x31FF RICH-ADCM +Shw-AddOn 0x3200 0x37FF Shw-AddOn +Pion 0x3800 0x38FF TRB3 +StartVeto 0x4000 0x40FF TRB +Wall 0x4400 0x47FF TRB +RPC 0x4800 0x4BFF TRB +TOF 0x4C00 0x4FFF TRB +SEB 0x5555 0x5555 TRB +Central-Hub 0x8000 0x80FF Hub2 +MDC-Hub 0x8100 0x81FF Hub2 +RICH-Hub 0x8300 0x83FF Hub2 +RPC-Hub 0x8400 0x84FF Hub2 +Shw-Hub 0x8500 0x85FF Hub2 +TOF-Hub 0x8600 0x86FF Hub2 +Wall-Hub 0x8700 0x87FF Hub2 +CTS-Hub 0x8800 0x88FF Hub2 +TestSetup 0xF000 0xFEFF Test +Broadcast 0xFF00 0xFFFF Broadcast +Hub-All 0x8000 0x8FFF Hub2 + diff --git a/main/data_sources.db b/main/data_sources.db new file mode 100644 index 0000000..7e2234b --- /dev/null +++ b/main/data_sources.db @@ -0,0 +1,34 @@ +# Table with active data sources + +# Addr On/Off Name DataSize +#Start must be the first for EvtId +0x8800 1 StartVetoCTS low +0x8000 0 Central low #off +0x8100 0 innerMDC low #off +0x8110 0 outerMDC low #off +0x8300 1 RICH12 mid +0x8310 1 RICH34 mid +0x8320 1 RICH56 mid +0x8400 0 RPC123 mid +0x8410 0 RPC456 mid +0x8600 0 TOF low +0x8700 0 FW low +0x1000 0 MDC12sec1 high +0x1010 0 MDC12sec2 high +0x1020 0 MDC12sec3 mid +0x1030 0 MDC12sec4 mid +0x1040 0 MDC12sec5 high +0x1050 0 MDC12sec6 high +0x1100 0 MDC34sec1 high +0x1110 0 MDC34sec2 mid +0x1120 0 MDC34sec3 high +0x1130 0 MDC34sec4 mid +0x1140 0 MDC34sec5 high +0x1150 0 MDC34sec6 high +0x1160 0 MDCspecial mid #off +0x3200 0 Shower1 mid +0x3210 0 Shower2 mid +0x3220 0 Shower3 mid +0x3230 0 Shower4 mid +0x3240 0 Shower5 mid +0x3250 0 Shower6 mid diff --git a/main/designfiles.db b/main/designfiles.db new file mode 100644 index 0000000..f5c398d --- /dev/null +++ b/main/designfiles.db @@ -0,0 +1,28 @@ +# Design files and compile times to use for the different FPGA types +# The entries of this table will be referenced by the number in the "entry" column +# Between columns there are always at least two spaces! + + +# Entry # Board/FPGA # Compile Time # Filename # IPU Data verion # +########################################################################################################################################################## + 1 CTS - /home/hadaq/tof/hades_trb_tof_trbnet_a.stapl + 2 Hub2FPGA1 - /home/hadaq/hub/hub2_fpga1_single_20100302.stp + 3 Hub2FPGA1CTS - /home/hadaq/hub/hub2_fpga1_20100302.stp + 4 Hub2FPGA2 - /home/hadaq/hub/hub2_fpga2_single_20100302.stp + 5 Hub2FPGA2CTS - /home/hadaq/hub/hub2_mb_03032010_1303.stp + 6 TRBTOF - /home/hadaq/tof/hades_trb_tof_trbnet_a.stapl 1 + 7 TRBRPC - /home/hadaq/tof/hades_trb_rpc_trbnet_a.stapl 1 + 8 TRBSlwCtrl - /home/hadaq/etrax_fs/mdc_oep/stapl/trb2_control_20091030.stapl 1 + 9 MDCAddOn1FPGA1 - /home/hadaq/etrax_fs/mdc_oep/stapl/mdcopt_fpga1_20091027.stp 1 + 10 MDCAddOn1FPGA2 - /home/hadaq/etrax_fs/mdc_oep/stapl/mdcopt_fpga2_20091027.stp 1 + 11 MDCAddOn1FPGA3 - /home/hadaq/etrax_fs/mdc_oep/stapl/mdcopt_fpga3_20091027.stp 1 + 12 OEP 0x4AE5E2A6 /home/hadaq/etrax_fs/mdc_oep/stapl/mdc_oepb_20091026.bit 1 + 13 ShowerAddOnFPGA1 + 14 ShowerAddOnFPGA2 + 15 ShowerAddOnFPGA3 + 16 TRBFW - + 17 TRBStart + 18 RICHADCMv3 - + 19 MDCHubFpga1234 - + 20 MDCHubFpga5 - + 21 TRBVeto diff --git a/main/main_hades.script b/main/main_hades.script new file mode 100644 index 0000000..8130635 --- /dev/null +++ b/main/main_hades.script @@ -0,0 +1,212 @@ + +################################################# +# Read configuration +################################################# +read_eb_conf ../evtbuild/eb.conf +read_addrange_db ../main/address_range.db + +################################################# +#Load TRB database files +################################################# +!ifdef MDCTEST + read_trb_db ../mdc/trb.db +!endif + +!ifndef NOCTS + read_trb_db ../cts/trb.db +!endif + +!ifndef NORPC + read_trb_db ../rpc/trb.db +!endif + +!ifndef NOTOF + read_trb_db ../tof/trb.db +!endif + +!ifndef NOHUB + read_trb_db ../hub/trb.db +!endif + +!ifndef NOWALL + read_trb_db ../wall/trb.db +!endif + +!ifndef NOSTARTCTS #Contains both Start and Veto TRBs! + read_trb_db ../start/trb.db +!endif + +!ifndef NOSHOWER + read_trb_db ../shower/trb.db +!endif + +################################################# +#Load FPGA designs +################################################# + +!ifndef CONFIGONLY +# Program CTS,SCS,TOF FPGA + exec_cmd{local} echo "Programming TRB-FPGA" + exec_cmd{scs} jam_trbv2 --trb -aRUN_XILINX_PROC /home/hadaq/mdc_oepb/stapl/trb2_control_20101110.stapl + exec_cmd{wall} jam_trbv2 --trb -aRUN_XILINX_PROC /home/hadaq/tof/fpga/20120305_tof.stapl + exec_cmd{rpc} jam_trbv2 --trb -aRUN_XILINX_PROC /home/hadaq/rpc/fpga/20120323_rpc_a.stapl + exec_cmd{tof} jam_trbv2 --trb -aRUN_XILINX_PROC /home/hadaq/tof/fpga/20120305_tof.stapl + exec_cmd{start} jam_trbv2 --trb -aRUN_XILINX_PROC /home/hadaq/tof/fpga/20120305_tof.stapl + exec_cmd{veto} jam_trbv2 --trb -aRUN_XILINX_PROC /home/hadaq/tof/fpga/20120305_tof.stapl + wait + + # Program 1st AddOn FPGA + exec_cmd{local} echo "Programming FPGA1" + exec_cmd{hub} jam_trbv2 --addononly -aFP /home/hadaq/hub/hub2_fpga1_single_20110517.stp + exec_cmd{hubcts} jam_trbv2 --addon -aFP /home/hadaq/hub/hub2_fpga1_full_20110517.stp + exec_cmd{hubcentral} jam_trbv2 --addon -aFP /home/hadaq/hub/hub2_fpga1_full_20110517.stp + exec_cmd{cts} jam_trbv2 --addononly -aFP /home/hadaq/cts/20120410_cts_fpga1_only_etrax_a.stp + + exec_cmd{shower} jam_trbv2 --addon -aFP /home/hadaq/shower/shower_fpga1_20110808_a.stp #stable + wait + + # Program 2nd AddOn FPGA + exec_cmd{local} echo "Programming FPGA2" + exec_cmd{hub} jam_trbv2 --addononly -aFP /home/hadaq/hub/hub2_fpga2_single_20111121.stp #experimental + exec_cmd{hubcentral} jam_trbv2 --addon -aFP /home/hadaq/hub/hub2_fpga2_full_20110523.stp # leave this hub with old + exec_cmd{hubcts} jam_trbv2 --addon -aFP /home/hadaq/hub/hub2_fpga2_full_20111121.stp #experimental + exec_cmd{cts} jam_trbv2 --addononly -aFP /home/hadaq/cts/20120321_cts_fpga2_only_etrax_a.stp + exec_cmd{shower} jam_trbv2 --addon -aFP /home/hadaq/shower/shower_fpga2_20120214.stp #stable + wait + + # Program 3d AddOn FPGA + exec_cmd{local} echo "Programming FPGA3" + exec_cmd{shower} jam_trbv2 --addon -aFP /home/hadaq/shower/shower_fpga3_o_20110608_b.stp #stable +wait + + # Wait for links + exec_cmd{local} echo "---------Waiting 8 seconds for FPGAs to boot ----------------" + exec_cmd{local} sleep 8 + exec_cmd{local} echo "---------Programming finished. Starting Configuration----------" + wait + +!endif + + +!ifndef NORESET + exec_cmd{local} echo "network reset" + exec_cmd{local} trbcmd reset + wait + exec_cmd{local} sleep 1 + wait +!endif + + +################################################# +#Configuration via TrbNet +################################################# + + +#Hub boards + !ifndef NOHUB + wait + exec_cmd{con} echo "Configure Hubs" + exec_script{pexor} ../hub/startup.script + wait + !endif + + !ifndef MDCNOCOMPILETIME + exec_cmd{nofork} check_compile_time oep 0x4c3b2466 + !endif + + +#Configuration on TRBs + exec_cmd{con} echo "Configuring TDC on TRBs & BLR" + !ifndef NORPC + exec_script{rpc} ../rpc/configure_rpc.script + !endif + + !ifndef NOWALL + exec_script{wall} ../wall/configure_wall.script + !endif + + !ifndef NOSTARTCTS + exec_script{start} ../start/configure_startveto.script + !endif + + !ifndef NOTOF + exec_script{tof} ../tof/configure_tof.script + !endif + + + !ifndef NOCTS + exec_script{blr} ../cts/configure_blr.script + !endif + +#MDC + !ifndef NOMDC + exec_cmd{con} echo "Configure MDC" + exec_script{pexor} ../mdc/startup.script + !endif + +#RICH + !ifndef NORICH + exec_cmd{con} echo "Configure RICH" + exec_script{pexor} ../rich/startup.script + !endif + +wait + +#RPC + !ifndef NORPC + exec_script{local} ../rpc/startup.script + !endif + +#Shower + !ifndef NOSHOWER + exec_cmd{con} echo "Configure Shower" + exec_script{local} ../shower/startup.script + exec_script{pexor} ../shower/configure_shower.script + !endif + +#Wall + !ifndef NOWALL + exec_cmd{con} echo "Configure Wall" + exec_script{local} ../wall/startup.script + !endif + +#Start/Veto + !ifndef NOSTARTCTS + exec_cmd{local} echo "Configure Start/Veto" + exec_script{local} ../start/startup.script + !endif + +#TOF + !ifndef NOTOF + exec_cmd{local} echo "Configure TOF" + exec_script{local} ../tof/startup.script + !endif + +wait + +#Central boards / CTS / SCS + !ifndef NOCTS + exec_cmd{local} echo "Configure CTS" + exec_script{local} ../cts/startup.script + !endif + +exec_cmd{local} trbcmd w 0xffff 0x50 0 #Reset global time + +#Oracle + !ifndef NOORACLE + exec_cmd{con} echo "Writing Oracle files" + read_subevtids_db ../main/subevtids.db + wait + exec_cmd{local} daq2oracle + !endif + +exec_cmd{con} echo "---------Configuration finished. DAQ should have started.----------" + + + + + +######################### +#Old stuff follows +######################### + diff --git a/main/new_startup.pl b/main/new_startup.pl new file mode 100755 index 0000000..8aefb3e --- /dev/null +++ b/main/new_startup.pl @@ -0,0 +1,2035 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use FileHandle; +use File::Path; +use File::Basename; +use Data::Dumper; + +use IO::Socket; +use Net::Ping; + +use Config::Std; +use Carp qw( croak ); +use Scalar::Util qw(reftype); +use List::Util; +use List::MoreUtils qw(any apply); + +use threads; +use threads::shared; + +#use Clone qw(clone); + +#- the command line option flags +my $opt_help = 0; +my $opt_eb = 0; +my $opt_rdo = 0; +my $opt_test = 0; +my $opt_file = "../main/startup.script"; +my $opt_etrax = "etraxp058"; +my $opt_verb = 0; +my $opt_ora = "file"; +my $opt_iptabl = 0; +my @opt_macro; + +GetOptions ('h|help' => \$opt_help, + 'b|eb' => \$opt_eb, + 'r|rdo' => \$opt_rdo, + 'f|file=s' => \$opt_file, + 'e|etrax=s' => \$opt_etrax, + 'm|macro=s' => \@opt_macro, + 'v|verb' => \$opt_verb, + 'o|oracle=s' => \$opt_ora, + 'i|iptabl' => \$opt_iptabl, + 't|test' => \$opt_test); + +if( $opt_help ) { + &help(); + exit(0); +} + +my @subsys_array = ('mdc','rich','rpc','start','tof','wall','hub'); + +my $expect_script = "/tmp/remote_exec.exp"; +my $var_dir = "/var/diskless/etrax_fs"; +my $log_dir = "/tmp/log"; + +my $cmd_server = "./bin/command_server"; +my $cmd_server_port = 4712; +my $cmd_server_prtcl = 'tcp'; +my $cmd_server_answer = ""; + +my %addr_db_conf; # Hash with all addresses, serials, uids from DBs +my $addr_db_conf_href = \%addr_db_conf; +my @startup; # Array with all startup configuration +my $startup_aref = \@startup; +my %trb_hash; # Hash with TRBs for different subsystems +my $trb_href = \%trb_hash; +my %EB_Args; # Hash with EB args +my $EB_Args_href = \%EB_Args; +my @rdo; # Array with etrax names which run readout +my $rdo_aref = \@rdo; + +my %data2ora_hash; # Hash with data to be stored in Oracle +my $data2ora_href = \%data2ora_hash; + +my @subEvtIds; # Array with subevent Ids +my $subEvtIds_aref = \@subEvtIds; + +my %addressRange; # Hash with ranges of TRBNet addresses for each type of board +my $addressRange_href = \%addressRange; + +if( 0 != &checkArgs() ){ + print "Exit.\n"; + exit(1); +} + +#- Get local time in seconds since Epoch +my $seconds1 = time; + +&prepareForStartup(); +&cleanup(); + +&readScript($opt_file, 'local'); + +&checkConnection(); + +&blockTCP("scs") if($opt_iptabl); + +unless( $opt_eb ){ + &execViaCmdServer(); +} + +if( $opt_eb ){ + &buildEB(); + &startEB(); +} + +exit(0); + +################### END OF MAIN #################### + +sub help() +{ + print "\n"; + print << 'EOF'; +startup.pl + + This script starts readout via Command_Server running + on etrax boards. The script also starts Event Builder + to collect the data. + +Usage: + + Command line: startup.pl + [-h|--help] : Show this help. + [-f|--file ] : Path to main config file. + [-b|--eb] : Start event builder. + [-r|--rdo] : Start readout. + [-e|--etrax ] : Etrax name. + [-m|--macro ] : Macro names for preprocessing startup.script files. + Only !ifdef, !ifndef, !endif directives are defined. + !ifdef - by default exclude following cmds, + !ifndef - by default include following cmds. + [-o|--oracle ] : Write ascii files with info for Oracle (default: file). + [-i|--iptabl] : Block TCP on SlowCtrl board, except ports 23 (telnet) and 4712 (cmd_serv). + [-t|--test] : Test without execution. + [-v|--verb] : Verbose. + +Examples: + + Start MDC script with macros CALIB and INIT: + startup.pl -f ../mdc/startup.script -m CALIB -m INIT + +EOF +} + +sub checkArgs() +{ + my $retval = 0; + + if($opt_eb){ + print "Option -b is supposed to start EB. This option is disabled.\n"; + $retval = 1; + } + if($opt_rdo){ + print "Option -r is not implemented yet.\n"; + $retval = 1; + } + if( ! (-e $opt_file) ){ + print "File $opt_file does not exist.\n"; + $retval = 1; + } + + return $retval; +} + +sub prepareForStartup() +{ + + my $var_log_dir = $var_dir . "/tmp/log"; + &makeDir($var_log_dir); + + my $mode_dir = $log_dir . "/mode"; + &makeDir($mode_dir); + + #- Write expect script + &writeExpect(); +} + +sub makeDir() +{ + my ($dir) = @_; + + #- Make all needed dirs/subdirs + my @log_dir_list = split('/', $dir); + + my $dir2mk = ""; + foreach my $subdir (@log_dir_list){ + next unless( $subdir ); + + $dir2mk = $dir2mk . "/" . $subdir; + mkdir($dir2mk) or die $! unless( -d $dir2mk); + } +} + +sub cleanup() +{ + unless( $opt_eb ){ + system("rm $log_dir/log*.txt 2>/dev/null 2>/dev/null") unless($opt_test); + system("rm $log_dir/board_ids_for_oracle*.txt 2>/dev/null 2>/dev/null") unless($opt_test); + system("rm $log_dir/mode/* 2>/dev/null 2>/dev/null") unless($opt_test); + } +} + +sub writeExpect() +{ + # If command_server is not started on Etrax at boot time + # this expect script can be executed to start command_server. + + #! Look if /tmp dir exists + my $tmp_dir = dirname("/tmp"); + if ( !(-d $tmp_dir) ){ + print "\nCannot access /tmp directory!\nExit.\n"; + exit(1); + } + + my $expect_script_my = <0} { + set host [lindex \$argv 0] + set path [lindex \$argv 1] + set bin [lindex \$argv 2] + set opt [lindex \$argv 3] +} else { + send_user "Usage: \$argv0 host path binary options\\n" +} + +spawn telnet \$host +expect { + "error" { exit; } + "login:" { send "root\\r"; exp_continue; } + "Password:" { send "pass\\r" } +} + +set timeout 240 + +expect "# " +send "killall -9 \$bin\\r" +expect "# " +send "cd /home/hadaq/\\r" +expect "# " +send "\$path\$bin \$opt\\r" +expect "# " + +EOF + + my $fh = new FileHandle(">$expect_script"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$expect_script\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $expect_script_my; + $fh->close(); + + #- open permissions + system("chmod 755 $expect_script") unless($opt_test); +} + +sub getSubsysName() +{ + my ($script) = @_; + + my $subsys; + + if( $script =~ /..\/(\w+)\/(\w+).script/ ){ + $subsys = $1; + + die "getSubsysName(): Undefined subsystem: \'$script\'! Exit.\n" unless( defined $subsys ); + } + else{ + $subsys = 'main'; + } + + return $subsys; +} + +sub preprocess() +{ + my ($preproc, $line) = @_; + + my ($directive, $macro) = split(" ", $line); + + &preprocessCheck( $preproc, $directive ); + + if( $directive eq '!ifdef' && (any {lc($_) eq lc($macro)} @opt_macro) ){ + $preproc->{'ifdef'} = 'on'; + $preproc->{'skeepLine'} = 0; + + return 1; + } + elsif( $directive eq '!ifdef' ){ + #- No ifdef macros defined in cmd line => skeep next lines + $preproc->{'ifdef'} = 'on'; + $preproc->{'skeepLine'} = 1; + + return 1; + } + elsif( $directive eq '!ifndef' && (any {lc($_) eq lc($macro)} @opt_macro) ){ + $preproc->{'ifndef'} = 'on'; + $preproc->{'skeepLine'} = 1; + + return 1; + } + elsif( $directive eq '!ifndef' ){ + #- No ifndef macros defined in cmd line => include next lines + $preproc->{'ifndef'} = 'on'; + $preproc->{'skeepLine'} = 0; + + return 1; + } + elsif( $directive eq '!endif' ){ + $preproc->{'ifndef'} = 'off'; + $preproc->{'ifdef'} = 'off'; + $preproc->{'skeepLine'} = 0; + + return 1; + } + + return $preproc->{'skeepLine'}; +} + +sub preprocessInit() +{ + my %preproc = ( + 'ifdef' => 'off', + 'ifndef' => 'off', + 'skeepLine' => 0 + ); + + return \%preproc; +} + +sub preprocessCheck() +{ + my ($preproc, $directive) = @_; + + if( $directive eq '!ifdef' || $directive eq '!ifndef' ){ + unless( ($preproc->{'ifdef'} eq 'off') && + ($preproc->{'ifndef'} eq 'off') ){ + print "Encapsulated \'ifdef\'/\'ifndef\' are not supported. Each \'ifdef\'/\'ifndef\' must be closed with \'endif\' before next \'ifdef\'/\'ifndef\' can be opened.\n"; + exit(1); + } + } + elsif( $directive eq '!endif' ){ + if( ($preproc->{'ifdef'} eq 'on' && $preproc->{'ifndef'} eq 'on') || + ($preproc->{'ifdef'} eq 'off' && $preproc->{'ifndef'} eq 'off') ){ + print "The sequence of directives looks fishy. Each \'ifdef\'/\'ifndef\' must be closed with \'endif\' before next \'ifdef\'/\'ifndef\' can be opened.\n"; + exit(1); + } + } + elsif( $directive =~ /!(\w+)/ ){ + print "Unknown directive $directive. Exit.\n"; + exit(1); + } +} + +sub readTRBSetup() +{ + my ($trb_db) = @_; + + my $fh = new FileHandle("$trb_db", "r"); + + &isItDefined($fh, $trb_db); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my ($sys, $etrax, $rdo) = split(" ", $_); + + unless( defined $etrax ){ + print "Etrax is not defined in $trb_db for $sys! Exit\n"; + $fh->close; + exit(1); + } + + #- Add to a main configuration hash + push( @{$trb_href->{$sys}}, $etrax ); + + #- Add to a readout array for EB + if( defined $rdo && $rdo =~ /rdo/ ){ + push( @$rdo_aref, $etrax ); + } + } + + $fh->close; +} + +sub readAddressRangeSetup() +{ + my ($addressRange_db) = @_; + + my $fh = new FileHandle("$addressRange_db", "r"); + + &isItDefined($fh, $addressRange_db); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my ($sys, $min, $max, $type) = split(" ", $_); + + $min =~ s{ # Substitue... + 0x # ...hex zero + }{}gxms; # ...with nothing + + $max =~ s{ # Substitue... + 0x # ...hex zero + }{}gxms; # ...with nothing + + + unless( defined $sys && defined $min && + defined $max && defined $type){ + print "Something wrong with a format of $addressRange_db! Exit.\n"; + $fh->close; + exit(1); + } + + $addressRange_href->{$sys}->{'MIN'} = $min; + $addressRange_href->{$sys}->{'MAX'} = $max; + $addressRange_href->{$sys}->{'TYPE'} = $type; + } + + $fh->close; +} + +sub readSubevtIdsSetup() +{ + my ($subevt_db) = @_; + + my $fh = new FileHandle("$subevt_db", "r"); + + &isItDefined($fh, $subevt_db); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my $subevt; + + if( $_ =~ /0x(\w+)/ ){ + $subevt = $1; + } + else{ + print "Something wrong with a format of $subevt_db! Exit\n"; + $fh->close; + exit(1); + } + + #- Add to a config array + push( @$subEvtIds_aref, $subevt ); + } + + $fh->close; +} + +sub readScript() +{ + my ($script, $exec_sys) = @_; + + #- Extract subsystem name + my $subsys = &getSubsysName($script); + #print "script: $script, subsys: $subsys\n"; + + my $fh = new FileHandle("$script", "r"); + &isItDefined($fh, $script); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my ($cmd, @param) = split(" ", $_); + + &add2startup( $subsys, $exec_sys, $cmd, \@param ); + } + + $fh->close; +} + +sub add2startup(){ + + my ($subsys, $exec_sys, $cmd, $aref) = @_; + + die "add2startup(): one or more arguments are not defined! Exit.\n" + unless( defined $subsys && defined $exec_sys && defined $cmd && defined $aref); + + if( $cmd =~ /exec_script{(\w+)}/ ){ + my $exec_sys = $1; + + #- exec_script is followed only by one parameter [0]: script name + &readScript( $aref->[0], $exec_sys ); + } + elsif( $cmd =~ /exec_cmd{(\w+)}/){ + my $exec_sys = $1; + + my $args = &getArgs4cmd($aref, $subsys); + &push2array( \@startup, $exec_sys, $args ); + } + elsif( $cmd eq 'exec_cmd'){ + + my $args = &getArgs4cmd($aref, $subsys); + + &push2array( \@startup, $exec_sys, $args ); + } + elsif( $cmd eq 'wait'){ + + #- At this point we will wait for the forked children + push( @startup, {$cmd => ['-']} ); + } + elsif( $cmd eq 'trbcmd'){ + my $args = &getArgs4cmd($aref, $subsys); + my $cmd_line = "$cmd $args"; + + &push2array( \@startup, $exec_sys, $cmd_line ); + } + elsif( $cmd eq 'set_addresses' ){ + my $serials = $aref->[0]; + my $addresses = $aref->[1]; + + my $conf = $subsys . "-" . $cmd . "-" . $serials . ".conf"; + my $args = &makeAddressesConf( $subsys, $serials, $addresses, $conf ); + my $bash_script = "trbdhcp -f $args"; + + &push2array( \@startup, $exec_sys, $bash_script ); + } + elsif( $cmd eq 'load_register' ){ + my $register = $aref->[0]; + + my $conf = $subsys . "-" . $cmd . "-" . $register . ".conf"; + my $args = &makeRegisterConf( $subsys, $register, $conf ); + my $bash_script = "trbcmd -f $args"; + + &push2array( \@startup, $exec_sys, $bash_script ); + } + elsif( $cmd eq 'daqop' ){ + my $args = &getArgs4cmd($aref, $subsys); + my $bash_script = "$cmd $args"; + + &push2array( \@startup, $exec_sys, $bash_script ); + } + elsif( $cmd eq 'read_trb_db' ){ + #- Read database file with TRB setup + my $trb_db = $aref->[0]; + + &readTRBSetup( $trb_db ); + } + elsif( $cmd eq 'read_addrange_db' ){ + #- Read database file with TRBNet address ranges + my $addrRanges_db = $aref->[0]; + + &readAddressRangeSetup($addrRanges_db); + } + elsif( $cmd eq 'read_subevtids_db' ){ + #- Read database file with subevent Ids + my $subevt_db = $aref->[0]; + + &readSubevtIdsSetup( $subevt_db ); + } + elsif( $cmd eq 'read_eb_conf' ){ + #- Read config file with EB settings + my $eb_conf = $aref->[0]; + + read_config $eb_conf => %$EB_Args_href; + } + else{ + die "add2startup(): do not know what to do with command \'$cmd\' for subsystem \'$subsys\'! Exit.\n"; + } +} + +sub checkScript() +{ +} + +sub getArgs4cmd() +{ + my ($aref, $subsys) = @_; + + my $args = ""; + + if( $aref->[0] eq '-f' && defined $subsys ){ + my $conf = $aref->[1]; + system("cp ../$subsys/$conf $var_dir/tmp/.") unless($opt_test); + $args = "-f /home/hadaq/tmp/" . $conf; + } + else{ + for( my $i=0; $i < scalar (@{$aref}); $i++){ + $args = $args . " " . $aref->[$i]; + } + } + + return $args; +} + +sub isItDefined() +{ + my ($fh, $name) = @_; + + if(!$fh) { + my $txt = "\nError! Could not open file \'$name\'. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + return 0; +} + +sub isVarDefined() +{ + my ($var, $name) = @_; + + unless( defined $var ){ + print "$name is not defined! Exit.\n"; + exit(1); + } +} + +sub push2array() +{ + my ($aref, $exec_sys, $cmd) = @_; + + if( defined $aref->[-1] && defined $aref->[-1]->{$exec_sys} ){ + #- If last exec_sys equals current exec_sys + #- push current cmd to the same exe_sys + push( @{$aref->[-1]->{$exec_sys}}, $cmd ); + } + else{ + #- Unless create new entry in the main array + push( @$aref, {$exec_sys => [$cmd]} ); + } +} + +sub execViaCmdServer() +{ + my (@process_list); + + my $i = 1; + + #- Loop over subsystems + foreach my $href ( @$startup_aref ){ + + my ($exec_sys, $cmd_aref) = each ( %$href ); + + if( $exec_sys eq 'wait' ){ + $| = 1; # turn off stdout buffering + print "wait...\r"; + + #- Wait for the forked children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } + + &scanLogs(); + + next; + } + + print "exec: $exec_sys\n" unless( $exec_sys eq "local"); + + #- Loop over TRBs for given exec_sys + if( $exec_sys =~ /etrax/ ){ + #- Name of etrax is explicitly written in exec_cmd{} + # in main startup script. + if($opt_etrax){ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . "_" . $opt_etrax . ".txt"; + &forkMe( $cmd_aref, \@process_list, $opt_etrax, $log); + } + else{ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . ".txt"; + &forkMe( $cmd_aref, \@process_list, $exec_sys, $log); + } + } + elsif( $exec_sys eq 'local' ){ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . ".txt"; + &forkMe( $cmd_aref, \@process_list, $exec_sys, $log); + } + elsif( $exec_sys eq 'nofork' ){ + &execLocal($cmd_aref); + } + else{ + #- Loop over TRBs for a given subsys + foreach my $trb ( @{$trb_href->{$exec_sys}} ){ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . "_" . $trb . ".txt"; + &forkMe( $cmd_aref, \@process_list, $trb, $log); + } + } + + $i++; #increment log file index + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } +} + +sub execLocal() +{ + my ($cmd_aref) = @_; + + #- Loop over cmds to be executed on the local system + # without forking + foreach my $cmd ( @{$cmd_aref} ){ + $| = 1; # turn off stdout buffering + + if($cmd =~ /check_compile_time/){ + &checkCompileTime($cmd) unless($opt_test); + } + } +} + +sub forkMe() +{ + my ($cmd_aref, $proc_list, $etrax, $log) = @_; + + my $child = fork(); + + if( $child ){ # parent + push( @$proc_list, $child ); + } + elsif( $child == 0 ) { # child + exit(0) if($opt_test); + + if( $etrax eq "local" ){ + + #- Loop over cmds to be executed on the local system + foreach my $cmd ( @{$cmd_aref} ){ + $| = 1; # turn off stdout buffering + print "sleep...\r" if( $cmd =~ /sleep/ ); + + if($cmd =~ /daq2oracle/){ + &data2ora() unless($opt_test); + } + else{ + + #- Redirect STDOUT but not for 'echo' + unless($cmd =~ /echo/){ + open(STDOUT, ">$log") || die "Cannot redirect STDOUT"; + open(STDERR, ">&STDOUT") || die "Cannot dup STDERR"; + select STDERR; $| = 1; # make unbuffered + select STDOUT; $| = 1; # make unbuffered + } + + system("$cmd") unless($opt_test); + + unless($cmd =~ /echo/){ + close(STDOUT); + close(STDERR); + } + } + } + } + else{ + #- Connect to commandServer to exec commands on the remote systems + if( &connectCmdServer($cmd_aref, $etrax, $cmd_server_port, $cmd_server_prtcl, $log) ){ + #print "Something went wrong on commandServer side.\n"; + } + } + + exit(0); # exit child + } + else{ + print "Could not fork: $!\n"; + exit(1); + } +} + +sub blockTCP() +{ + my ($sys) = @_; + + my $host = @{$trb_href->{$sys}}[0]; # SlowCtrl Etrax name; + + my @blockCmd_list; + + push(@blockCmd_list, "iptables -A INPUT -p tcp --dport 23 -j ACCEPT"); + push(@blockCmd_list, "iptables -A INPUT -p tcp --dport 4712 -j ACCEPT"); + push(@blockCmd_list, "iptables -A INPUT -p tcp -j DROP"); + + $log = $log_dir . "/block_tcp_" . $host . ".log"; + + &connectCmdServer(\@blockCmd_list, $host, $cmd_server_port, $cmd_server_prtcl, $log); +} + +sub releaseTCP() +{ + my ($sys) = @_; + + my $host = @{$trb_href->{$sys}}[0]; # SlowCtrl Etrax name; + + my @releaseCmd_list; + + push(@releaseCmd_list, "iptables -D INPUT -p tcp -j DROP"); + push(@releaseCmd_list, "iptables -D INPUT -p tcp --dport 23 -j ACCEPT"); + push(@releaseCmd_list, "iptables -D INPUT -p tcp --dport 4712 -j ACCEPT"); + + $log = $log_dir . "/release_tcp_" . $host . ".log"; + + &connectCmdServer(\@releaseCmd_list, $host, $cmd_server_port, $cmd_server_prtcl, $log); +} + +sub connectCmdServer() +{ + my ($cmd, $remote_host, $remote_port, $protocol, $log) = @_; + + # '$cmd' can be a reference to an array of commands + # or just single command. In the first case, the commands + # from the array will be executed one after another. + + &isVarDefined( $cmd, "connectCmdServer(): cmd" ); + &isVarDefined( $remote_host, "connectCmdServer(): remote_host" ); + + my $fh = new FileHandle(">$log"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$log\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + my $answer; + my $retval = 1; + + my $socket = IO::Socket::INET->new(PeerAddr => $remote_host, + PeerPort => $remote_port, + Proto => $protocol, + Type => SOCK_STREAM) + or $answer = "ERROR: No response from Cmd Server at $remote_host:$remote_port\n"; + + unless( defined $answer ){ + $socket->autoflush(1); + print $socket "iamfromhadesdaq\n"; + $answer = <$socket>; + + &print2file($fh, $answer); + + my $reftype = reftype \$cmd; + + if( $reftype =~ /REF/ ){ + #- Loop over commands to be executed on etrax + foreach my $command ( @{$cmd} ){ + + $command = &cmdParam( $command, $remote_host ); + + print $socket "$command\n"; + &print2file( $fh, "===> $command\n" ); + + while ( <$socket> ) { + &print2file( $fh, $_ ); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + } + else{ + print $socket "$cmd\n"; + &print2file( $fh, "===> $cmd\n" ); + + while ( <$socket> ) { + &print2file( $fh, $_ ); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + + close($socket); + } + + if( $answer =~ /Connection accepted/ ){ + $retval = 0; + } + else{ + &print2file( $fh, $answer ); + } + + $fh->close(); + + return $retval; +} + +sub print2file() +{ + my ($fh, $toprint) = @_; + + if( defined $toprint ){ + print $fh $toprint; + + if( $opt_verb || $toprint =~ /ERROR/){ + print "$toprint\n"; + } + } +} + +sub cmdParam(){ + my ($cmd, $etrax) = @_; + + croak "cmdParam: undefined etrax name. Exit.\n" unless( defined $etrax ); + + my $trbnum = 0; #default + if( $etrax =~ /etraxp?(\d{3})/ || $etrax =~ /trb?\d(\d{2})/ ){ + $trbnum = $1; + } + else{ + croak "cmdParam: unexpected etrax name: $etrax. Exit.\n"; + } + + my $eb_port = $EB_Args_href->{'Main'}->{'PORT_BASE'} + $trbnum; + my $eb_ip = $EB_Args_href->{'Main'}->{'EB_IP'}; + + #- replace TRBNUM + $cmd =~ s{ # Substitue... + \${TRBNUM} # ...a parameter + } + {$trbnum}gxms; # Raplace it with a TRB number + + #- replace EBIP + $cmd =~ s{ # Substitue... + \${EBIP} # ...a parameter + } + {$eb_ip}gxms; # Raplace it with a EB IP + + #- replace EBPORT + $cmd =~ s{ # Substitue... + \${EBPORT} # ...a parameter + } + {$eb_port}gxms; # Raplace it with a EB PORT + + return $cmd; +} + +sub makeRegisterConf() +{ + my ($subsys, $register, $outConf) = @_; + + $register = "../" . $subsys . "/" . $register; + + my %reg_hash; + my $reg_href = \%reg_hash; + + my $fh = new FileHandle("$register", "r"); + &isItDefined($fh, $register); + + my $reg_table = 0; + my $val_table = 0; + my $ver_table = 0; + my %mb_type; #Motherboard type + my $mb_type = \%mb_type; + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Find which table we will read now + if(/^(\s+)?!Register\stable/){ + $reg_table = 1; + $val_table = 0; + $ver_table = 0; + next; + } + elsif(/^(\s+)?!Value\stable/){ + $reg_table = 0; + $val_table = 1; + $ver_table = 0; + next; + } + elsif(/^(\s+)?!Version\stable/){ + $reg_table = 0; + $val_table = 0; + $ver_table = 1; + next; + } + + if($reg_table){ + my ($type, @reg) = split(" ", $_); + my $reg = \@reg; + $mb_type->{$type} = $reg; + } + elsif($val_table){ + # We assume here that reg_table was before val_table + # thus mb_type hash is already filled at this point. + + my ($addr, $type, @val) = split(" ", $_); + + if( ! defined $mb_type->{$type} ){ + print "Error: Board type '$type' specified in 'Value table' in $register\n"; + print "is most likely not defined in 'Register table'! Exit.\n"; + $fh->close; + exit(1); + } + + my $arr_size = scalar @{ $mb_type->{$type} }; + + for(my $i=0; $i<$arr_size; $i++){ + my $reg = @{$mb_type->{$type}}[$i]; + my $val = $val[$i]; + + push(@{$reg_hash{$addr}}, {$reg => $val}); + } + } + elsif($ver_table){ + $data2ora_href->{"MDC"}->{"THRESH_VERS"} = $_; + } + } + + $fh->close; + + #--------------- Write config file + my $outConf_register = $var_dir . "/tmp/" . $outConf; + my $ret_register = "/home/hadaq/tmp/" . $outConf; + + $fh = new FileHandle(">$outConf_register"); + + foreach my $addr ( sort keys %{$reg_href} ){ + foreach my $ref (@{$reg_href->{$addr}}){ + my ($reg, $thr) = each( %{$ref} ); + + print $fh "w $addr $reg $thr\n"; + } + } + + $fh->close; + + return $ret_register; +} + +sub makeAddressesConf() +{ + my ($subsys, $serials, $addresses, $outConf) = @_; + + $serials = "../" . $subsys . "/" . $serials; + $addresses = "../" . $subsys . "/" . $addresses; + + my %trbdhcp_hash; + my $trbdhcp_href = \%trbdhcp_hash; + + #------------ Read addresses into trbdhcp hash + my $fh = new FileHandle("$addresses", "r"); + &isItDefined($fh, $addresses); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + my ($addr, $serial, $endpoint, $design) = split(" ", $_); + + #- All fields must be defined + next unless( defined $design && defined $addr && + defined $serial && defined $endpoint); + + #- Skip all lines with serial number zero + next if( $serial eq '0' ); + + #- Define uniqueu key + my $key = $addr . "_" . $endpoint; + + $trbdhcp_href->{$key}->{'addr'} = lc($addr); + $trbdhcp_href->{$key}->{'design'} = $design; + $trbdhcp_href->{$key}->{'endpoint'} = $endpoint; + $trbdhcp_href->{$key}->{'serial'} = $serial; + + } + + $fh->close; + + #------------ Read serials into trbdhcp hash + $fh = new FileHandle("$serials", "r"); + &isItDefined($fh, $serials); + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + my ($serial, $uid) = split(" ", $_); + + next unless( defined $serial && defined $uid ); + + #- Skip all lines with serial number zero + next if( $serial eq '0' ); + + foreach my $key ( keys %{$trbdhcp_href} ){ + + next unless( $serial eq $trbdhcp_href->{$key}->{'serial'} ); + $trbdhcp_href->{$key}->{'uid'} = lc($uid); + } + } + + $fh->close; + + #------------ Write config file for 'trbdhcp' + my $outConf_trbdhcp = $var_dir . "/tmp/" . $outConf; + my $ret_trbdhcp = "/home/hadaq/tmp/" . $outConf; + + $fh = new FileHandle(">$outConf_trbdhcp"); + + foreach my $key (sort keys %$trbdhcp_href) { + my $addr = $trbdhcp_href->{$key}->{'addr'}; + my $uid = $trbdhcp_href->{$key}->{'uid'}; + my $endpoint = $trbdhcp_href->{$key}->{'endpoint'}; + + next if( ! defined $addr || ! defined $uid || ! defined $endpoint); + + print $fh "$addr $uid $endpoint\n"; + } + + $fh->close; + + #--- Add this hash to a global hash + %addr_db_conf = (%addr_db_conf, %$trbdhcp_href); + + return $ret_trbdhcp; +} + +sub checkCompileTime() +{ + my ($cmd) = @_; + + my $sys; + my $compile_time; + + if($cmd =~ /check_compile_time\s+(\w+)\s+0x(\w+)/){ + $sys = lc($1); + $compile_time = hex($2); + } + + unless( defined $sys || defined $compile_time ){ + die "check_compile_time command must contain system and compile time as arguments! Exit.\n"; + } + + my $read_cmd = "daqop read compile time hex $sys"; + my @out = `$read_cmd`; + + my $oldCompileTime = 0; + + foreach my $line (@out){ + + next if($line =~ /Read compile time/ ); + + if( $line =~ /failed/ ){ + print "ERROR: when reading compile times of $sys: $line\n"; + &askUser(); + } + + my $local_time; + my $local_addr; + + if( $line =~ />\s+(\w+)\s+0x(\w+)/ ){ + $local_addr = lc($1); + $local_time = hex($2); + } + + unless( defined $local_addr || defined $local_time ){ + print "ERROR: unexpected output: $line\n from command: $read_cmd\n"; + &askUser(); + } + + if( defined $local_time && defined $local_addr){ + if( $local_time < $compile_time ){ + $oldCompileTime = 1; + print "Compile time for $sys $local_addr is too old!\n"; + } + } + } + + &askUser() if($oldCompileTime); +} + +sub askUser() +{ + my $answer = &promptUser("Continue?", "yes/no"); + if( $answer eq "no" || $answer eq "n" ){ + print "Exit.\n"; + &releaseTCP("scs"); + exit(0); + } + else{ + print "Continue...\n"; + } +} + +sub buildEB() +{ + my $numOfMsgs = 0; + my $netmem_input = ""; + + #- Loop over subsystems + foreach my $etrax ( @$rdo_aref ){ + + my $trbnum; + if( $etrax =~ /etraxp?0(\d{2})/ ){ + $trbnum = $1; + } + else{ + croak "buildEB: unexpected etrax name: $etrax. Exit.\n"; + } + + $numOfMsgs++; + my $port = $EB_Args_href->{'Main'}->{'PORT_BASE'} + $trbnum; + $netmem_input = $netmem_input . " -i UDP:0.0.0.0:" . $port; + } + + $EB_Args_href->{'Main'}->{'NETMEM_INPUT'} = $netmem_input; + $EB_Args_href->{'Main'}->{'MSGS'} = $numOfMsgs; +} + +sub startEB() +{ + my $cmd_eb = "daq_evtbuild" . + " -x " . $EB_Args_href->{'Main'}->{'EB_EXT'} . + " -d " . $EB_Args_href->{'Main'}->{'EB_OUTDEV'} . + " -o " . $EB_Args_href->{'Main'}->{'EB_OUTDIR'} . + " -m " . $EB_Args_href->{'Main'}->{'MSGS'} . + " -q " . $EB_Args_href->{'Main'}->{'QUEUESIZE'} . + " " . $EB_Args_href->{'Main'}->{'ONLINESERVER'} . + " -S " . $EB_Args_href->{'Main'}->{'SHMEMNAME'} . + " --filesize " . $EB_Args_href->{'Main'}->{'EB_FSIZE'}; + + if( defined $EB_Args_href->{'Main'}->{'EB_EVTID'} ){ + $cmd_eb = $cmd_eb . " -I " . $EB_Args_href->{'Main'}->{'EB_EVTID'}; + } + + + my $cmd_netmem = "daq_netmem" . + " -m " . $EB_Args_href->{'Main'}->{'MSGS'} . + " -q " . $EB_Args_href->{'Main'}->{'QUEUESIZE'} . + " -S " . $EB_Args_href->{'Main'}->{'SHMEMNAME'} . + $EB_Args_href->{'Main'}->{'NETMEM_INPUT'}; + + print "cmd_eb: $cmd_eb\n"; + print "cmd_netmem: $cmd_netmem\n"; + + system("xterm -T \"Event Builder\" -geometry 132x13+100+000 -e '$cmd_eb' &") unless($opt_test); + sleep 2; + system("xterm -T \"Net to Memory\" -geometry 132x40+100+200 -e '$cmd_netmem' &") unless($opt_test); +} + +sub checkConnection() +{ + + #----------- Check connection to hosts ------------- + print "Check connection to hosts...\n"; + + my @dead_hosts = (); + my @alive_hosts = (); + + &pingHosts(\@alive_hosts, \@dead_hosts); + + if( @dead_hosts ){ + print "Cannot connect to the following hosts:\n"; + + foreach my $host (@dead_hosts){ + + my $msg = "undef"; + if($host =~ /etraxp?(\d{3})/){ + my $serial = $1; + $msg = &serial2addrAndSysType($serial, "TRB"); + } + + print "$host $msg\n"; + } + + &askUser(); + } + else{ + print "Connection to hosts is OK.\n"; + } + + #---------- Check connection to command servers ------------- + print "Check connection to command servers...\n"; + + my @dead_cservers = (); + + &checkCmdServers(\@alive_hosts, \@dead_cservers); + + if( @dead_cservers ){ + print "Cannot connect to command servers for the hosts:\n"; + + foreach my $host (@dead_cservers){ + print "$host\n"; + } + + print "I will try to restart the command servers\n"; + + &restartCmdServers(\@dead_cservers); + + @dead_cservers = (); + + &checkCmdServers(\@alive_hosts, \@dead_cservers); + + if( @dead_cservers ){ + print "Still cannot connect to command servers for the hosts:\n"; + + foreach my $host (@dead_cservers){ + print "$host\n"; + } + + print "Try to start \'command_server -p 4712 &\' on these hosts by hand.\n"; + print "Exit.\n"; + exit(0); + } + else{ + print "Missing command_servers have been started! Continue...\n"; + sleep(2); + } + + } + else{ + print "Connection to command servers is OK.\n"; + } + + &rmDeadHosts(\@dead_hosts); +} + +sub rmDeadHosts() +{ + my ($dead_hosts_aref) = @_; + + #my $copy = clone($some_ref); + + foreach my $sys (%$trb_href){ + + next unless( defined @{$trb_href->{$sys}} && $#{$trb_href->{$sys}} > 0 ); + + foreach my $host (@$dead_hosts_aref){ + @{$trb_href->{$sys}} = grep { !($_ eq $host) } @{$trb_href->{$sys}}; + } + } +} + +#----------------------------( promptUser )----------------------------- +# +# FUNCTION: promptUser +# +# PURPOSE: Prompt the user for some type of input, and return the +# input back to the calling program. +# +# ARGS: $promptString - what you want to prompt the user with +# $defaultValue - (optional) a default value for the prompt +# +# EXAMPLES: +# $username = &promptUser("Enter the username "); +# $password = &promptUser("Enter the password "); +# $homeDir = &promptUser("Enter the home directory ", "/home/$username"); +# print "$username, $password, $homeDir\n"; +# +#------------------------------------------------------------------------- + +sub promptUser { + + # two possible input arguments - $promptString, and $defaultValue + # make the input arguments local variables. + + my ($promptString,$defaultValue) = @_; + + # if there is a default value, use the first print statement; if + # no default is provided, print the second string. + + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + my $input = ; # get the input from STDIN (presumably the keyboard) + + # remove the newline character from the end of the input the user gave us + + chomp($input); + + # if we had a $default value, and the user gave us input, then + # return the input; if we had a default, and they gave us no + # no input, return the $defaultValue. + # + # if we did not have a default value, then just return whatever + # the user gave us. if they just hit the key, + # the calling routine will have to deal with that. + + if ("$defaultValue") { + return $input ? $input : $defaultValue; # return $input if it has a value + } else { + return $input; + } +} + +sub pingHosts() +{ + my ($alive_hosts_aref, $dead_hosts_aref) = @_; + + my @thread_list = (); + + foreach my $sys (%$trb_href){ + foreach my $host ( @{$trb_href->{$sys}} ){ + push(@thread_list, threads->new( \&pingHost, $host)); + } + } + + #- Join threads + my $retcode; + + foreach my $t (@thread_list){ + $retcode = $t->join(); + + next if($retcode eq -1); + + my ($host, $hstat) = split(/:/, $retcode); + + if( $hstat eq "alive" ){ + push( @$alive_hosts_aref, $host ); + } + elsif( $hstat eq "dead" ){ + push( @$dead_hosts_aref, $host ); + } + else{ + print "ping $host returned unknown status: $hstat. Exit.\n"; + exit(0); + } + } +} + +sub pingHost() +{ + my ($host) = @_; + + my $retval; + + my $p = Net::Ping->new(); + + if( $p->ping($host) ){ + $retval = "$host:alive"; + } + else{ + $retval = "$host:dead"; + } + + $p->close(); + + return $retval; +} + +sub checkCmdServers() +{ + my ($alive_hosts_aref, $dead_cservers_aref) = @_; + + foreach my $host (@$alive_hosts_aref){ + my $sock = new IO::Socket::INET ( + PeerAddr => $host, + PeerPort => $cmd_server_port, + Proto => 'tcp'); + push( @$dead_cservers_aref, $host ) unless $sock; + close($sock) if( defined $sock ); + } +} + +sub execViaExpect() +{ + my ($etrax, $path, $cmd, $args, $log) = @_; + + my $exe = "$expect_script $etrax $path $cmd $args > $log 2>&1"; + print "exe: $exe\n" if($opt_verb); + system($exe) unless($opt_test); +} + +sub restartCmdServers() +{ + my ($dead_cservers_aref) = @_; + + my $path = "/home/hadaq/bin/"; + + foreach my $host (@$dead_cservers_aref){ + my $log = $log_dir . "/expect_" . $host . ".log"; + &execViaExpect( $host, $path, "command_server", "\'-p 4712 &\'", $log); + } +} + +sub data2ora() +{ + my @id_list = `daqop read ids`; + + foreach my $id_line (@id_list){ + + if( $id_line =~ /failed/ ){ + print "ERROR: data2ora(): 'daqop read ids' failed! Exit.\n"; + exit(1); + } + + #- Match the string: Jun 10 16:47:08 CEST 2010 + if( $id_line =~ /0x(\w+)\s+0x(\w+)\s+0x(\w+)/ ){ + my $addr = lc($1); + my $uid = lc($2); + my $fpga = $3; + + #- There are boards with several FPGAs + # These boards have identical Ids but several different + # trbnet addresses (three addresses for the board with three FPGAs) + # The smallest address is of importance for us because it is an address + # of FPGA which sends the data out (uplink). Thus the smallest + # address is the address of the data source. + if( defined $data2ora_href->{"BOARDID"}->{$uid} ){ + if( $addr < $data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'} ){ + $data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'} = $addr; + } + } + else{ + $data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'} = $addr; + } + } + } + + #-------- Write data to a file to be passed to Oracle + + my $timestamp = &timeStamp(); + my $ora_file = "/home/hadaq/oper/daq2ora/daq2ora_" . $timestamp . ".txt"; + my $current_file = "/home/hadaq/oper/daq2ora/daq2ora_current.txt"; + + #- Read settings with resolution mode of TRBs + my $TDCsettings_href = &readTRBTDCsettings(); + + open( FILE, '>', $ora_file ) or die "Could not open $ora_file: $!" if($opt_ora eq "file"); + + foreach my $uid ( sort keys %{$data2ora_href->{"BOARDID"}} ){ + my $addr = $data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'}; + my $subevtid; + + if( any {lc($_) eq lc($addr)} @subEvtIds ){ + $subevtid = lc($addr); + } + else{ + $subevtid = "NULL"; + } + + #- Get TRB resolution mode (returns 0 if the board is not TRB) + my $mode = &getTRBResolutionMode($TDCsettings_href, lc($addr)); + + my $outdata = sprintf("%19s %6s %6s %4s", $uid, $addr, $subevtid, $mode); + + print "data2ora: $outdata\n" if($opt_ora eq "file" && $opt_verb); + print FILE "$outdata\n" if($opt_ora eq "file"); + + unless( $mode eq "NULL" ){ + my $cmd = "/home/hadaq/scripts/set_modrc.sh 0x$mode 0x$addr 0xa0c2"; + my $host = @{$trb_href->{"scs"}}[0]; # SlowStrl Etrax name; + my $log = $log_dir . "/mode/modrc_" . $host . ".log"; + &connectCmdServer($cmd, $host, $cmd_server_port, $cmd_server_prtcl, $log); + } + } + + if( defined $data2ora_href->{"MDC"}->{"THRESH_VERS"} ){ + my $var = $data2ora_href->{"MDC"}->{"THRESH_VERS"}; + print FILE "mdc_thresh_version $var\n" if($opt_ora eq "file"); + } + + if( defined $data2ora_href->{"MDC"}->{"TDCMASK_VERS"} ){ + my $var = $data2ora_href->{"MDC"}->{"TDCMASK_VERS"}; + print FILE "mdc_tdcmask_version $var\n" if($opt_ora eq "file"); + } + + close( FILE ) or die "Could not close $ora_file: $!" if($opt_ora eq "file"); + + system("cp $ora_file $current_file") if($opt_ora eq "file"); +} + +sub readTRBTDCsettings() +{ + #-------- Read TRB TDC settings + my $config_file = "/var/diskless/etrax_fs/trbtdctools/config/TRB_TDC_settings.conf"; + + my $TDCsettings_href; + + unless( $TDCsettings_href = do $config_file ){ + die "Couldn't parse $config_file: $@, stopped" if $@; + die "Couldn't do $config_file: $!, stopped" unless defined $TDCsettings_href; + die "Couldn't run $config_file, stopped" unless $TDCsettings_href; + } + + return $TDCsettings_href; +} + +sub getTRBResolutionMode() +{ + my ($TDCsettings_href, $addr) = @_; + + my $mode; + + my $board_type = &boardType(lc($addr)); + + if( $board_type eq "TRB" && (&excludeBoards($addr)) ){ + my $serial = &addr2serial(lc($addr)); + $mode = &resMode($TDCsettings_href, $serial); + } + else{ + $mode = "NULL"; + } + + return $mode; +} + +sub resMode() +{ + my ($TDCsettings_href, $serial) = @_; + + my $trbname = sprintf("TRB_%03d", $serial); + + my $mrcc_a = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_A'}->{'mode_rc_compression'}; + my $mrc_a = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_A'}->{'mode_rc'}; + my $mrcc_b = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_B'}->{'mode_rc_compression'}; + my $mrc_b = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_B'}->{'mode_rc'}; + my $mrcc_c = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_C'}->{'mode_rc_compression'}; + my $mrc_c = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_C'}->{'mode_rc'}; + my $mrcc_d = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_D'}->{'mode_rc_compression'}; + my $mrc_d = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_D'}->{'mode_rc'}; + + my $mode_undefined = 0; + + unless( defined $mrcc_a ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_A: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_a ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_A: mode_rc is not defined! Exit.\n"; + } + unless( defined $mrcc_b ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_B: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_b ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_B: mode_rc is not defined! Exit.\n"; + } + unless( defined $mrcc_c ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_C: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_c ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_C: mode_rc is not defined! Exit.\n"; + } + unless( defined $mrcc_d ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_D: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_d ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_D: mode_rc is not defined! Exit.\n"; + } + + #- All four TDCs must have identical modes + unless( $mrcc_a == $mrcc_b && $mrcc_a == $mrcc_c && $mrcc_a == $mrcc_d && + $mrc_a == $mrc_b && $mrc_a == $mrc_c && $mrc_a == $mrc_d ){ + print "ERROR: $trbname, resolution modes must be identical for all four TDCs! Exit.\n"; + } + + if( $mode_undefined ){ + exit(1); + } + + # Description of the resolution modes: + # + # mrcc = mode_rc_compression + # mrc = mode_rc + # + # mrcc mrc mode + # 0 0 00 - high resolution mode (100ps binning) + # 1 1 01 - very high resolution mode (25ps binning) + # 0 1 02 - very high resolution mode calibration data + # (one hit produces 4 data words like in high resolution mode) + + my $mode; + + if( $mrcc_a eq "0" && $mrc_a eq "0" ){ + $mode = "00"; + } + elsif( $mrcc_a eq "1" && $mrc_a eq "1" ){ + $mode = "01"; + } + elsif( $mrcc_a eq "0" && $mrc_a eq "1" ){ + $mode = "02"; + } + else{ + print "ERROR: $trbname, resolution modes have wrong values! Exit.\n"; + } + + return $mode; +} + +sub addr2serial() +{ + my ($addr) = @_; + + my $serial; + + my $addr_hex = "0x" . lc($addr); + + foreach my $key ( keys %$addr_db_conf_href ){ + if( $addr_db_conf_href->{$key}->{'addr'} eq $addr_hex ){ + unless( defined $addr_db_conf_href->{$key}->{'serial'} ){ + next; + } + + $serial = $addr_db_conf_href->{$key}->{'serial'}; + last; + } + } + + unless( defined $serial ){ + print "ERROR: addr2serial(): unknown serial number for address $addr. Exit.\n"; + exit(1); + } + + return $serial; +} + +sub serial2addrAndSysType() +{ + my ($serial, $board_type) = @_; + + # There is no direct connection between serial number + # and TRB-Net address. One should provide board type + # in addtion to serial number. + + my $addr; + my $bType; + my $bSysType; + + foreach my $key ( keys %$addr_db_conf_href ){ + next unless( defined $addr_db_conf_href->{$key}->{'serial'} ); + + if( $addr_db_conf_href->{$key}->{'serial'} eq $serial ){ + unless( defined $addr_db_conf_href->{$key}->{'addr'} ){ + next; + } + + $addr = $addr_db_conf_href->{$key}->{'addr'}; + + &boardSysType($addr, \$bType, \$bSysType); + + next unless($bType eq $board_type); + + last; + } + } + + unless( defined $addr ){ + print "ERROR: serial2addr(): unknown address for serial number $serial. Exit.\n"; + exit(1); + } + + unless( defined $bSysType ){ + print "ERROR: serial2addr(): unknown board system type for serial number $serial. Exit.\n"; + exit(1); + } + + my $retval = "addr: $addr type: $bSysType"; + + return $retval; +} + +sub excludeBoards() +{ + my ($addr) = @_; + + # This subroutine excludes boards which have unused TDCs + # and those TDCs must not be configured. Moreover the corresponding + # register should not be overwritten with TDC resoltuion mode value. + + # Exclude all CTS and SCS boards + my $board_sys; + my $retval = 1; + + foreach my $sys ( keys %$addressRange_href ){ + my $addr_min = lc($addressRange_href->{$sys}->{'MIN'}); + my $addr_max = lc($addressRange_href->{$sys}->{'MAX'}); + + if( hex(lc($addr)) >= hex($addr_min) && hex(lc($addr)) <= hex($addr_max) ){ + $board_sys = $addressRange_href->{$sys}; + last; + } + } + + unless( defined $board_sys ){ + print "TRB-Net address $addr is outside of the known address ranges! Exit.\n"; + exit(0); + } + + if( $board_sys eq "CTS" || $board_sys eq "SCS" ){ + $retval = 0; + } + + return $retval; +} + +sub boardSysType() +{ + my ($addr, $bType_ref, $bSysType_ref) = @_; + + foreach my $sys ( keys %$addressRange_href ){ + my $addr_min = lc($addressRange_href->{$sys}->{'MIN'}); + my $addr_max = lc($addressRange_href->{$sys}->{'MAX'}); + + if( hex(lc($addr)) >= hex($addr_min) && hex(lc($addr)) <= hex($addr_max) ){ + $$bType_ref = $addressRange_href->{$sys}->{'TYPE'}; + $$bSysType_ref = $sys; + last; + } + } + + unless( defined $$bType_ref ){ + print "ERROR: boardSysType(): unknown board type for address $addr.\n"; + $$bType_ref = "undef"; + } + + unless( defined $$bSysType_ref ){ + print "ERROR: boardSysType(): unknown board system type for address $addr.\n"; + $$bSysType_ref = "undef"; + } +} + +sub boardType() +{ + my ($addr) = @_; + + my $board_type; + + foreach my $sys ( keys %$addressRange_href ){ + my $addr_min = lc($addressRange_href->{$sys}->{'MIN'}); + my $addr_max = lc($addressRange_href->{$sys}->{'MAX'}); + + if( hex(lc($addr)) >= hex($addr_min) && hex(lc($addr)) <= hex($addr_max) ){ + $board_type = $addressRange_href->{$sys}->{'TYPE'}; + last; + } + } + + unless( defined $board_type ){ + print "ERROR: boardType(): unknown board type for address $addr. Exit.\n"; + exit(1); + } + + return $board_type; +} + +sub timeStamp() +{ + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($seconds1); + my $timestamp = sprintf("%4d-%02d-%02d_%02d.%02d.%02d", + $year+1900, $mon+1, $mday, $hour, $min, $sec); + + return $timestamp; +} + +sub scanLogs() +{ + #- Check the log files which were created + # after DAQ restart (after $seconds) + + opendir(DIR, $log_dir) or die "Could not open $log_dir: $!";; + my @logfile_list = grep(/^log/, readdir(DIR)); + closedir(DIR); + + #- Sort files by modification date + @logfile_list = sort { -M "$log_dir/$a" <=> -M "$log_dir/$b" } (@logfile_list); + + my $errorFound = 0; + + foreach my $file (@logfile_list){ + + #- Modification date in seconds since EPOCH + my $seconds2 = (stat "$log_dir/$file")[9]; + + if( $seconds2 > $seconds1 ){ + if(&scanLogFile("$log_dir/$file")){ + $errorFound = 1; + } + } + } + + if($errorFound){ + &askUser(); + } + + #- Update time. + # We want to look only at the log files + # which were not checked before. + $seconds1 = time; +} + +sub scanLogFile() +{ + my ($logFile) = @_; + + my $retval = 0; + + open(DAT, $logFile) || die("Could not open $logFile!"); + my @log_data = ; + close(DAT); + + if( any {$_ =~ /TX Busy/} @log_data ){ + print "Found \'TX Busy\' in $logFile. Problem with TRB-Net?\n"; + $retval = 1; + } + + if( any {$_ =~ /Verification Failure/} @log_data ){ + print "Found \'Verification Failure\' in $logFile. Problem with jam-programming?\n"; + $retval = 1; + } + + if( any {$_ =~ /Fifo not empty/} @log_data ){ + print "Found \'Fifo not empty\' in $logFile. Problem with TRB-Net?\n"; + $retval = 1; + } + + return $retval; +} diff --git a/main/restartEB.sh b/main/restartEB.sh new file mode 100755 index 0000000..684f45a --- /dev/null +++ b/main/restartEB.sh @@ -0,0 +1,5 @@ +#!/bin/bash +cd /home/hadaq/trbsoft/daq/evtbuild/ +./start_eb_gbe.pl -e stop -n 1-16 +sleep 10 +./start_eb_gbe.sh diff --git a/main/serials_trb.db b/main/serials_trb.db new file mode 100644 index 0000000..ca14946 --- /dev/null +++ b/main/serials_trb.db @@ -0,0 +1,30 @@ +023 400000012410f728 +031 0a0000012410fa28 +034 d7000001241ee528 +040 9500000123f4fe28 +051 6200000123f25f28 +052 7700000123f26428 +053 ad00000123f25528 +054 e200000124172628 +058 3c00000123f5a328 +062 df000001c17f1728 +064 910000012419cd28 +072 71000001c17b8728 +074 fa000001c17e8428 +079 58000001fc5ba128 +081 5a000001fc5de428 +084 be00000123ec4c28 +086 34000001fc5bb028 +089 c0000001ff590b28 +096 b5000001fc42c928 +097 e1000001fc7a6f28 +098 9a000001fc644128 +099 00000001ff46f328 +100 6400000123f26a28 +101 e7000001ff469c28 +102 32000001fc42dd28 +103 0e000001fc3c0c28 +104 6d000001fc3ed328 +105 cc000001fc41c828 +106 51000001fc32a428 + diff --git a/main/startup.pl b/main/startup.pl new file mode 100755 index 0000000..a8ec24d --- /dev/null +++ b/main/startup.pl @@ -0,0 +1,2305 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use FileHandle; +use File::Path; +use File::Basename; +use Data::Dumper; +use Time::HiRes; + +use IO::Socket; +use Net::Ping; + +use Config::Std; +use Carp qw( croak ); +use Scalar::Util qw(reftype); +use List::Util; +use List::MoreUtils qw(any apply); + +use IO::Socket; +use IO::Select; + +use threads; +use threads::shared; + +#use Clone qw(clone); + +#- the command line option flags +my $opt_help = 0; +my $opt_eb = "on"; +my $opt_check = 1; +my $opt_rdo = 0; +my $opt_test = 0; +my $opt_file = "../main/startup.script"; +my $opt_etrax = "etraxp058"; +my $opt_verb = 0; +my $opt_ora = "file"; +my @opt_macro; +my @dead_cservers; + +GetOptions ('h|help' => \$opt_help, + 'b|eb=s' => \$opt_eb, + 'c|check=i' => \$opt_check, + 'r|rdo' => \$opt_rdo, + 'f|file=s' => \$opt_file, + 'e|etrax=s' => \$opt_etrax, + 'm|macro=s' => \@opt_macro, + 'v|verb' => \$opt_verb, + 'o|oracle=s' => \$opt_ora, + 't|test' => \$opt_test); + +if( $opt_help ) { + &help(); + exit(0); +} + +my $parent_pid = $$; + +my @subsys_array = ('mdc','rich','rpc','start','tof','wall','hub'); + +my $expect_script = "/tmp/remote_exec.exp"; +my $var_dir = "/var/diskless/etrax_fs"; +my $log_dir = "/tmp/log"; + +my $cmd_server = "./bin/command_server"; +my $cmd_server_port = 4712; +my $cmd_server_prtcl = 'tcp'; +my $cmd_server_answer = ""; + +my %addr_db_conf; # Hash with all addresses, serials, uids from DBs +my $addr_db_conf_href = \%addr_db_conf; +my @startup; # Array with all startup configuration +my $startup_aref = \@startup; +my %trb_hash; # Hash with TRBs for different subsystems +my $trb_href = \%trb_hash; +my %EB_Args; # Hash with EB args +my $EB_Args_href = \%EB_Args; +my @rdo; # Array with etrax names which run readout +my $rdo_aref = \@rdo; + +my @usedMacros = (); # Array of used macro names to identify names with typos + +my %data2ora_hash; # Hash with data to be stored in Oracle +my $data2ora_href = \%data2ora_hash; + +my @subEvtIds; # Array with subevent Ids +my $subEvtIds_aref = \@subEvtIds; + +my %addressRange; # Hash with ranges of TRBNet addresses for each type of board +my $addressRange_href = \%addressRange; + +if( 0 != &checkArgs() ){ + print "Exit.\n"; + exit(1); +} + +#- Get local time in seconds since Epoch +my $seconds1 = time; + +my $child_pid = &forkStatusServer(); + +&prepareForStartup(); #0.05s +&cleanup(); #0.02s +&readScript($opt_file, 'local'); #1.3s +&checkUnusedMacros(); #0s + +#print Dumper $startup_aref; +#print Dumper $trb_href; +#print Dumper $addr_db_conf_href->{'0x3230_3'}; +&checkConnection() if($opt_check); #2.6s + +&closeEBs() if($opt_eb eq "on"); +&execViaCmdServer(); +&startEBs() if($opt_eb eq "on"); + +exit(0); + +################### END OF MAIN #################### + +sub help() +{ + print "\n"; + print << 'EOF'; +startup.pl + + This script starts readout via Command_Server running + on etrax boards. The script also starts Event Builder + to collect the data. + +Usage: + + Command line: startup.pl + [-h|--help] : Show this help. + [-f|--file ] : Path to main config file. + [-b|--eb |] : Automatic restart of EBs (default: on). + [-r|--rdo] : Start readout. + [-e|--etrax ] : Etrax name. + [-m|--macro ] : Macro names for preprocessing startup.script files. + Only !ifdef, !ifndef, !endif directives are defined. + !ifdef - by default exclude following cmds, + !ifndef - by default include following cmds. + [-o|--oracle ] : Write ascii files with info for Oracle (default: file). + [-t|--test] : Test without execution. + [-v|--verb] : Verbose. + +Examples: + + Start MDC script with macros CALIB and INIT: + startup.pl -f ../mdc/startup.script -m CALIB -m INIT + +EOF +} + +sub checkArgs() +{ + my $retval = 0; + + if($opt_rdo){ + print "Option -r is not implemented yet.\n"; + $retval = 1; + } + if( ! (-e $opt_file) ){ + print "File $opt_file does not exist.\n"; + $retval = 1; + } + + return $retval; +} + +sub prepareForStartup() +{ + + my $var_log_dir = $var_dir . "/tmp/log"; + &makeDir($var_log_dir); + + my $mode_dir = $log_dir . "/mode"; + &makeDir($mode_dir); + + #- Write expect script + &writeExpect(); +} + +sub makeDir() +{ + my ($dir) = @_; + + #- Make all needed dirs/subdirs + my @log_dir_list = split('/', $dir); + + my $dir2mk = ""; + foreach my $subdir (@log_dir_list){ + next unless( $subdir ); + + $dir2mk = $dir2mk . "/" . $subdir; + mkdir($dir2mk) or die $! unless( -d $dir2mk); + } +} + +sub cleanup() +{ + system("rm $log_dir/log*.txt 2>/dev/null 2>/dev/null") unless($opt_test); + system("rm $log_dir/board_ids_for_oracle*.txt 2>/dev/null 2>/dev/null") unless($opt_test); + system("rm $log_dir/mode/* 2>/dev/null 2>/dev/null") unless($opt_test); +} + +sub writeExpect() +{ + # If command_server is not started on Etrax at boot time + # this expect script can be executed to start command_server. + + #! Look if /tmp dir exists + my $tmp_dir = dirname("/tmp"); + if ( !(-d $tmp_dir) ){ + print "\nCannot access /tmp directory!\nExit.\n"; + exit(1); + } + + my $expect_script_my = <0} { + set host [lindex \$argv 0] + set path [lindex \$argv 1] + set bin [lindex \$argv 2] + set opt [lindex \$argv 3] +} else { + send_user "Usage: \$argv0 host path binary options\\n" +} + +spawn telnet \$host +expect { + "error" { exit; } + "login:" { send "root\\r"; exp_continue; } + "Password:" { send "pass\\r" } +} + +set timeout 240 + +expect "# " +send "killall -9 \$bin\\r" +expect "# " +send "cd /home/hadaq/\\r" +expect "# " +send "\$path\$bin \$opt\\r" +expect "# " + +EOF + + my $fh = new FileHandle(">$expect_script"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$expect_script\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $expect_script_my; + $fh->close(); + + #- open permissions + system("chmod 755 $expect_script") unless($opt_test); +} + +sub getSubsysName() +{ + my ($script) = @_; + + my $subsys; + + if( $script =~ /..\/(\w+)\/(\w+).script/ ){ + $subsys = $1; + + die "getSubsysName(): Undefined subsystem: \'$script\'! Exit.\n" unless( defined $subsys ); + } + else{ + $subsys = 'main'; + } + + return $subsys; +} + +sub preprocess() +{ + my ($preproc, $line) = @_; + + my ($directive, $macro) = split(" ", $line); + + &preprocessCheck( $preproc, $directive ); + + if( $directive eq "!ifdef" and (any {lc($_) eq lc($macro)} @opt_macro) ){ + $preproc->{'ifdef'} = 'on'; + $preproc->{'skeepLine'} = 0; + + #- Save found macro names + push(@usedMacros, $macro) unless(any {lc($_) eq lc($macro)} @usedMacros); + + return 1; + } + elsif( $directive eq "!ifdef" ){ + #- No ifdef macros defined in cmd line => skeep next lines + $preproc->{'ifdef'} = 'on'; + $preproc->{'skeepLine'} = 1; + + return 1; + } + elsif( $directive eq "!ifndef" && (any {lc($_) eq lc($macro)} @opt_macro) ){ + $preproc->{'ifndef'} = 'on'; + $preproc->{'skeepLine'} = 1; + + #- Save found macro names + push(@usedMacros, $macro) unless(any {lc($_) eq lc($macro)} @usedMacros); + + return 1; + } + elsif( $directive eq "!ifndef" ){ + #- No ifndef macros defined in cmd line => include next lines + $preproc->{'ifndef'} = 'on'; + $preproc->{'skeepLine'} = 0; + + return 1; + } + elsif( $directive eq "!endif" ){ + $preproc->{'ifndef'} = 'off'; + $preproc->{'ifdef'} = 'off'; + $preproc->{'skeepLine'} = 0; + + return 1; + } + + return $preproc->{'skeepLine'}; +} + +sub checkUnusedMacros() +{ + my @unusedMacros = (); + my $foundUnused = 0; + + foreach my $macro (@opt_macro){ + unless((any {lc($_) eq lc($macro)} @usedMacros)){ + push(@unusedMacros, $macro); + $foundUnused = 1; + } + } + + if($foundUnused){ + print "\nUnused macro names:"; + + foreach my $macro (@unusedMacros){ + print " $macro"; + } + + print "\n"; + + &askUser(); + } +} + +sub preprocessInit() +{ + my %preproc = ( + 'ifdef' => 'off', + 'ifndef' => 'off', + 'skeepLine' => 0 + ); + + return \%preproc; +} + +sub preprocessCheck() +{ + my ($preproc, $directive) = @_; + + if( $directive eq "!ifdef" || $directive eq "!ifndef" ){ + unless( ($preproc->{'ifdef'} eq 'off') && + ($preproc->{'ifndef'} eq 'off') ){ + print "Encapsulated \'ifdef\'/\'ifndef\' are not supported. Each \'ifdef\'/\'ifndef\' must be closed with \'endif\' before next \'ifdef\'/\'ifndef\' can be opened.\n"; + exit(1); + } + } + elsif( $directive eq "!endif" ){ + if( ($preproc->{'ifdef'} eq 'on' && $preproc->{'ifndef'} eq 'on') || + ($preproc->{'ifdef'} eq 'off' && $preproc->{'ifndef'} eq 'off') ){ + print "The sequence of directives looks fishy. Each \'ifdef\'/\'ifndef\' must be closed with \'endif\' before next \'ifdef\'/\'ifndef\' can be opened.\n"; + exit(1); + } + } + elsif( $directive =~ /!(\w+)/ ){ + print "Unknown directive $directive. Exit.\n"; + exit(1); + } +} + +sub readTRBSetup() +{ + my ($trb_db) = @_; + + my $fh = new FileHandle("$trb_db", "r"); + + &isItDefined($fh, $trb_db); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my ($sys, $etrax, $rdo) = split(" ", $_); + + unless( defined $etrax ){ + print "Etrax is not defined in $trb_db for $sys! Exit\n"; + $fh->close; + exit(1); + } + + #- Add to a main configuration hash + push( @{$trb_href->{$sys}}, $etrax ); + + #- Add to a readout array for EB + if( defined $rdo && $rdo =~ /rdo/ ){ + push( @$rdo_aref, $etrax ); + } + } + + $fh->close; +} + +sub readAddressRangeSetup() +{ + my ($addressRange_db) = @_; + + my $fh = new FileHandle("$addressRange_db", "r"); + + &isItDefined($fh, $addressRange_db); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my ($sys, $min, $max, $type) = split(" ", $_); + + $min =~ s{ # Substitue... + 0x # ...hex zero + }{}gxms; # ...with nothing + + $max =~ s{ # Substitue... + 0x # ...hex zero + }{}gxms; # ...with nothing + + + unless( defined $sys && defined $min && + defined $max && defined $type){ + print "Something wrong with a format of $addressRange_db! Exit.\n"; + $fh->close; + exit(1); + } + + $addressRange_href->{$sys}->{'MIN'} = $min; + $addressRange_href->{$sys}->{'MAX'} = $max; + $addressRange_href->{$sys}->{'TYPE'} = $type; + } + + $fh->close; +} + +sub readSubevtIdsSetup() +{ + my ($subevt_db) = @_; + + my $fh = new FileHandle("$subevt_db", "r"); + + &isItDefined($fh, $subevt_db); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my $subevt; + + if( $_ =~ /0x(\w+)/ ){ + $subevt = $1; + } + else{ + print "Something wrong with a format of $subevt_db! Exit\n"; + $fh->close; + exit(1); + } + + #- Add to a config array + push( @$subEvtIds_aref, $subevt ); + } + + $fh->close; +} + +sub readScript() +{ + my ($script, $exec_sys) = @_; + + #- Extract subsystem name + my $subsys = &getSubsysName($script); + #print "script: $script, subsys: $subsys\n"; + + my $fh = new FileHandle("$script", "r"); + &isItDefined($fh, $script); + + #- Init preprocessor hash + my $preproc = &preprocessInit(); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Check for preprocessor directives + next if( &preprocess($preproc, $_) ); + + #- Extract command and parameters + my ($cmd, @param) = split(" ", $_); + + &add2startup( $subsys, $exec_sys, $cmd, \@param ); + } + + $fh->close; +} + +sub add2startup(){ + + my ($subsys, $exec_sys, $cmd, $aref) = @_; + + die "add2startup(): one or more arguments are not defined! Exit.\n" + unless( defined $subsys && defined $exec_sys && defined $cmd && defined $aref); + + if( $cmd =~ /exec_script{(\w+)}/ ){ + my $exec_sys = $1; + + #- exec_script is followed only by one parameter [0]: script name + &readScript( $aref->[0], $exec_sys ); + } + elsif( $cmd =~ /exec_cmd{(\w+)}/){ + my $exec_sys = $1; + + my $args = &getArgs4cmd($aref, $subsys); + &push2array( \@startup, $exec_sys, $args ); + } + elsif( $cmd eq 'exec_cmd'){ + + my $args = &getArgs4cmd($aref, $subsys); + + &push2array( \@startup, $exec_sys, $args ); + } + elsif( $cmd eq 'wait'){ + + #- At this point we will wait for the forked children + push( @startup, {$cmd => ['-']} ); + } + elsif( $cmd eq 'trbcmd'){ + my $args = &getArgs4cmd($aref, $subsys); + my $cmd_line = "$cmd $args"; + + &push2array( \@startup, $exec_sys, $cmd_line ); + } + elsif( $cmd eq 'set_addresses' ){ + my $serials = $aref->[0]; + my $addresses = $aref->[1]; + + my $conf = $subsys . "-" . $cmd . "-" . $serials . ".conf"; + my $args = &makeAddressesConf( $subsys, $serials, $addresses, $conf ); + my $bash_script = "trbdhcp -f $args"; + + &push2array( \@startup, $exec_sys, $bash_script ); + } + elsif( $cmd eq 'load_register' ){ + my $register = $aref->[0]; + + my $conf = $subsys . "-" . $cmd . "-" . $register . ".conf"; + my $args = &makeRegisterConf( $subsys, $register, $conf ); + my $bash_script = "trbcmd -f $args"; + + &push2array( \@startup, $exec_sys, $bash_script ); + } + elsif( $cmd eq 'daqop' ){ + my $args = &getArgs4cmd($aref, $subsys); + my $bash_script = "$cmd $args"; + + &push2array( \@startup, $exec_sys, $bash_script ); + } + elsif( $cmd eq 'read_trb_db' ){ + #- Read database file with TRB setup + my $trb_db = $aref->[0]; + + &readTRBSetup( $trb_db ); + } + elsif( $cmd eq 'read_addrange_db' ){ + #- Read database file with TRBNet address ranges + my $addrRanges_db = $aref->[0]; + + &readAddressRangeSetup($addrRanges_db); + } + elsif( $cmd eq 'read_subevtids_db' ){ + #- Read database file with subevent Ids + my $subevt_db = $aref->[0]; + + &readSubevtIdsSetup( $subevt_db ); + } + elsif( $cmd eq 'read_eb_conf' ){ + #- Read config file with EB settings + my $eb_conf = $aref->[0]; + + read_config $eb_conf => %$EB_Args_href; + } + else{ + die "add2startup(): do not know what to do with command \'$cmd\' for subsystem \'$subsys\'! Exit.\n"; + } +} + +sub checkScript() +{ +} + +sub getArgs4cmd() +{ + my ($aref, $subsys) = @_; + + my $args = ""; + + if( $aref->[0] eq '-f' && defined $subsys ){ + my $conf = $aref->[1]; + system("cp ../$subsys/$conf $var_dir/tmp/.") unless($opt_test); + $args = "-f /home/hadaq/tmp/" . $conf; + } + else{ + for( my $i=0; $i < scalar (@{$aref}); $i++){ + $args = $args . " " . $aref->[$i]; + } + } + + return $args; +} + +sub isItDefined() +{ + my ($fh, $name) = @_; + + if(!$fh) { + my $txt = "\nError! Could not open file \'$name\'. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + return 0; +} + +sub isVarDefined() +{ + my ($var, $name) = @_; + + unless( defined $var ){ + print "$name is not defined! Exit.\n"; + exit(1); + } +} + +sub push2array() +{ + my ($aref, $exec_sys, $cmd) = @_; + + if( defined $aref->[-1] && defined $aref->[-1]->{$exec_sys} ){ + #- If last exec_sys equals current exec_sys + #- push current cmd to the same exec_sys + push( @{$aref->[-1]->{$exec_sys}}, $cmd ); + } + else{ + #- Unless create new entry in the main array + push( @$aref, {$exec_sys => [$cmd]} ); + } +} + +sub execViaCmdServer() +{ + my (@process_list); + + my $i = 1; + + #- Loop over subsystems + foreach my $href ( @$startup_aref ){ +# print Time::HiRes::time()."\n" ; + + my ($exec_sys, $cmd_aref) = each ( %$href ); + + if($exec_sys eq 'con') { + foreach my $cmd ( @{$cmd_aref} ){ + system($cmd); + } + } + + if( $exec_sys eq 'wait' ){ + $| = 1; # turn off stdout buffering + print "wait...\r"; + #- Wait for the forked children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } + &scanLogs(); +# print Time::HiRes::time()."\n"; + next; + } + + print "exec: $exec_sys\n" unless( $exec_sys eq "local" || $exec_sys eq "con"); + + #system("logger -p local1.info -t DAQ $exec_sys"); + + #- Loop over TRBs for given exec_sys + if( $exec_sys =~ /etrax/ ){ + #- Name of etrax is explicitly written in exec_cmd{} + # in main startup script. + if($opt_etrax){ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . "_" . $opt_etrax . ".txt"; + &forkMe( $cmd_aref, \@process_list, $opt_etrax, $log); + } + else{ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . ".txt"; + &forkMe( $cmd_aref, \@process_list, $exec_sys, $log); + } + } + elsif( $exec_sys eq 'local' ){ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . ".txt"; + &forkMe( $cmd_aref, \@process_list, $exec_sys, $log); + } + elsif( $exec_sys eq 'nofork'){ + &execLocal($cmd_aref,$exec_sys); + } + else{ + #- Loop over TRBs for a given subsys + foreach my $trb ( @{$trb_href->{$exec_sys}} ){ + my $log = $log_dir . "/" . "log" . $i . "_" . $exec_sys . "_" . $trb . ".txt"; + &forkMe( $cmd_aref, \@process_list, $trb, $log); + } + } + + $i++; #increment log file index + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } +} + +sub execLocal() +{ + my ($cmd_aref) = @_; + + #- Loop over cmds to be executed on the local system + # without forking + foreach my $cmd ( @{$cmd_aref} ){ + $| = 1; # turn off stdout buffering + + if($cmd =~ /check_compile_time/){ + &checkCompileTime($cmd) unless($opt_test); + } + } +} + +sub forkMe() +{ + my ($cmd_aref, $proc_list, $etrax, $log) = @_; + + my $child = fork(); + + if( $child ){ # parent + push( @$proc_list, $child ); +# print "$child: ".$cmd_aref->[0]."\n"; + } + elsif( $child == 0 ) { # child + exit(0) if($opt_test); + + if( $etrax eq "local" ){ + + #- Loop over cmds to be executed on the local system + foreach my $cmd ( @{$cmd_aref} ){ + $| = 1; # turn off stdout buffering + print "sleep...\r" if( $cmd =~ /sleep/ ); + + if($cmd =~ /daq2oracle/){ + &data2ora() unless($opt_test); + } + else{ + + #- Redirect STDOUT but not for 'echo' + unless($cmd =~ /echo/){ + open(STDOUT, ">>$log") || die "Cannot redirect STDOUT"; + open(STDERR, ">>&STDOUT") || die "Cannot dup STDERR"; + select STDERR; $| = 1; # make unbuffered + select STDOUT; $| = 1; # make unbuffered + } + + unless($opt_test){ + print "===> $cmd\n" unless($cmd =~ /echo/); + system("$cmd"); + print "> returned value of command $?\n" unless($cmd =~ /echo/); + } + + unless($cmd =~ /echo/){ + close(STDOUT); + close(STDERR); + } + } + } + } + else{ + #- Connect to commandServer to exec commands on the remote systems + if( &connectCmdServer($cmd_aref, $etrax, $cmd_server_port, $cmd_server_prtcl, $log) ){ + #print "Something went wrong on commandServer side.\n"; + } + } + + exit(0); # exit child + } + else{ + print "Could not fork: $!\n"; + exit(1); + } +} + +sub connectCmdServer() +{ + my ($cmd, $remote_host, $remote_port, $protocol, $log) = @_; + + # '$cmd' can be a reference to an array of commands + # or just single command. In the first case, the commands + # from the array will be executed one after another. + + &isVarDefined( $cmd, "connectCmdServer(): cmd" ); + &isVarDefined( $remote_host, "connectCmdServer(): remote_host" ); + + my $fh = new FileHandle(">$log"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$log\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + my $answer; + my $retval = 1; + + my $socket = IO::Socket::INET->new(PeerAddr => $remote_host, + PeerPort => $remote_port, + Proto => $protocol, + Type => SOCK_STREAM) + or $answer = "ERROR: No response from Cmd Server at $remote_host:$remote_port\n"; + + unless( defined $answer ){ + $socket->autoflush(1); + print $socket "iamfromhadesdaq\n"; + $answer = <$socket>; + + &print2file($fh, $answer); + + my $reftype = reftype \$cmd; + + if( $reftype =~ /REF/ ){ + #- Loop over commands to be executed on etrax + foreach my $command ( @{$cmd} ){ + + $command = &cmdParam( $command, $remote_host ); + + print $socket "$command\n"; + &print2file( $fh, "===> $command\n" ); + + while ( <$socket> ) { + &print2file( $fh, $_ ); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + } + else{ + print $socket "$cmd\n"; + &print2file( $fh, "===> $cmd\n" ); + + while ( <$socket> ) { + &print2file( $fh, $_ ); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + + close($socket); + } + + if( $answer =~ /Connection accepted/ ){ + $retval = 0; + } + else{ + &print2file( $fh, $answer ); + } + + $fh->close(); + + return $retval; +} + +sub cpThresholds() +{ + my ($timestamp) = @_; + + my $thresh_dir = "/data/lxhadesdaq/daq/thresh"; + my %ora_thresh; + my $ora_thresh_href = \%ora_thresh; + + foreach my $my_href ( @{$startup_aref} ){ + + my %my_hash = %$my_href; + + my ($exec_sys, $cmd_aref) = each ( %my_hash ); + + next unless( defined $exec_sys ); + + next if( $exec_sys eq 'wait' ); + + foreach my $cmd ( @{$cmd_aref} ){ + if( $cmd =~ /spi_trb/ ){ + $cmd =~ s/^\s+//; # remove leading whitespace + + my ($spi, $thresh) = split(" ", $cmd); + my $thresh_name_new = $thresh_dir . "/thresh_" . $timestamp . "_" . $exec_sys; + + $ora_thresh_href->{$exec_sys} = $thresh_name_new; + + my $THRPATH = "/var/diskless/etrax_fs"; + + $thresh =~ s{ # Substitue... + \/home\/hadaq # ...an Etrax path + } + {$THRPATH}gxms; # ...with lxhadesdaq path + + if( $thresh =~ /\${TRBNUM}/ ){ + foreach my $trb ( @{$trb_href->{$exec_sys}} ){ + my $trbnum = 0; #default + if( $trb =~ /etraxp?(\d{3})/ || $trb =~ /trb?\d(\d{2})/){ + $trbnum = $1; + } + else{ + croak "cmdParam: unexpected etrax name: $trb. Exit.\n"; + } + + #- replace TRBNUM + $thresh =~ s{ # Substitue ... + \${TRBNUM} # ... a parameter + } + {$trbnum}gxms; # ... with a TRB number + + my $thresh_name_trb = $thresh_name_new . "_" . $trbnum; + + system("cp $thresh $thresh_name_trb"); + } + } + else{ + system("cp $thresh $thresh_name_new"); + } + } + } + } + + #- Build a line for Oracle DB + my $line = ""; + + foreach my $exec_sys (sort keys %{$ora_thresh_href}){ + my $thresh_name = $ora_thresh_href->{$exec_sys}; + $line = $line . " " . $exec_sys . " lxhadesdaq:" . $thresh_name . "%"; + } + + unless( $line eq "" ){ + $line = "loaded_thresholds " . $timestamp . " Loaded thresholds:% " . $line . "\n"; + } + else{ + print "WARNING: could not identify file names for loaded thresholds!\n" + } + + return $line; +} + +sub print2file() +{ + my ($fh, $toprint) = @_; + + if( defined $toprint ){ + print $fh $toprint; + + if( $opt_verb || $toprint =~ /ERROR/){ + print "$toprint\n"; + } + } +} + +sub cmdParam(){ + my ($cmd, $etrax) = @_; + + croak "cmdParam: undefined etrax name. Exit.\n" unless( defined $etrax ); + + my $trbnum = 0; #default + if( $etrax =~ /etraxp?(\d{3})/ || $etrax =~ /trb?\d(\d{2})/ || $etrax =~ /hades?\w(\d{2})/){ + $trbnum = $1; + } + else{ + croak "cmdParam: unexpected etrax name: $etrax. Exit.\n"; + } + + my $eb_port = $EB_Args_href->{'Main'}->{'PORT_BASE'} + $trbnum; + my $eb_ip = $EB_Args_href->{'Main'}->{'EB_IP'}; + + #- replace TRBNUM + $cmd =~ s{ # Substitue... + \${TRBNUM} # ...a parameter + } + {$trbnum}gxms; # Raplace it with a TRB number + + #- replace EBIP + $cmd =~ s{ # Substitue... + \${EBIP} # ...a parameter + } + {$eb_ip}gxms; # Raplace it with a EB IP + + #- replace EBPORT + $cmd =~ s{ # Substitue... + \${EBPORT} # ...a parameter + } + {$eb_port}gxms; # Raplace it with a EB PORT + + $cmd = "source /home/hadaq/.bashrc; " . $cmd if($etrax =~ /hades?\w(\d{2})/); + + return $cmd; +} + +sub makeRegisterConf() +{ + my ($subsys, $register, $outConf) = @_; + + $register = "../" . $subsys . "/" . $register; + + my %reg_hash; + my $reg_href = \%reg_hash; + + my $fh = new FileHandle("$register", "r"); + &isItDefined($fh, $register); + + my $reg_table = 0; + my $val_table = 0; + my $ver_table = 0; + my $ver_tdcmask = 0; + my %mb_type; #Motherboard type + my $mb_type = \%mb_type; + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #- Find which table we will read now + if(/^(\s+)?!Register\stable/){ + $reg_table = 1; + $val_table = 0; + $ver_table = 0; + $ver_tdcmask = 0; + next; + } + elsif(/^(\s+)?!Value\stable/){ + $reg_table = 0; + $val_table = 1; + $ver_table = 0; + $ver_tdcmask = 0; + next; + } + elsif(/^(\s+)?!Version\stable/){ + $reg_table = 0; + $val_table = 0; + $ver_table = 1; + $ver_tdcmask = 0; + next; + } + elsif(/^(\s+)?!Version\stdcmask/){ + $reg_table = 0; + $val_table = 0; + $ver_table = 0; + $ver_tdcmask = 1; + next; + } + + if($reg_table){ + my ($type, @reg) = split(" ", $_); + my $reg = \@reg; + $mb_type->{$type} = $reg; + } + elsif($val_table){ + # We assume here that reg_table was before val_table + # thus mb_type hash is already filled at this point. + + my ($addr, $type, @val) = split(" ", $_); + + if( ! defined $mb_type->{$type} ){ + print "Error: Board type '$type' specified in 'Value table' in $register\n"; + print "is most likely not defined in 'Register table'! Exit.\n"; + $fh->close; + exit(1); + } + + my $arr_size = scalar @{ $mb_type->{$type} }; + + for(my $i=0; $i<$arr_size; $i++){ + my $reg = @{$mb_type->{$type}}[$i]; + my $val = $val[$i]; + + push(@{$reg_hash{$addr}}, {$reg => $val}); + } + } + elsif($ver_table){ + $data2ora_href->{"MDC"}->{"THRESH_VERS"} = $_ if( $subsys eq "mdc"); + $data2ora_href->{"RICH"}->{"THRESH_VERS"} = $_ if( $subsys eq "rich"); + } + elsif($ver_tdcmask){ + $data2ora_href->{"MDC"}->{"TDCMASK_VERS"} = $_ if( $subsys eq "mdc"); + } + } + + $fh->close; + + #--------------- Write config file + my $outConf_register = $var_dir . "/tmp/" . $outConf; + my $ret_register = "/home/hadaq/tmp/" . $outConf; + + $fh = new FileHandle(">$outConf_register"); + + foreach my $addr ( sort keys %{$reg_href} ){ + foreach my $ref (@{$reg_href->{$addr}}){ + my ($reg, $thr) = each( %{$ref} ); + + print $fh "w $addr $reg $thr\n"; + } + } + + $fh->close; + + return $ret_register; +} + +sub makeAddressesConf() +{ + my ($subsys, $serials, $addresses, $outConf) = @_; + + $serials = "../" . $subsys . "/" . $serials; + $addresses = "../" . $subsys . "/" . $addresses; + + my %trbdhcp_hash; + my $trbdhcp_href = \%trbdhcp_hash; + + #------------ Read addresses into trbdhcp hash + my $fh = new FileHandle("$addresses", "r"); + &isItDefined($fh, $addresses); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + my ($addr, $serial, $endpoint, $design, $trbNr) = split(" ", $_); + + #- All fields must be defined + next unless( defined $design && defined $addr && + defined $serial && defined $endpoint); + + #- Skip all lines with serial number zero + next if( $serial eq '0' ); + + #- Define uniqueu key + my $key = $addr . "_" . $endpoint; + + $trbdhcp_href->{$key}->{'addr'} = lc($addr); + $trbdhcp_href->{$key}->{'design'} = $design; + $trbdhcp_href->{$key}->{'endpoint'} = $endpoint; + $trbdhcp_href->{$key}->{'serial'} = $serial; + $trbdhcp_href->{$key}->{'trb'} = $trbNr; + + } + + $fh->close; + + #------------ Read serials into trbdhcp hash + $fh = new FileHandle("$serials", "r"); + &isItDefined($fh, $serials); + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + my ($serial, $uid) = split(" ", $_); + + next unless( defined $serial && defined $uid ); + + #- Skip all lines with serial number zero + next if( $serial eq '0' ); + + foreach my $key ( keys %{$trbdhcp_href} ){ + + next unless( $serial eq $trbdhcp_href->{$key}->{'serial'} ); + $trbdhcp_href->{$key}->{'uid'} = lc($uid); + } + } + + $fh->close; + + #------------ Write config file for 'trbdhcp' + my $outConf_trbdhcp = $var_dir . "/tmp/" . $outConf; + my $ret_trbdhcp = "/home/hadaq/tmp/" . $outConf; + + $fh = new FileHandle(">$outConf_trbdhcp"); + + foreach my $key (sort keys %$trbdhcp_href) { + my $addr = $trbdhcp_href->{$key}->{'addr'}; + my $uid = $trbdhcp_href->{$key}->{'uid'}; + my $endpoint = $trbdhcp_href->{$key}->{'endpoint'}; + + next if( ! defined $addr || ! defined $uid || ! defined $endpoint); + + print $fh "$addr $uid $endpoint\n"; + } + + $fh->close; + + #--- Add this hash to a global hash + %addr_db_conf = (%addr_db_conf, %$trbdhcp_href); + + return $ret_trbdhcp; +} + +sub checkCompileTime() +{ + my ($cmd) = @_; + + my $sys; + my $compile_time; + + if($cmd =~ /check_compile_time\s+(\w+)\s+0x(\w+)/){ + $sys = lc($1); + $compile_time = hex($2); + } + + unless( defined $sys || defined $compile_time ){ + die "check_compile_time command must contain system and compile time as arguments! Exit.\n"; + } + + my $read_cmd = ""; + if(lc($sys) eq "oep"){ + $read_cmd = "trbcmd r 0xfffd 0x40"; + } + else{ + print "Reading compile times failed: unsupported sys type $sys\n"; + return 0; + } + + my @out = `$read_cmd`; + + my $oldCompileTime = 0; + + foreach my $line (@out){ + + next if($line =~ /Read compile time/ ); + + if( $line =~ /failed/ ){ + print "ERROR: when reading compile times of $sys: $line\n"; + &askUser(); + } + + my $local_time; + my $local_addr; + + if( $line =~ /0x(\w+)\s+0x(\w+)/ ){ + $local_addr = lc($1); + $local_time = hex($2); + } + + unless( defined $local_addr || defined $local_time ){ + print "ERROR: unexpected output: $line\n from command: $read_cmd\n"; + &askUser(); + } + + if( defined $local_time && defined $local_addr){ + if( $local_time < $compile_time ){ + $oldCompileTime = 1; + print "Compile time for $sys $local_addr is too old!\n"; + } + } + } + + &askUser() if($oldCompileTime); +} + +sub askUser() +{ + my $answer = &promptUser("Continue?", "Enter to continue, Ctrl+C to stop"); + if( $answer eq "no" || $answer eq "n" ){ + print "Exit.\n"; + exit(0); + } + else{ + print "Continue...\n"; + } +} + +sub checkConnection() +{ + + #----------- Check connection to hosts ------------- + print "Check connection to hosts...\n"; + + my @dead_hosts = (); + my @alive_hosts = (); + &pingHosts(\@alive_hosts, \@dead_hosts); + + if( @dead_hosts ){ + print "Cannot connect to the following hosts:\n"; + + foreach my $host (@dead_hosts){ + + my $msg = "undef"; + if($host =~ /etraxp?(\d{3})/){ + my $serial = $1; + + if(&checkShowerNORPC($host)){ + $msg = "addr: - type: -"; + } + else{ + $msg = &serial2addrAndSysType($serial, "TRB"); + } + } + + print "$host $msg\n"; + system("logger -p local1.info -t DAQ STARTUP \\ Cannot connect to $host $msg"); + } + + &askUser(); + } + else{ + print "Connection to hosts is OK.\n"; + } + + #---------- Check connection to command servers ------------- +# print "Check connection to command servers...\n"; + +# my @dead_cservers = (); + +# &checkCmdServers(\@alive_hosts, \@dead_cservers); + + if( @dead_cservers ){ + print "Cannot connect to command servers for the hosts:\n"; + + foreach my $host (@dead_cservers){ + print "$host\n"; + system("logger -p local1.info -t DAQ STARTUP \\ Cannot connect to command server at $host"); + } + + print "I will try to restart the command servers\n"; + + &restartCmdServers(\@dead_cservers); + + @dead_cservers = (); + + &pingHosts(\@alive_hosts, \@dead_cservers); + + if( @dead_cservers ){ + print "Still cannot connect to command servers for the hosts:\n"; + + foreach my $host (@dead_cservers){ + print "$host\n"; + } + + print "Try to start \'command_server -p 4712 &\' on these hosts by hand.\n"; + print "Exit.\n"; + exit(0); + } + else{ + print "Missing command_servers have been started! Continue...\n"; + sleep(2); + } + + } + else{ + print "Connection to command servers is OK.\n"; + } + if( @dead_hosts ){ + &rmDeadHosts(\@dead_hosts); + } +} + +sub rmDeadHosts() +{ + my ($dead_hosts_aref) = @_; + + #my $copy = clone($some_ref); + + foreach my $sys (%$trb_href){ + + next unless( defined @{$trb_href->{$sys}} && $#{$trb_href->{$sys}} > 0 ); + + foreach my $host (@$dead_hosts_aref){ + @{$trb_href->{$sys}} = grep { !($_ eq $host) } @{$trb_href->{$sys}}; + } + } +} + + + +sub promptUser { +#----------------------------( promptUser )----------------------------- +# +# FUNCTION: promptUser +# +# PURPOSE: Prompt the user for some type of input, and return the +# input back to the calling program. +# +# ARGS: $promptString - what you want to prompt the user with +# $defaultValue - (optional) a default value for the prompt +# +# EXAMPLES: +# $username = &promptUser("Enter the username "); +# $password = &promptUser("Enter the password "); +# $homeDir = &promptUser("Enter the home directory ", "/home/$username"); +# print "$username, $password, $homeDir\n"; +# +#------------------------------------------------------------------------- + # two possible input arguments - $promptString, and $defaultValue + # make the input arguments local variables. + + my ($promptString,$defaultValue) = @_; + + # if there is a default value, use the first print statement; if + # no default is provided, print the second string. + + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + my $input = ; # get the input from STDIN (presumably the keyboard) + + # remove the newline character from the end of the input the user gave us + + chomp($input); + + # if we had a $default value, and the user gave us input, then + # return the input; if we had a default, and they gave us no + # no input, return the $defaultValue. + # + # if we did not have a default value, then just return whatever + # the user gave us. if they just hit the key, + # the calling routine will have to deal with that. + + if ("$defaultValue") { + return $input ? $input : $defaultValue; # return $input if it has a value + } else { + return $input; + } +} + +sub pingHosts() +{ + my ($alive_hosts_aref, $dead_hosts_aref) = @_; + my @thread_list = (); + my @host_tmp_list = (); + + foreach my $sys (%$trb_href){ + foreach my $host ( @{$trb_href->{$sys}} ){ + + next if(any {$host eq $_} @host_tmp_list); # Exclude hosts which were already checked + push(@thread_list, threads->new( \&pingHost, $host)); + push(@host_tmp_list, $host); + } + } + + #- Join threads + my $retcode; + + foreach my $t (@thread_list){ + $retcode = $t->join(); + + next if($retcode eq -1); + + my ($host, $hstat) = split(/:/, $retcode); + + if( $hstat eq "alive" ){ + push( @$alive_hosts_aref, $host ); + } + elsif( $hstat eq "dead" ){ + push( @$dead_hosts_aref, $host ); + } + elsif( $hstat eq "cmdserverdead" ){ + push( @$alive_hosts_aref, $host ); + push( @dead_cservers, $host ); + } + else{ + print "ping $host returned unknown status: $hstat. Exit.\n"; + exit(0); + } + } +} + +sub pingHost() +{ + my ($host) = @_; + + my $retval = "undef"; +# print $host." ".Time::HiRes::time()."\n" ; + my $p = Net::Ping->new(); + + if( $p->ping($host,1) ){ + $retval = "$host:alive"; + } + else{ + $retval = "$host:dead"; + return $retval; + } + $p->close(); +# print $host." ".Time::HiRes::time()."\n" ; + #Jan 06.01.12 + my $sock = new IO::Socket::INET ( + PeerAddr => $host, + PeerPort => $cmd_server_port, + Proto => 'tcp'); + $retval = "$host:cmdserverdead" unless $sock; + close($sock) if( defined $sock ); + #Jan 06.01.12 +#print $host." ".Time::HiRes::time()."\n" ; + return $retval; +} + +# sub checkCmdServers() +# { +# my ($alive_hosts_aref, $dead_cservers_aref) = @_; +# +# foreach my $host (@$alive_hosts_aref){ +# my $sock = new IO::Socket::INET ( +# PeerAddr => $host, +# PeerPort => $cmd_server_port, +# Proto => 'tcp'); +# push( @$dead_cservers_aref, $host ) unless $sock; +# close($sock) if( defined $sock ); +# } +# } + +sub execViaExpect() +{ + my ($etrax, $path, $cmd, $args, $log) = @_; + + my $exe = "$expect_script $etrax $path $cmd $args > $log 2>&1"; + print "exe: $exe\n" if($opt_verb); + system($exe) unless($opt_test); +} + +sub restartCmdServers() +{ + my ($dead_cservers_aref) = @_; + + my $path = "/home/hadaq/bin/"; + + foreach my $host (@$dead_cservers_aref){ + my $log = $log_dir . "/expect_" . $host . ".log"; + &execViaExpect( $host, $path, "command_server", "\'-p 4712 &\'", $log); + } +} + +sub data2ora() +{ + + #- Read unique IDs + my @id_list = `trbcmd i 0xffff`; + + foreach my $id_line (@id_list){ + + if( $id_line =~ /failed/ ){ + print "ERROR: data2ora(): 'daqop read ids' failed! Exit.\n"; + exit(1); + } + + if( $id_line =~ /0x(\w+)\s+0x(\w+)\s+0x(\w+)/ ){ + my $addr = lc($1); + my $uid = lc($2); + my $fpga = $3; + + #- There are boards with several FPGAs + # These boards have identical Ids but several different + # trbnet addresses (three addresses for the board with three FPGAs) + # The smallest address is of importance for us because it is an address + # of FPGA which sends the data out (uplink). Thus the smallest + # address is the address of the data source. + if( defined $data2ora_href->{"BOARDID"}->{$uid} ){ + if( hex($addr) < hex($data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'}) ){ + $data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'} = $addr; + } + } + else{ + $data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'} = $addr; + } + } + } + + #-------- Write data to a file to be passed to Oracle + + my $timestamp = &timeStamp(); + my $ora_file = "/home/hadaq/oper/daq2ora/daq2ora_" . $timestamp . ".txt"; + my $current_file = "/home/hadaq/oper/daq2ora/daq2ora_current.txt"; + + #- Read settings with resolution mode of TRBs + my $TDCsettings_href = &readTRBTDCsettings(); + + open( FILE, '>', $ora_file ) or die "Could not open $ora_file: $!" if($opt_ora eq "file"); + + #- Write threshold file names + my $line_thresh = &cpThresholds($timestamp); + if( $line_thresh =~ /loaded_thresholds/){ + #print FILE $line_thresh; + } + + foreach my $uid ( sort keys %{$data2ora_href->{"BOARDID"}} ){ + my $addr = $data2ora_href->{"BOARDID"}->{$uid}->{'ADDR'}; + my $subevtid; + + if( any {lc($_) eq lc($addr)} @subEvtIds ){ + $subevtid = lc($addr); + } + else{ + $subevtid = "NULL"; + } + + #- Get TRB resolution mode (returns 0 if the board is not TRB) + my $mode = &getTRBResolutionMode($TDCsettings_href, lc($addr)); + + my $outdata = sprintf("%19s %6s %6s %4s", $uid, $addr, $subevtid, $mode); + + print "data2ora: $outdata\n" if($opt_ora eq "file" && $opt_verb); + print FILE "$outdata\n" if($opt_ora eq "file"); + + #- If mode == 0x00 it not necessary to write these zeros to the register + # because '00' is the default value of the register. + unless( $mode eq "NULL" || $mode == 0 ){ + my $cmd = "/home/hadaq/scripts/set_modrc.sh 0x$mode 0x$addr 0xa0c2"; + #my $host = @{$trb_href->{"scs"}}[0]; # CTS Etrax name; + my $host = "hadesp31"; # pexor slow control interface; + my $log = $log_dir . "/mode/modrc_" . $host . ".log"; + &connectCmdServer($cmd, $host, $cmd_server_port, $cmd_server_prtcl, $log); + } + } + + if( defined $data2ora_href->{"MDC"}->{"THRESH_VERS"} ){ + my $var = $data2ora_href->{"MDC"}->{"THRESH_VERS"}; + print FILE "mdc_thresh_version $var\n" if($opt_ora eq "file"); + } + + if( defined $data2ora_href->{"MDC"}->{"TDCMASK_VERS"} ){ + my $var = $data2ora_href->{"MDC"}->{"TDCMASK_VERS"}; + print FILE "mdc_tdcmask_version $var\n" if($opt_ora eq "file"); + } + + if( defined $data2ora_href->{"RICH"}->{"THRESH_VERS"} ){ + my $var = $data2ora_href->{"RICH"}->{"THRESH_VERS"}; + print FILE "rich_thresh_version $var\n" if($opt_ora eq "file"); + } + + close( FILE ) or die "Could not close $ora_file: $!" if($opt_ora eq "file"); + + system("cp $ora_file $current_file") if($opt_ora eq "file"); +} + +sub readTRBTDCsettings() +{ + #-------- Read TRB TDC settings + my $config_file = "/var/diskless/etrax_fs/trbtdctools/config/TRB_TDC_settings.conf"; + + my $TDCsettings_href; + + unless( $TDCsettings_href = do $config_file ){ + die "Couldn't parse $config_file: $@, stopped" if $@; + die "Couldn't do $config_file: $!, stopped" unless defined $TDCsettings_href; + die "Couldn't run $config_file, stopped" unless $TDCsettings_href; + } + + return $TDCsettings_href; +} + +sub getTRBResolutionMode() +{ + my ($TDCsettings_href, $addr) = @_; + + my $mode; + + my $board_type; + my $board_sysType; + &boardSysType(lc($addr), \$board_type, \$board_sysType); + + if( $board_type eq "TRB" && $board_sysType ne "CTS" && (&excludeBoards($addr)) ){ + my $serial = &addr2serial(lc($addr)); + $mode = &resMode($TDCsettings_href, $serial); + } + else{ + $mode = "NULL"; + } + + return $mode; +} + +sub resMode() +{ + my ($TDCsettings_href, $serial) = @_; + + my $trbname = sprintf("TRB_%03d", $serial); + + my $mrcc_a = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_A'}->{'mode_rc_compression'}; + my $mrc_a = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_A'}->{'mode_rc'}; + my $mrcc_b = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_B'}->{'mode_rc_compression'}; + my $mrc_b = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_B'}->{'mode_rc'}; + my $mrcc_c = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_C'}->{'mode_rc_compression'}; + my $mrc_c = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_C'}->{'mode_rc'}; + my $mrcc_d = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_D'}->{'mode_rc_compression'}; + my $mrc_d = $TDCsettings_href->{$trbname}->{'TDC'}->{'TDC_D'}->{'mode_rc'}; + + my $mode_undefined = 0; + + unless( defined $mrcc_a ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_A: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_a ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_A: mode_rc is not defined! Exit.\n"; + } + unless( defined $mrcc_b ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_B: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_b ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_B: mode_rc is not defined! Exit.\n"; + } + unless( defined $mrcc_c ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_C: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_c ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_C: mode_rc is not defined! Exit.\n"; + } + unless( defined $mrcc_d ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_D: mode_rc_compression is not defined! Exit.\n"; + } + unless( defined $mrc_d ){ + $mode_undefined = 1; + print "ERROR: $trbname, TDC_D: mode_rc is not defined! Exit.\n"; + } + + #- All four TDCs must have identical modes + unless( $mode_undefined ){ + unless( $mrcc_a == $mrcc_b && $mrcc_a == $mrcc_c && $mrcc_a == $mrcc_d && + $mrc_a == $mrc_b && $mrc_a == $mrc_c && $mrc_a == $mrc_d ){ + print "ERROR: $trbname, resolution modes must be identical for all four TDCs! Exit.\n"; + } + } + + if( $mode_undefined ){ + exit(1); + } + + # Description of the resolution modes: + # + # mrcc = mode_rc_compression + # mrc = mode_rc + # + # mrcc mrc mode + # 0 0 00 - high resolution mode (100ps binning) + # 1 1 01 - very high resolution mode (25ps binning) + # 0 1 02 - very high resolution mode calibration data + # (one hit produces 4 data words like in high resolution mode) + + my $mode; + + if( $mrcc_a eq "0" && $mrc_a eq "0" ){ + $mode = "00"; + } + elsif( $mrcc_a eq "1" && $mrc_a eq "1" ){ + $mode = "01"; + } + elsif( $mrcc_a eq "0" && $mrc_a eq "1" ){ + $mode = "02"; + } + else{ + print "ERROR: $trbname, resolution modes have wrong values! Exit.\n"; + } + + return $mode; +} + +sub addr2serial() +{ + my ($addr) = @_; + + my $serial; + + my $addr_hex = "0x" . lc($addr); + + foreach my $key ( keys %$addr_db_conf_href ){ + if( $addr_db_conf_href->{$key}->{'addr'} eq $addr_hex ){ + unless( defined $addr_db_conf_href->{$key}->{'serial'} ){ + next; + } + + $serial = $addr_db_conf_href->{$key}->{'serial'}; + last; + } + } + + unless( defined $serial ){ + print "ERROR: addr2serial(): unknown serial number for address $addr. Exit.\n"; + exit(1); + } + + return $serial; +} + +sub checkShowerNORPC() +{ + my ($trb) = @_; + + my $retVal = 0; + + unless(defined $trb_href->{'rpc'}){ + if(any {$trb eq $_} @{$trb_href->{'shower'}}){ + $retVal = 1; + } + } + + return $retVal; +} + +sub serial2addrAndSysType() +{ + my ($serial, $board_type) = @_; + + # There is no direct connection between serial number + # and TRB-Net address. One should provide board type + # in addition to serial number. + + my $addr; + my $bType; + my $bSysType; + + foreach my $key ( keys %$addr_db_conf_href ){ + next unless( defined $addr_db_conf_href->{$key}->{'serial'} ); + next unless( defined $addr_db_conf_href->{$key}->{'trb'} ); + + if( $addr_db_conf_href->{$key}->{'serial'} == $serial && + $addr_db_conf_href->{$key}->{'serial'} == $addr_db_conf_href->{$key}->{'trb'} ){ + unless( defined $addr_db_conf_href->{$key}->{'addr'} ){ + next; + } + + $addr = $addr_db_conf_href->{$key}->{'addr'}; + + &boardSysType($addr, \$bType, \$bSysType); + + next unless($bType eq $board_type); + + last; + } + } + + unless( defined $addr ){ + print "ERROR: serial2addr(): unknown address for serial number $serial.\n"; + #exit(1); + } + + unless( defined $bSysType ){ + print "ERROR: serial2addr(): unknown board system type for serial number $serial.\n"; + #exit(1); + } + + my $retval = ""; + if( defined $addr && defined $bSysType ){ + $retval = "addr: $addr type: $bSysType"; + } + + return $retval; +} + +sub excludeBoards() +{ + my ($addr) = @_; + + # This subroutine excludes boards which have unused TDCs + # and those TDCs must not be configured. Moreover the corresponding + # register should not be overwritten with TDC resoltuion mode value. + + # Exclude all CTS and SCS boards + my $board_sys; + my $retval = 1; + + foreach my $sys ( keys %$addressRange_href ){ + my $addr_min = lc($addressRange_href->{$sys}->{'MIN'}); + my $addr_max = lc($addressRange_href->{$sys}->{'MAX'}); + + if( hex(lc($addr)) >= hex($addr_min) && hex(lc($addr)) <= hex($addr_max) ){ + $board_sys = $addressRange_href->{$sys}; + last; + } + } + + unless( defined $board_sys ){ + print "TRB-Net address $addr is outside of the known address ranges! Exit.\n"; + exit(0); + } + + if( $board_sys eq "CTS" || $board_sys eq "SCS" ){ + $retval = 0; + } + + return $retval; +} + +sub boardSysType() +{ + my ($addr, $bType_ref, $bSysType_ref) = @_; + + foreach my $sys ( keys %$addressRange_href ){ + my $addr_min = lc($addressRange_href->{$sys}->{'MIN'}); + my $addr_max = lc($addressRange_href->{$sys}->{'MAX'}); + + if( hex(lc($addr)) >= hex($addr_min) && hex(lc($addr)) <= hex($addr_max) ){ + $$bType_ref = $addressRange_href->{$sys}->{'TYPE'}; + $$bSysType_ref = $sys; + last; + } + } + + unless( defined $$bType_ref ){ + print "ERROR: boardSysType(): unknown board type for address $addr.\n"; + $$bType_ref = "undef"; + } + + unless( defined $$bSysType_ref ){ + print "ERROR: boardSysType(): unknown board system type for address $addr.\n"; + $$bSysType_ref = "undef"; + } +} + +sub boardType() +{ + my ($addr) = @_; + + my $board_type; + + foreach my $sys ( keys %$addressRange_href ){ + my $addr_min = lc($addressRange_href->{$sys}->{'MIN'}); + my $addr_max = lc($addressRange_href->{$sys}->{'MAX'}); + + if( hex(lc($addr)) >= hex($addr_min) && hex(lc($addr)) <= hex($addr_max) ){ + $board_type = $addressRange_href->{$sys}->{'TYPE'}; + last; + } + } + + unless( defined $board_type ){ + print "ERROR: boardType(): unknown board type for address $addr. Exit.\n"; + exit(1); + } + + return $board_type; +} + +sub timeStamp() +{ + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($seconds1); + my $timestamp = sprintf("%4d-%02d-%02d_%02d.%02d.%02d", + $year+1900, $mon+1, $mday, $hour, $min, $sec); + + return $timestamp; +} + +sub scanLogs() +{ + #- Check the log files which were created + # after DAQ restart (after $seconds) + + opendir(DIR, $log_dir) or die "Could not open $log_dir: $!";; + my @logfile_list = grep(/^log/, readdir(DIR)); + closedir(DIR); + + #- Sort files by modification date + @logfile_list = sort { -M "$log_dir/$a" <=> -M "$log_dir/$b" } (@logfile_list); + + my $errorFound = 0; + + foreach my $file (@logfile_list){ + + #- Modification date in seconds since EPOCH + my $seconds2 = (stat "$log_dir/$file")[9]; + + if( $seconds2 > $seconds1 ){ + if(&scanLogFile("$log_dir/$file")){ + $errorFound = 1; + } + } + } + + if($errorFound){ + &askUser(); + } + + #- Update time. + # We want to look only at the log files + # which were not checked before. + $seconds1 = time; +} + +sub scanLogFile() +{ + my ($logFile) = @_; + + my $retval = 0; + + open(DAT, $logFile) || die("Could not open $logFile!"); + my @log_data = ; + close(DAT); + + if( any {$_ =~ /TX Busy/} @log_data ){ + print "Found \'TX Busy\' in $logFile. Press Ctrl-C and try again!\n"; + system("logger -p local1.info -t DAQ STARTUP \\ Found \'TX Busy\' in $logFile"); + $retval = 1; + } + + if( any {$_ =~ /Verification Failure/} @log_data ){ + print "Found \'Verification Failure\' in $logFile. Problem with jam-programming?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ Found \'Verification Failure\' in $logFile"); + $retval = 1; + } + + if( any {$_ =~ /Fifo not empty/} @log_data ){ + print "Found \'Fifo not empty\' in $logFile. Problem with TRB-Net?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ \'Fifo not empty\' in $logFile"); + $retval = 1; + } + + if( any {$_ =~ /command not found/} @log_data ){ + print "Found \'command not found\' in $logFile. Problem with environment settings?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ \'command not found\' in $logFile"); + $retval = 1; + } + + if( any {$_ =~ /file not found/} @log_data ){ + print "Found \'file not found\' in $logFile. Problem with environment settings?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ \'file not found\' in $logFile"); + $retval = 1; + } + + if( any {$_ =~ /No such file or directory/} @log_data ){ + print "Found \'No such file or directory\' in $logFile. Problem with missing file?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ \'No such file or directory\' in $logFile"); + $retval = 1; + } + + if( any {$_ =~ /Permission denied/} @log_data ){ + print "Found \'Permission denied\' in $logFile. Problem with permission settings?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ \'Permission denied\' in $logFile"); + $retval = 1; + } + if( any {$_ =~ /RPC/} @log_data ){ + print "Found \'Remote Procedure Call (RPC) Error\' in $logFile. Problem with trbnet deamon?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ \'Remote Procedure Call (RPC) Error\' in $logFile"); + $retval = 1; + } + if( any {$_ =~ /(DMA|SEMAPHORE|PEXOR)/i} @log_data ){ + print "Found \'DMA/Semaphore/Pexor Error\' in $logFile. Problem with PEXOR?\n"; + system("logger -p local1.info -t DAQ STARTUP \\ \'Logfile shows DMA/Semaphore/Pexor Error\' in $logFile"); + $retval = 1; + } + + return $retval; +} + +sub forkStatusServer() +{ + my $child = fork(); + + if( $child ){ # parent + } + elsif( $child == 0 ) { # child + &statusServer(); + exit(0); # exit child + } + else{ + print "Could not fork statusServer: $!\n"; + exit(1); + } + + return $child; +} + +sub statusServer() +{ + + #- socket for broadcast + my $sock_udp = IO::Socket::INET->new(PeerPort => 1960, + PeerAddr => "192.168.103.255", + Proto => 'udp', + LocalAddr => "192.168.100.50", + Broadcast => 1, + Reuse => 1) + or die "Can't bind : $@\n"; + + #- Inform all clients that DAQ is being restarted + $sock_udp->send("STARTING") or die("Socket send error $!"); + close($sock_udp); + + #- Start TCP server + my $sock = new IO::Socket::INET( LocalAddr => "192.168.100.50", + LocalPort => 1972, + Proto => 'tcp', + Listen => SOMAXCONN, + Reuse => 1); + + $sock or die "Cannot bind socket :$!"; + + STDOUT->autoflush(1); + + my($new_sock, $buf); + + my $selector = new IO::Select( $sock ); + + while(1) { + + # wait 3 seconds for connections + while (my @file_handles = $selector->can_read( 3 )) { + + foreach my $file_handle (@file_handles) { + + if($file_handle == $sock) { + + # create a new socket for this transaction + unless (defined( $new_sock = $sock->accept() )) + { + print "statusServer: ERROR - Cannot open socket to send status!\n"; + return; + } + + while (defined($buf = <$new_sock>)) { + #print "client asked: $buf"; + if($buf =~ /MON_HUB: STILL STARTING\?/){ + $new_sock->send("STARTING\n") or die("Socket send error $!"); + } + + unless( kill(0, $parent_pid) ){ + print "Exit status server thread.\n"; + close( $new_sock ); + close( $sock ); + exit(0); + } + } + + close( $new_sock ); + } + } + + unless( kill(0, $parent_pid) ){ + print "Exit status server thread.\n"; + close( $sock ); + exit(0); + } + } + + unless( kill(0, $parent_pid) ){ + print "Exit status server thread.\n"; + close( $sock ); + exit(0); + } + } +} + +sub closeEBs() +{ + print "Kill EBs..."; + system("cd ../evtbuild/; ./start_eb_gbe.pl -e stop -n 1-16"); + print "\n"; +} + +sub startEBs() +{ + print "Start EBs...\n"; + system("cd ../evtbuild/; ./start_eb_gbe.sh"); + print "\n"; +} diff --git a/main/startup_briccolage.sh b/main/startup_briccolage.sh new file mode 100755 index 0000000..6a509f4 --- /dev/null +++ b/main/startup_briccolage.sh @@ -0,0 +1,362 @@ +#!/bin/bash +notifyall.sh "DAQ" " DAQ is going to be restarted." "STARTUP" & + +#Stop monitoring scripts + echo " Killing log-scripts" + ssh hades33 "cd /home/hadaq/trbsoft/hadesdaq/hmon; ./stop.sh" & + ssh hades33 "killall -USR1 speakdaemon.pl" & + killall mdc_calibration_masks.pl; + + +#Stop Eventbuilder + echo " Killing EB, scheduling restart"; + ./restartEB.sh >/dev/null 2>/dev/null & + + export DAQOPSERVER=hadesp31 + echo " Pexor clean-up..." + #set DMA transfer size, flush buffers, reset DMA core" + ssh hades31 "pkill -USR1 trbnetd 2>/dev/null; killall trbcmd 2>/dev/null; trbcmdlocal W 0x703 0x20; trbcmdlocal f 3; trbcmdlocal W 0x702 2;" + echo " Doing Reset..." + ssh hades31 "tryreset.pl; pkill -USR2 trbnetd" + ssh hades31 "pgrep trbnetd 1>/dev/null || trbnetd" + + echo " Enable ports..." + +# switchport.pl 0x1040 0 off # P0S3 missing - mounting + +#Switch on all MDC OEPs, small workaround for one broken hardware port: + switchport.pl 0x1030 0 off + switchport.pl 0xfe11 all on + switchport.pl 0x1030 0 on + trbcmd w 0x1031 0xc0 0xfbf #one hardware port is not working, but nothing connected + trbcmd w 0x1031 0xc1 0xfbf #one hardware port is not working, but nothing connected + trbcmd w 0x1031 0xc3 0xfbf #one hardware port is not working, but nothing connected + +# 2012-04-30: 10:16:00 0x223b removed from system, reinit doesnt work +# switchport.pl 0x1133 5 off + +# 2012-09-09: 0x2022 0x2233 removed as not working + switchport.pl 0x1134 5 off #0x2233 +# switchport.pl 0x1034 6 off #0x2022 +# + +# 2012-10-5: 06:50 removed, busy several times. +#switchport.pl 0x1052 3 off #0x214a + +#Retransmission on as early as possible + trbcmd setbit 0xfffd 0x22 0x08000000 #enable retransmission on oep + trbcmd setbit 0xfe11 0x22 0x08000000 #enable retransmission on mdchub + + +#Main Start-up + echo " Running Startup script" +# time ./startup.pl -f main_hades.script -eb off -o file \ +# -m TOF -m RPC -m WALL -m RICH -m SHOWER \ +# -m STARTCTS -m NORESET -m CONFIGONLY -m MON_CTS \ +# -m MDC -m MDCreg0current -m MDCnomasks -m MDCDATASET -m MDCindiv + + +#startup for MDC-tests + time ./startup.pl -f main_hades.script -eb off -o file \ + -m TOF -m RPC -m WALL -m RICH -m SHOWER \ + -m STARTCTS -m NORESET -m CONFIGONLY -m MON_CTS \ + -m MDC -m MDCreg0current -m MDCnomasks -m MDCDATASET -m MDCindiv + +######################################## +### DO NOT CHANGE ANY MDC SETTINGS HERE - without changing them in reviveoep.pl as well!!!!!! +######################################## + + +# -m MDCnomasks -m MDCDATASET -m MON_CTS -m MDCindiv \ +# -m MDC + +#All calib to EB1 +trbcmd w 0x0003 0xa0f3 0xff1 + +/home/hadaq/trbsoft/hadesdaq/utils/move_doublecpu_irq.sh & +scp /home/hadaq/oper/daq2ora/daq2ora_current.txt hades33:/home/hadaq/trbsoft/hadesdaq/hmon/files/ & + + + #Start-up finished + notifyall.sh "DAQ" " DAQ has been started." "STARTUP" & + echo " Configuration finished!" + +#Start Monitoring + echo " Restart Monitoring" + /home/hadaq/jan/crashlog.pl #Log timeouts after restart + nohup ssh hades33 "cd /home/hadaq/trbsoft/hadesdaq/hmon; ./start.sh &" /dev/null 2>/dev/null & + nohup /home/hadaq/trbsoft/hadesdaq/utils/mdc_calibration_masks.pl & + nohup ssh hades33 "sleep 20; killall -USR2 speakdaemon.pl" 1>/dev/null 2>/dev/null & + echo " Everything done. Closing window." + disown + + + +########################################### +#Old unnecessary stuff +########################################### + +# -m MDC234_p1s1245 + + +# time ./startup.pl -f main_hades.script -eb off -o file \ +# -m TOF -m RPC -m WALL -m RICH -m SHOWER \ +# -m STARTCTS -m NORESET -m CONFIGONLY -m MON_CTS \ + + +# switchport.pl 0x8501 3 off # shower sector 4 not connected correctly + +# switchport.pl 0x8001 3 off # turn off mdc12 +# switchport.pl 0x8001 4 off # turn off mdc34 + + +# stoptrigger.sh +# sleep 1; +#switchport.pl 0x8501 3 off # shower sector 4 not connected correctly +# starttrigger.sh + +# trbcmd w 0xfe11 0xc5 0x1005 +# additional MDC test stand ... MDC concentrator 0x1160 +# switchport.pl 0x8101 8 off # if there is an additional board for detector tests. Off by default +# switchport.pl 0x8111 8 off # off all additional 0x1160 MDC concentrator in the tent +# switchport.pl 0x1160 2 off # half off additional board for tests +# switchport.pl 0x1160 3 off # half off additional board for tests +# switchport.pl 0x8111 2 off #missing sector in 3/4 +# switchport.pl 0x8111 4 off #missing sector in 3/4 +# switchport.pl 0x1030 2 off +# switchport.pl 0x1030 2 on +# trbcmd w 0x1033 0xc0 0xeff +# trbcmd w 0x1033 0xc1 0xeff +# trbcmd w 0x1033 0xc3 0xeff + +#Seems to work from time to time... +# switchport.pl 0x1114 7 off #Board 2211 not connected after moving chamber + + +# switchport.pl 0x1044 1 off +# switchport.pl 0x1162 6 off + +# switchport.pl 0x8101 4 off 0 +# switchport.pl 0x8101 4 off 1 + #Shower sector 4 is switched off at the end of the file! +#Usual enable for OEPs +# switchport.pl 0xfe11 all on +# ~/trbsoft/daq/mdc/switchon_ports_loop.pl + + +# switchport.pl 0x1030 0 off +# switchport.pl 0x1030 0 on +# trbcmd w 0x1031 0xc0 0xfbf +# trbcmd w 0x1031 0xc1 0xfbf +# trbcmd w 0x1031 0xc3 0xfbf +# switchport.pl 0x1162 6 off + +######################## +##End clean-up before beamtime +######################## + + + +# cd ../evtbuild/ +# ./start_eb_gbe.pl -e stop -n 1-16 >/dev/null 2>/dev/null & +# cd ../main +# nohup ~/bin/logerrors.pl > /dev/null & +# nohup ~/bin/logmissingmbo.pl 1>/dev/null 2>/dev/null & + +#Uncomment these lines to run with TRB +# export DAQOPSERVER=hadesp31 +# echo "Doing Reset..." +# ssh hades31 "killall trbnetd; killall trbcmd; trbcmdlocal f 3; trbcmdlocal reset" & +# sleep 1; +# command_client.pl -e etraxp023 -c "monitorlock.sh lock; killall trbnetd; trbcmd reset; trbnetd; monitorlock.sh unlock" +# sleep 1; +# # ssh hades31 "trbcmd reset" +# ssh hades31 "trbnetd" +# echo "Done. Enable ports..." + +# echo "hades31"; +# ssh hades31 "killall trbnetd; trbcmd reset; sleep 3; trbnetd" & +# echo "trb"; +# command_client.pl -e etraxp023 -c "monitorlock.sh lock; killall trbnetd; t reset; sleep 3; trbnetd; monitorlock.sh unlock" +# echo "sleep"; +# sleep 3; +# echo "startup"; + +#Replaced daqop with a new script that shows error messages... +# switchport.pl 0x8111 2 off # sector 1 has been removed (outer mdc) +# switchport.pl 0x8111 4 off # sector 3 has been removed (outer mdc) + + +#0x234B is broken - workaround... JM 20110626 +#This will fail after a powercycle! +# trbcmd w 0x1140 0xc3 0xfffd +# trbcmd w 0xfe11 0xc0 0xffff #comment this line for the first restart after a powercycle +# trbcmd w 0xfe11 0xc1 0xffff #comment this line for the first restart after a powercycle +# trbcmd w 0xfe11 0xc3 0xffff #comment this line for the first restart after a powercycle +# trbcmd w 0x1140 0xc3 0xffff +# trbcmd w 0x1142 0xc0 0xffef +# trbcmd w 0x1142 0xc1 0xffef +# trbcmd w 0x1142 0xc3 0xffef +#end o f workaround +# daqop switch hub ax8111 port 6 off # some OEP has a problem 2011-06-27 + + + +# daqop switch hub ax8111 port 2 off # sector has been removed +# daqop switch hub ax8111 port 4 off # sector has been removed +# daqop switch hub ax8101 port 8 off #if there is a additional board for detector tests. Off by default +# daqop switch hub ax1160 port 2 off #plane I +# daqop switch hub ax1160 port 3 off #plane I + +# trbcmd w 0x1150 0xc0 0xfffb +# trbcmd w 0x1150 0xc1 0xfffb +# trbcmd w 0x1150 0xc3 0xfffb +# trbcmd w 0xfe11 0xc0 0xffff #comment this line for the first restart after a powercycle +# trbcmd w 0xfe11 0xc1 0xffff #comment this line for the first restart after a powercycle +# trbcmd w 0xfe11 0xc3 0xffff #comment this line for the first restart after a powercycle +# trbcmd w 0x1150 0xc3 0xffff +# trbcmd w 0x1153 0xc0 0xfffd +# trbcmd w 0x1153 0xc1 0xfffd +# trbcmd w 0x1153 0xc3 0xfffd + + +#daqop switch hub ax8111 port 8 off #someone can not decide where the additional board belongs... +#daqop switch hub ax1053 port 1 off #OEP not working since moving to meas. position 2010-11-10 + +#daqop switch hub ax1051 port 2 off #2141 +# daqop switch hub ax1051 port 4 off #2143 +#daqop switch hub ax1104 port 2 off # to turn off MB 2309 + + +#../mdc/switchon_ports_loop.pl; +#daqop switch hub ax8111 port 4 off # sector has been moved to service position + +#daqop switch hub ax8111 port 8 off # sector has been removed AT 11.03.2011 off 0x1160 + + +#daqop switch hub ax8101 port 8 off + +#MDC3/4 off to read-out only extra board +#trbcmd w 0x8111 0xc0 0xff01 +#trbcmd w 0x8111 0xc1 0xff01 +#trbcmd w 0x8111 0xc3 0xff01 + +#trbcmd w 0x8110 0xc0 0x1 +#trbcmd w 0x8110 0xc1 0x1 +#trbcmd w 0x8110 0xc3 0x1 + +# daqop switch hub ax1020 port 0 off +# daqop switch hub ax1020 port 1 off + + +#single channels test +##time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m MDC34 -m CONFIGONLY -m NORESET -m NORESTART -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS -m thresh38; +#time ./startup.pl -f main_hades.script -o file -m TOF -m NORPC -m NOWALL -m NORICH -m NOSHOWER -m STARTCTS -m CONFIGONLY -m MDC234 -m NORESET -m NORESTART -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS -m allMDCTDCoff; +#time ./startup.pl -f main_hades.script -o file -m TOF -m NORPC -m NOWALL -m NORICH -m NOSHOWER -m STARTCTS -m NORESET -m CONFIGONLY -m MDC234 -m reg0sr13nsP1 -m singleChannel -m MDCDATASET -m MON_CTS -m thresh40; + +#time ./startup.pl -f main_hades.script -o file -m NORESET -m TOF -m NOMDC -m NORPC -m WALL -m RICH -m SHOWER -m STARTCTS -m CONFIGONLY -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS -m thresh60; + +#time ./startup.pl -f main_hades.script -o file -m TOF -m NORPC -m NOWALL -m NORICH -m SHOWER -m STARTCTS -m MDC -m CONFIGONLY -m NORESET -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS -m thresh70; + +#03.03 sector not powered +#daqop switch hub ax1100 port 0 off +#daqop switch hub ax1100 port 1 off + +#daqop switch hub ax1162 port 3 off #221a off + +#test switch off AT +#daqop switch hub ax1160 port 1 off + +#daqop switch hub ax1000 port 2 off +#daqop switch hub ax1000 port 3 off + +#daqop switch hub ax1010 port 0 off +#daqop switch hub ax1010 port 1 off +#daqop switch hub ax1010 port 2 off +#daqop switch hub ax1010 port 3 off + +#daqop switch hub ax1050 port 0 off +#daqop switch hub ax1050 port 1 off +#daqop switch hub ax1050 port 2 off +#daqop switch hub ax1050 port 3 off + +# trbcmd w 0x8101 0xc0 0x100 +# trbcmd w 0x8101 0xc1 0x100 +# trbcmd w 0x8101 0xc3 0x100 + + +#daqop switch hub ax1031 port 6 off # 0x2015 ripped from MBO on 2010-10-15 +#daqop switch hub ax1104 port 5 off # 0x230c - token not back during calib. reinit stopped with token not back during readout +#daqop switch hub ax1104 port 6 off # 0x230d +#daqop switch port 4 hub ax1144 off # 0x224B +#daqop switch port 5 hub ax1153 off # 0x2354 +#daqop switch port 0 hub ax1050 off #1051 => 0x2140 .. 0x2147 +#time ./startup.pl -f main_hades.script -o file -m TOF -m NORPC -m NOWALL -m NORICH -m SHOWER -m STARTCTS -m MDC34 -m NORESET -m NORESTART -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS -m thresh40; + + + +#CTS settings moved to cts/cts_settings.trbcmd +#Configure BLR moved to cts/configure_blr.script +#Load shower pedestals moved to shower/startup.script + +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m MDC -m MDCSWITCHOFF -m MDCDATASET -m EB0 -m CONFIGONLY -m NORESET -m thresh40 ; +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m MDC134 -m MDCDATASET -m MDCindiv -m CONFIGONLY -m NORESET -m reg0sr13nsP1; +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m MDC -m MDCDATASET -m CONFIGONLY -m NORESET -m thresh60 -m reg0sroff; +#time ./startup.pl -f main_hades.script -o file -m NOTOF -m NORPC -m NOWALL -m NORICH -m NOSHOWER -m STARTCTS -m MDC134 -m MDCDATASET -m CONFIGONLY -m NORESET -m MDCindiv -m reg0sr13nsP1; +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m MDC34 -m MDCDATASET -m CONFIGONLY -m ONECHANNEL -m NORESET -m MDCindiv -m reg0sr13nsP1; +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m NOMDC -m CONFIGONLY -m NORESET -m MDCindiv -m reg0sr13nsP1 -m MDCDATASET -m ONECHANNEL -m MON_CTS; +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m NOSHOWER -m STARTCTS -m MDC34 -m MDCDATASET -m CONFIGONLY -m NORESET -m MDCindiv -m reg0sr13nsP1; +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m MDC134 -m MDCDATASET -m CONFIGONLY -m NORESET -m thresh40 -m reg0sr13nsP1; +#time ./startup.pl -f main_hades.script -o file -m NOTOF -m NORPC -m NOWALL -m NORICH -m SHOWER -m STARTCTS -m NOMDC34 -m NOMDCDATASET -m CONFIGONLY -m ONECHANNEL -m NORESET -m MDCindiv -m reg0sr13nsP1; +#time ./startup.pl -f main_hades.script -o file -m TOF -m NORPC -m WALL -m RICH -m SHOWER -m STARTCTS -m NOMDC -m NORESET -m MDCindiv -m reg0sr13nsP1 -m MDCDATASET -m ONECHANNEL -m MON_CTS; +#time ./startup.pl -f main_hades.script -o file -m NOTOF -m NORPC -m NOWALL -m RICH -m SHOWER -m STARTCTS -m MDC34 -m NORESET -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS -m thresh60; +#time ./startup.pl -f main_hades.script -o file -m NOTOF -m NORPC -m NOWALL -m RICH -m SHOWER -m STARTCTS -m MDC34 -m NORESET -m MDCindiv -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS; +#time ./startup.pl -f main_hades.script -o file -m NOTOF -m NORPC -m WALL -m RICH -m SHOWER -m STARTCTS -m MDC34 -m NORESET -m MDCindiv -m reg0sr13nsP1 -m MDCDATASET -m MON_CTS; +#time ./startup.pl -f main_hades.script -o file -m TOF -m RPC -m WALL -m RICH -m SHOWER -m STARTCTS -m NOMDC -m NORESET -m MDCindiv -m reg0sr13nsP1 -m MDCDATASET -m ONECHANNEL -m MON_CTS; + + +# +#sleep 1 +#command_client.pl -e etraxp058 -c "rw_trbv2 --addon r 0 0; rw_trbv2 --addon w 0 e1 01; #rw_trbv2 --addon w 0 e2 10; rw_trbv2 --addon w 0 e3 fff" +#daqop switch hub port 3 ax8501 off +#daqop switch hub port 3 ax8111 off # switch off sector 3 outer MDC + +#####daqop switch hub port 3 ax8100 off # switch off inner MDC + + +#daqop switch hub port 1 ax8801 off # switch off start + + +#d switch hub ax1120 off port 0 +#d switch hub ax1120 off port 1 + +#command_client.pl -e etraxp058 -c "jam_trbv2 --addon -aFP /home/hadaq/cts/18082010_cts_fpga1.stp" +#command_client.pl -e etraxp058 -c "jam_trbv2 --addon -aFP /home/hadaq/cts/20100819_cts_fpga2.stp" + + +# trbcmd w 0x0003 0xA0f0 0xffe777 #lxhadeb04 is excluded + +# trbcmd w 0x0003 0xA0f1 0x20 #Events per EB +# trbcmd w 0x0003 0xA0f0 0xff00ff #15 - 0 EB enable , 31 - 16 downscale of RPC/TOF TDC trailers and headers +# command_client.pl -e etraxp058 -c " +# rw_trbv2 --addon r 0 0; +# #rw_trbv2 --addon w 0 e1 f; #EB enable +# #rw_trbv2 --addon w 0 e2 20; #Events per EB +# rw_trbv2 --addon w 0 e3 0; #Pulser (100MHz/value) (0 is off) +# rw_trbv2 --addon w 0 e4 700; #Trigger Information +# rw_trbv2 --addon w 0 e5 21; #Start delay +# rw_trbv2 --addon w 0 e6 02; #PT delay +# #rw_trbv2 --addon w 0 c0 4220; #Trigger settings 5: MDC, 6:Shw ped, 8:shw cal, 9: 0xE, 14 enable beam inhibit input-> shower pedestals trigger +# rw_trbv2 --addon w 0 c1 001CB000; #16-12:MDC34 delay, 21-17: MDC12 delay +# #rw_trbv2 --addon w 0 c1 0000000; #16-12:MDC34 delay, 21-17: MDC12 delay +# rw_trbv2 --addon w 0 c2 5c6f; #Multiplexer +# rw_trbv2 --addon w 0 c3 ffffffff; #All inputs on for monitor +# rw_trbv2 --addon w 0 c5 ffff;#fff00000; #anticoincidence +# rw_trbv2 --addon w 0 c7 4000;# pt4 mdc temp trigger 3800; #Output enable +# rw_trbv2 --addon w 0 ca 4000; #PT1 downscaling +# rw_trbv2 --addon w 0 d1 22222222; #fine delay start +# rw_trbv2 --addon w 0 d9 77777777; #width of start +# rw_trbv2 --addon w 0 dc 0fff0000; #PT1 length +# "; + + diff --git a/main/subevtids.db b/main/subevtids.db new file mode 100644 index 0000000..7dc475d --- /dev/null +++ b/main/subevtids.db @@ -0,0 +1,35 @@ +# subEvtId System + +0x0001 #CTS +0x1000 #MDC-AddOn +0x1010 #MDC-AddOn +0x1020 #MDC-AddOn +0x1030 #MDC-AddOn +0x1040 #MDC-AddOn +0x1050 #MDC-AddOn +0x1100 #MDC-AddOn +0x1110 #MDC-AddOn +0x1120 #MDC-AddOn +0x1130 #MDC-AddOn +0x1140 #MDC-AddOn +0x1150 #MDC-AddOn +0x3200 #SHW-AddOn +0x3210 #SHW-AddOn +0x3220 #SHW-AddOn +0x3230 #SHW-AddOn +0x3240 #SHW-AddOn +0x3250 #SHW-AddOn +0x8000 #Hub2 +0x8100 #Hub2 +0x8110 #Hub2 +0x8300 #Hub2 +0x8310 #Hub2 +0x8320 #Hub2 +0x8400 #Hub2 +0x8410 #Hub2 +0x8500 #Hub2 +0x8600 #Hub2 +0x8700 #Hub2 +0x8800 #Hub2 +0x8900 #Pion1 +0x8910 #Pion2 -- 2.43.0