File Coverage

blib/lib/ITM.pm
Criterion Covered Total %
statement 62 69 89.8
branch 22 28 78.5
condition 12 15 80.0
subroutine 18 21 85.7
pod 0 10 0.0
total 114 143 79.7


line stmt bran cond sub pod time code
1             package ITM;
2             our $AUTHORITY = 'cpan:GETTY';
3             # ABSTRACT: ITM/SWD deserializer
4             $ITM::VERSION = '0.002';
5 4     4   48443 use strict;
  4         9  
  4         166  
6 4     4   17 use warnings;
  4         5  
  4         113  
7 4     4   787 use bytes;
  4         15  
  4         20  
8 4     4   98 use Carp qw( croak );
  4         9  
  4         236  
9 4     4   16 use Exporter 'import';
  4         5  
  4         96  
10 4     4   13 use List::Util qw( sum );
  4         5  
  4         362  
11              
12 4     4   1418 use ITM::Sync;
  4         13  
  4         123  
13 4     4   1752 use ITM::Overflow;
  4         10  
  4         100  
14 4     4   1301 use ITM::Instrumentation;
  4         8  
  4         119  
15 4     4   1313 use ITM::HardwareSource;
  4         7  
  4         2125  
16              
17 19     19 0 72 sub ITM_SYNC { 1 }
18 13     13 0 41 sub ITM_OVERFLOW { 2 }
19 0     0 0 0 sub ITM_TIMESTAMP { 3 }
20 0     0 0 0 sub ITM_EXTENSION { 4 }
21 0     0 0 0 sub ITM_RESERVED { 5 }
22 23     23 0 62 sub ITM_INSTRUMENTATION { 6 }
23 4     4 0 27 sub ITM_HARDWARE_SOURCE { 7 }
24              
25             our @EXPORT = qw(
26              
27             ITM_SYNC ITM_OVERFLOW ITM_TIMESTAMP ITM_EXTENSION ITM_RESERVED ITM_INSTRUMENTATION ITM_HARDWARE_SOURCE
28              
29             itm_header itm_parse
30              
31             );
32              
33             sub itm_size {
34 13     13 0 17 my ( $b0, $b1 ) = @_;
35 13 100 100     77 return 1 if $b0 && !$b1;
36 8 100 66     60 return 2 if !$b0 && $b1;
37 2 50 33     22 return 4 if $b0 && $b1;
38             }
39              
40             sub itm_header {
41 21     21 0 3583 my ( $byte ) = @_;
42 21         99 my @b = split(//,unpack('b8',$byte));
43 21         47 my $bits = join('',reverse(@b));
44 21 100 100     184 if ($bits eq '00000000' || $bits eq '10000000') {
    100 100        
    100          
    50          
45 5         16 return { type => ITM_SYNC, size => 0 };
46             } elsif ($b[0] == 0 && $b[1] == 0) { # Not Instrument / Hardware Source
47 3         11 return { type => ITM_OVERFLOW, size => 0 };
48             } elsif ($b[2] == 0) {
49 11         20 return { type => ITM_INSTRUMENTATION, size => itm_size(@b[0..1]), source => ord(pack('b*',join('',@b[3..7]))) };
50             } elsif ($b[2] == 1) {
51 2         7 return { type => ITM_HARDWARE_SOURCE, size => itm_size(@b[0..1]), source => ord(pack('b*',join('',@b[3..7]))) };
52             }
53 0         0 return undef;
54             }
55              
56             sub itm_parse {
57 12     12 0 12223 my ( @args ) = @_;
58 12 50       30 if (!ref $args[0]) {
59 12         28 my ( $header_byte, @data ) = split(//,$args[0]);
60 12         25 return _itm_parse(itm_header($header_byte), join("",@data));
61             } else {
62 0         0 return _itm_parse(@args);
63             }
64 0         0 croak(__PACKAGE__."::itm_parse Unknown parameter count");
65             }
66              
67             sub _itm_parse {
68 12     12   17 my ( $header, $payload ) = @_;
69 12 50       37 if ((defined $payload ? length($payload) : 0) != $header->{size}) {
    50          
70 0         0 croak(__PACKAGE__."::itm_parse given payload doesn't fit required size");
71             }
72 12         22 delete $header->{size};
73 12 100       18 if ( $header->{type} == ITM_SYNC ) {
    100          
    100          
    50          
74 3         4 return ITM::Sync->new( %{$header} );
  3         53  
75             } elsif ( $header->{type} == ITM_OVERFLOW ) {
76 2         3 return ITM::Overflow->new( %{$header} );
  2         17  
77             } elsif ( $header->{type} == ITM_INSTRUMENTATION ) {
78 6         6 return ITM::Instrumentation->new( %{$header}, payload => $payload );
  6         118  
79             } elsif ( $header->{type} == ITM_HARDWARE_SOURCE ) {
80 1         2 return ITM::HardwareSource->new( %{$header}, payload => $payload );
  1         8  
81             }
82             }
83              
84             1;
85              
86             __END__