Enhance readserial.py to try to account for host time offsets.
[seabios.git] / tools / readserial.py
1 #!/usr/bin/env python
2 # Script that can read from a serial device and show timestamps.
3 #
4 # Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
5 #
6 # This file may be distributed under the terms of the GNU GPLv3 license.
7
8 # Usage:
9 #   tools/readserial.py /dev/ttyUSB0 115200
10
11 import sys
12 import time
13 import select
14 import serial
15
16 # Reset time counter after this much idle time.
17 RESTARTINTERVAL = 60
18 # Alter timing reports based on how much time would be spent writing
19 # to serial.
20 ADJUSTBAUD = 1
21 # Number of bits in a transmitted byte - 8N1 is 1 start bit + 8 data
22 # bits + 1 stop bit.
23 BITSPERBYTE = 10
24
25 def readserial(infile, logfile, baudrate):
26     lasttime = 0
27     byteadjust = 0.0
28     if ADJUSTBAUD:
29         byteadjust = float(BITSPERBYTE) / baudrate
30     while 1:
31         # Read data
32         try:
33             res = select.select([infile, sys.stdin], [], [])
34         except KeyboardInterrupt:
35             sys.stdout.write("\n")
36             break
37         if sys.stdin in res[0]:
38             # Got keyboard input - force reset on next serial input
39             sys.stdin.read(1)
40             lasttime = 0
41             if len(res[0]) == 1:
42                 continue
43         d = infile.read(4096)
44         datatime = time.time()
45
46         datatime -= len(d) * byteadjust
47
48         # Reset start time if no data for some time
49         if datatime - lasttime > RESTARTINTERVAL:
50             starttime = datatime
51             charcount = 0
52             isnewline = 1
53             msg = "\n\n======= %s (adjust=%d)\n" % (
54                 time.asctime(time.localtime(datatime)), ADJUSTBAUD)
55             sys.stdout.write(msg)
56             logfile.write(msg)
57         lasttime = datatime
58
59         # Translate unprintable chars; add timestamps
60         out = ""
61         for c in d:
62             if isnewline:
63                 delta = datatime - starttime - (charcount * byteadjust)
64                 out += "%06.3f: " % delta
65                 isnewline = 0
66             oc = ord(c)
67             charcount += 1
68             datatime += byteadjust
69             if oc == 0x0d:
70                 continue
71             if oc == 0x00:
72                 out += "<00>\n"
73                 isnewline = 1
74                 continue
75             if oc == 0x0a:
76                 out += "\n"
77                 isnewline = 1
78                 continue
79             if oc < 0x20 or oc >= 0x7f and oc != 0x09:
80                 out += "<%02x>" % oc
81                 continue
82             out += c
83
84         sys.stdout.write(out)
85         sys.stdout.flush()
86         logfile.write(out)
87         logfile.flush()
88
89 def printUsage():
90     print "Usage:\n   %s [<serialdevice> [<baud>]]" % (sys.argv[0],)
91     sys.exit(1)
92
93 def main():
94     serialport = 0
95     baud = 115200
96     if len(sys.argv) > 3:
97         printUsage()
98     if len(sys.argv) > 1:
99         serialport = sys.argv[1]
100     if len(sys.argv) > 2:
101         baud = int(sys.argv[2])
102
103     ser = serial.Serial(serialport, baud, timeout=0)
104
105     logname = time.strftime("seriallog-%Y%m%d_%H%M%S.log")
106     f = open(logname, 'wb')
107     readserial(ser, f, baud)
108
109 if __name__ == '__main__':
110     main()