From: Jan Michel Date: Wed, 31 Jul 2013 15:01:18 +0000 (+0200) Subject: added unpacker for hld files. headers are read & printed X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=62deb1313e97dcd83b09a5b862eead508636ada1;p=mvdsensorcontrol.git added unpacker for hld files. headers are read & printed --- diff --git a/tools/preview/unpack_hld.pl b/tools/preview/unpack_hld.pl new file mode 100755 index 0000000..e833d2c --- /dev/null +++ b/tools/preview/unpack_hld.pl @@ -0,0 +1,399 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use Data::Dumper; +use FileHandle; +use feature "switch"; + +############################################################################### +## Configuration ############################################################## +############################################################################### + +my $SensorHeaderLength = 7; + +my $file; +my $opt_help = 0; +my $opt_verb = 0; +my $opt_debug = 0; +my $totalevents = 1E9; +my $mode = ""; + +GetOptions ('h|help' => \$opt_help, + 'f|file=s' => \$file, + 'v|verb' => \$opt_verb, + 'd|debug' => \$opt_debug, + 'e|events=i' => \$totalevents); + + + + +if($opt_help) { + printf("Usage: unpack_hld.pl \n"); + printf("[-h|--help] Show this help\n"); + printf("-f|--file Path to hld file\n"); + printf("[-v|--verb] Dump hld file content\n"); + printf("[-d|--debug] More debugging output\n"); + printf("\n"); + exit; + } + + + +############################################################################### +## HLD Reader ################################################################# +############################################################################### + + +if(&checkArgs()){ + exit(0); +} + +my @evtHeader_list = (); +my $evtHeader_aref = \@evtHeader_list; + +my @subEvtHeader_list = (); +my $subEvtHeader_aref = \@subEvtHeader_list; + +my @data_list = (); +my $data_aref = \@data_list; + +my $fh = new FileHandle("$file", "r"); + +while(1){ + @evtHeader_list = (); + + &getEvtHeader($fh,$evtHeader_aref); + &printEvtHeader($evtHeader_aref) if($opt_verb); + + my $evtSize = $evtHeader_aref->[0]; + if (!defined $evtSize || $evtSize < 0x10) {last;} + + #- If the size is only 32 Bytes -> goto to + # the next Event Header since there are no subevents + next unless defined $evtSize; + next if($evtSize == 32); + + my $size_cntr = 32; # Bytes + + while($evtSize > $size_cntr){ + + @subEvtHeader_list = (); + + my $decoding = &getSubEvtHeader($fh,$subEvtHeader_aref); + &printSubEvtHeader($subEvtHeader_aref) if($opt_verb); + + my $subEvtSize = $subEvtHeader_aref->[0]; + + $size_cntr = $size_cntr + $subEvtSize; + + #- If the size is only 16 Bytes -> goto to + # the next Sub Event Header since there are no subevents + next if($subEvtSize == 16); + + @data_list = (); + &getSubEvtData($fh, $data_aref, $subEvtSize, $decoding); + &printData($data_aref) if($opt_verb); + + my $paddedSize = &padding($fh, $subEvtSize); + + $size_cntr = $size_cntr + $paddedSize; + + #----------> User function <--------- + &analyzeData($evtHeader_aref, $subEvtHeader_aref, $data_aref); + } +} + +$fh->close(); + +exit(0); + +####################### END OF MAIN ################### + +sub printEvtHeader() +{ + my ($data_aref) = @_; + + print "\n"; + + printf("size: %08x ", $data_aref->[0]); + printf("decoding: %08x ", $data_aref->[1]); + printf("id: %08x ", $data_aref->[2]); + printf("seqNr: %08x\n", $data_aref->[3]); + + my $year = (($data_aref->[4] >> 16) & 0xff) + 1900; + my $mon = (($data_aref->[4] >> 8) & 0xff) + 1; + my $mday = ($data_aref->[4] >> 0) & 0xff; + + my $hour = ($data_aref->[5] >> 16) & 0xff; + my $min = ($data_aref->[5] >> 8) & 0xff; + my $sec = ($data_aref->[5] >> 0) & 0xff; + + printf("date: %04d-%02d-%02d ", $year, $mon, $mday); + printf("time: %02d:%02d:%02d ", $hour, $min, $sec); + printf("runNr: %08x ", $data_aref->[6]); + printf("expId: %08x\n", $data_aref->[7]); +} + +sub printSubEvtHeader() +{ + my ($data_aref) = @_; + + print "\n"; + + printf("size: %08x ", $data_aref->[0]); + printf("decoding: %08x ", $data_aref->[1]); + printf("id: %08x ", $data_aref->[2]); + printf("trigNr: %08x\n", $data_aref->[3]); +} + +sub printData() +{ + my ($data_aref) = @_; + + my $cntr = 0; + + print "\n"; + + foreach my $word (@$data_aref){ + printf("%08x ", $word); + + $cntr++; + + print "\n" if( ($cntr%4) == 0); + } +} + +sub getEvtHeader() +{ + my ($fh, $data_aref) = @_; + + my @tmp_list; + + foreach my $i (1..8){ + my $header; + + read($fh, $header, 4); + &checkEndOfFile($fh, $header); + + push(@tmp_list, $header); + } + + my $decoding = unpack("V*", $tmp_list[1]); + unless(defined $decoding) {printf "This seems to be the end\n"; return -1;} + + if($opt_debug){ + if(&getEndianess($decoding)){ + printf("\n Event Decoding: %08x Byte Order: Little Endian\n", $decoding); + } + else{ + printf("\n Event Decoding: %08x Byte Order: Big Endian\n", $decoding); + } + } + + foreach my $tmp (@tmp_list){ + my $word; + + if(&getEndianess($decoding)){ + $word = unpack("V*", $tmp); # Small Endian + } + else{ + $word = unpack("N*", $tmp); # Big Endian + } + + push(@$data_aref, $word); + } +} + +sub getSubEvtHeader() +{ + my ($fh, $data_aref) = @_; + + my @tmp_list; + + foreach my $i (1..4){ + my $header; + + read($fh, $header, 4); + &checkEndOfFile($fh, $header); + + push(@tmp_list, $header); + } + + my $decoding = unpack("V*", $tmp_list[1]); + + if($opt_debug){ + if(&getEndianess($decoding)){ + printf("\n SubEvent Decoding: %08x Byte Order: Little Endian\n", $decoding); + } + else{ + printf("\n SubEvent Decoding: %08x Byte Order: Big Endian\n", $decoding); + } + } + + foreach my $tmp (@tmp_list){ + my $word; + + if(&getEndianess($decoding)){ + $word = unpack("V*", $tmp); # Small Endian + } + else{ + $word = unpack("N*", $tmp); # Big Endian + } + + push(@$data_aref, $word); + } + + return &getEndianess($decoding); +} + +sub getEndianess() +{ + my ($decoding) = @_; + + # Return values: + # 0 : Big Endian + # 1 : Little Endian + # + # Usually (when sent by GbE-FPGAs) Event Headers are Little Endian + # SubEvent Headers and data are Big Endian + + my $retVal = 0; + + if(defined($decoding) && ($decoding & 0x000000ff) > 0){ + $retVal = 1; # This is Little Endian + } + + return $retVal; +} + +sub getSubEvtData() +{ + my ($fh, $data_aref, $size, $decoding) = @_; + + #- Subtract subevent header size and devide by word size + my $nrOfWords = ($size - 16)/4; + + foreach my $i (1..$nrOfWords){ + + my $tmp; + read($fh, $tmp, 4); + &checkEndOfFile($fh, $tmp); + + my $word; + + if(&getEndianess($decoding)){ + $word = unpack("V*", $tmp); # Little Endian + } + else{ + $word = unpack("N*", $tmp); # Big Endian + } + + push(@$data_aref, $word); + } +} + +sub padding() +{ + my ($fh, $size) = @_; + + my $retVal = 0; # Size of the padded word + + #- Check 64-bit (8-Byte) alignment + unless( ($size%8) == 0){ + my $tmp; + read($fh, $tmp, 4); + + my $word; + $word = unpack("V*", $tmp); # Little Endian + + unless($word == 0){ + #- Padding word is not zero + + printf("\n Padding word is not zero: %08x! \n", $word) if($opt_debug); + #$fh->close(); + #exit(0); + } + + $retVal = 4; # Bytes + } + + return $retVal; +} + +sub checkEndOfFile() +{ + my ($fh, $tmp) = @_; + + unless( defined $tmp){ + #- The end of the file + print "\n End of file\n"; + $fh->close(); + exit(0); + } +} + +sub checkArgs() +{ + my $retVal = 0; + + unless( defined $file){ + print "\n You must provide a path to the hld file!\n"; + print " Read help.\n"; + $retVal = 1; + } + + return $retVal; +} + + + + + + + +############################################################################### +## MVD Unpacker ############################################################### +############################################################################### + + +sub analyzeData() { + my ($evtHeader, $subEvtHeader, $data) = @_; + my $EvtId = $evtHeader->[3]; + my $pos = 0; + my $time = 0; + my $SubEvtSize = $subEvtHeader->[1]/4-6; + + while(1) { #Loop over SubSubEvents + my $RocId = $data->[$pos] & 0xffff; + my $RocLength = ($data->[$pos]>>16) & 0xffff; + if($RocId == 0x5555) {last;} + my $RocEnd = $pos + $RocLength; + $pos++; + + for(my $i = 0; $i < $SensorHeaderLength;$i++) { + for($i) { + when (1) {printf("Sensor ID: %8x\t",$data->[$pos]&0xffff);} + when (2) {printf("Status: %08x\t",$data->[$pos]);} + when (3) {printf("Error Code: %08x\t",$data->[$pos]);} + when (4) {printf("Debug: %08x\t",$data->[$pos]);} + when (5) {$time = $data->[$pos];} + when (6) {printf("Time: %08x%08x\n",$data->[$pos],$time);} + } + + $pos++; + } + + while(1) { + if($pos >= $RocEnd) {$pos++;last;} +# printf("$pos %08x\n",$data->[$pos]); + + + $pos++; + } + + + } + } +