2 Simple Trace Parser library
4 -- fair warning, this is best to just get trace data values, I didn't see any better implementation for this, so I just made one myself
7 -- Load the traceParser library
8 local traceParser = require("trace_parse")
10 -- Parse the trace file
11 local trace_data = traceParser.parse_trace_file(filename)
13 -- Print the parsed data
14 for _, record in ipairs(trace_data) do
15 -- Format the data bytes
17 for i = 1, #record.data do
18 table.insert(data_bytes, string.format("%02X", record.data:byte(i)))
20 local data_str = table.concat(data_bytes, "")
21 print("Data: " .. data_str)
26 local bit
= require("bit") -- Requires Lua bitwise library (bit)
27 local traceParser
= {}
29 -- Function to read a 4-byte unsigned integer (little-endian)
30 local function read_u32_le(data
, pos
)
31 if pos
+ 3 > #data
then return nil, pos
end
32 local b1
, b2
, b3
, b4
= data
:byte(pos
, pos
+ 3)
33 return (b4
* 2^
24) + (b3
* 2^
16) + (b2
* 2^
8) + b1
, pos
+ 4
36 -- Function to read a 2-byte unsigned integer (little-endian)
37 local function read_u16_le(data
, pos
)
38 if pos
+ 1 > #data
then return nil, pos
end
39 local b1
, b2
= data
:byte(pos
, pos
+ 1)
40 return (b2
* 2^
8) + b1
, pos
+ 2
43 -- Function to parse a single record from the trace file
44 local function parse_record(trace
, pos
)
47 -- Read the 32-bit timestamp (4 bytes, little-endian)
48 record
.timestamp_start
, pos
= read_u32_le(trace
, pos
)
50 -- Read the 16-bit duration (2 bytes, little-endian)
51 record
.duration
, pos
= read_u16_le(trace
, pos
)
53 -- Read the 15-bit data length and 1-bit isResponse flag
54 local data_len_and_flag
, pos
= read_u16_le(trace
, pos
)
55 record
.data_len
= bit
.band(data_len_and_flag
, 0x7FFF) -- 15 bits for data length
56 record
.is_response
= bit
.rshift(data_len_and_flag
, 15) == 1 -- 1 bit for isResponse
58 -- Read the data bytes
59 record
.data
, pos
= trace
:sub(pos
, pos
+ record
.data_len
- 1), pos
+ record
.data_len
61 -- Read the parity bytes (parity length is ceil(data_len / 8))
62 local parity_len
= math
.ceil(record
.data_len
/ 8)
63 record
.parity
, pos
= trace
:sub(pos
, pos
+ parity_len
- 1), pos
+ parity_len
68 -- Function to parse the entire trace file
69 function traceParser
.parse_trace_file(file_path
)
71 local trace_file
= io
.open(file_path
, "rb")
73 if not trace_file
then
74 error("Could not open file: " .. file_path
)
77 -- Read the entire content of the file
78 local content
= trace_file
:read("*all")
81 -- Parse records in the file
83 while pos
<= #content
do
85 record
, pos
= parse_record(content
, pos
)
87 table.insert(trace_data
, record
)
89 break -- Stop if the record is invalid or incomplete