control
cts
evtbuild
+hub
+main
Directories to check:
-hub
-main
mdc
monitor
oracle
#!/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
source /home/hadaq/.bash_profile
echo \" <Startup> Connected to lxhadesdaq...\"
echo \" <Startup> Starting DAQ with default settings...\"
- cd /home/hadaq/trbsoft/hadesdaq/main/
+ cd /home/hadaq/trbsoft/daq/main/
time bash ./startup_briccolage.sh
sleep 10
"
--- /dev/null
+#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
+
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+
+#################################################
+# 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
+#########################
+
--- /dev/null
+#!/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/name>] : Path to main config file.
+ [-b|--eb] : Start event builder.
+ [-r|--rdo] : Start readout.
+ [-e|--etrax <name>] : Etrax name.
+ [-m|--macro <name>] : 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 <null|
+ file>] : 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 = <<EOF;
+#!/usr/bin/expect -f
+
+# This script is automatically generated by startup.pl
+# Do not edit, the changes will be lost.
+
+# Print args
+send_user "\$argv0 [lrange \$argv 0 \$argc]\\n"
+
+# Get args
+#
+# host : etrax name
+# path : path to executable
+# bin : executable name
+# opt : args for executable
+#
+if {\$argc>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 = <STDIN>; # 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 <enter> 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 = <DAT>;
+ 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;
+}
--- /dev/null
+#!/bin/bash
+cd /home/hadaq/trbsoft/daq/evtbuild/
+./start_eb_gbe.pl -e stop -n 1-16
+sleep 10
+./start_eb_gbe.sh
--- /dev/null
+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
+
--- /dev/null
+#!/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/name>] : Path to main config file.
+ [-b|--eb <on>|<off>] : Automatic restart of EBs (default: on).
+ [-r|--rdo] : Start readout.
+ [-e|--etrax <name>] : Etrax name.
+ [-m|--macro <name>] : 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 <null|
+ file>] : 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 = <<EOF;
+#!/usr/bin/expect -f
+
+# This script is automatically generated by startup.pl
+# Do not edit, the changes will be lost.
+
+# Print args
+send_user "\$argv0 [lrange \$argv 0 \$argc]\\n"
+
+# Get args
+#
+# host : etrax name
+# path : path to executable
+# bin : executable name
+# opt : args for executable
+#
+if {\$argc>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 \\<E\\> 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 \\<E\\> 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 = <STDIN>; # 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 <enter> 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 = <DAT>;
+ 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 \\<E\\> 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 \\<E\\> 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 \\<E\\> \'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 \\<E\\> \'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 \\<E\\> \'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 \\<E\\> \'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 \\<E\\> \'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 \\<E\\> \'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 \\<E\\> \'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";
+}
--- /dev/null
+#!/bin/bash
+notifyall.sh "DAQ" "<I> DAQ is going to be restarted." "STARTUP" &
+
+#Stop monitoring scripts
+ echo " <Logger> 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 " <EB> Killing EB, scheduling restart";
+ ./restartEB.sh >/dev/null 2>/dev/null &
+
+ export DAQOPSERVER=hadesp31
+ echo " <TrbNet> 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 " <TrbNet> Doing Reset..."
+ ssh hades31 "tryreset.pl; pkill -USR2 trbnetd"
+ ssh hades31 "pgrep trbnetd 1>/dev/null || trbnetd"
+
+ echo " <TrbNet> 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 " <Startup> 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" "<N> DAQ has been started." "STARTUP" &
+ echo " <Startup> Configuration finished!"
+
+#Start Monitoring
+ echo " <Startup> Restart Monitoring"
+ /home/hadaq/jan/crashlog.pl #Log timeouts after restart
+ nohup ssh hades33 "cd /home/hadaq/trbsoft/hadesdaq/hmon; ./start.sh &" </dev/null 1>/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 " <Startup> 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
+# ";
+
+
--- /dev/null
+# 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