mspbsldump/logtracer.py

118 lines
4.1 KiB
Python
Executable File

#!/usr/bin/env python3
import datetime
import serial
import sys
from typing import *
class Rec(NamedTuple):
cycle: int
delta: int
pc: int
sp: int
sr: int
gp: List[int]
stack: List[int]
def __str__(self):
a = "cycle: %d (%d)" % (self.cycle, self.delta)
b = "pc = %05x sp = %05x sr = %03x" % (self.pc, self.sp, self.sr)
gp1 = " ".join(("%sr%d: %05x" % ((" " if d < 6 else ""), d+4, self.gp[d])) for d in range(6))
gp2 = " ".join(("%sr%d: %05x" % ((" " if d < 6 else ""), d+4, self.gp[d])) for d in range(6,12))
stack = " ".join("%02x"%x for x in self.stack)
return '\n'.join([a, b, gp1, gp2, stack])
def __eq__(self, other):
if self.pc != other.pc: return False
if self.sp != other.sp: return False
if self.sr != other.sr: return False
if any(self.gp[x] != other.gp[x] for x in range(12)): return False
if any(self.stack[x] != other.stack[x] for x in range(16)): return False
return True
def __ne__(self, other):
if self.pc != other.pc: return True
if self.sp != other.sp: return True
if self.sr != other.sr: return True
if any(self.gp[x] != other.gp[x] for x in range(12)): return True
if any(self.stack[x] != other.stack[x] for x in range(16)): return True
return False
TIMEOUT = 60*60*8
with serial.Serial(sys.argv[1] if len(sys.argv) > 1 else "/dev/ttyACM1", 9600, timeout=TIMEOUT) as ser:
with open("mspbsl.log", "w", buffering=1) as log:
recs = []
while True:
# wait for "hello world"
while True:
l = ser.readline().strip()
if b"hello world!" in l:
break
# start tracing
while True:
try:
l = []
while len(l) == 0:
l = ser.readline().strip().decode('utf-8')
if len(l) == 0: continue
if "hello world" in l:
print("no!")
break # start over
#if l[0:1] != "- ":
# print("no")
# #assert False, l
# break
ticks = int(l[2:])
pcspsr = ser.readline().strip().decode('utf-8').split()
if pcspsr == ["hello", "world!"]: continue
assert len(pcspsr) == 3, pcspsr
r4to15 = ser.readline().strip().decode('utf-8').split()
if pcspsr == ["hello", "world!"]: continue
assert len(r4to15) == 12, r4to15
stack = ser.readline().strip().decode('utf-8').split()
if pcspsr == ["hello", "world!"]: continue
assert len(stack) == 16, stack
pc = int(pcspsr[0], 16)
sp = int(pcspsr[1], 16)
sr = int(pcspsr[2], 16)
gp = [int(r4to15[i],16) for i in range(12)]
stack = [int(x,16) for x in stack]
delta = -1
if len(recs) > 0:
rec_ = Rec(ticks, delta, pc, sp, sr, gp, stack)
for i in range(2, min(15, len(recs))):
if recs[-i] == recs[-1]:
continue
delta = ticks - recs[-i].cycle - 1
break
rec = Rec(ticks, delta, pc, sp, sr, gp, stack)
if len(recs) == 0 or rec != recs[-1]:
lstr = '-----\n%s' % str(rec)
log.write(lstr+'\n')
log.flush()
print(lstr)
recs.append(rec)
except UnicodeDecodeError: pass # just continue from the next one
print("\n"*4)
"""
ticks: 399
pc: 01712 sp: 03bfc sr: 00c
r4: 00123 r5: 01234 r6: 02345 r7: 03456 r8: 04567 r9: 05678
r10: 06789 r11: 0789a r12: 089ab r13: 09abc r14: 03bfc r15: 01c54
stack:
"""