Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


imported SEABIOS source tree
[palacios.git] / bios / seabios / 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 optparse
15
16 # Reset time counter after this much idle time.
17 RESTARTINTERVAL = 60
18 # Number of bits in a transmitted byte - 8N1 is 1 start bit + 8 data
19 # bits + 1 stop bit.
20 BITSPERBYTE = 10
21
22 def calibrateserialwrite(outfile, byteadjust):
23     # Build 4000 bytes of dummy data.
24     data = "0123456789" * 4 + "012345678" + "\n"
25     data = data * 80
26     while 1:
27         st = time.time()
28         outfile.write(data)
29         outfile.flush()
30         et = time.time()
31         sys.stdout.write(
32             "Wrote %d - %.1fus per char (theory states %.1fus)\n" % (
33                 len(data), (et-st) / len(data) * 1000000, byteadjust * 1000000))
34         sys.stdout.flush()
35         time.sleep(3)
36
37 def calibrateserialread(infile, byteadjust):
38     starttime = lasttime = 0
39     totalchars = 0
40     while 1:
41         select.select([infile], [], [])
42         d = infile.read(4096)
43         curtime = time.time()
44         if curtime - lasttime > 1.0:
45             if starttime and totalchars:
46                 sys.stdout.write(
47                     "Calibrating on %d bytes - %.1fus per char"
48                     " (theory states %.1fus)\n" % (
49                         totalchars,
50                         float(lasttime - starttime) * 1000000 / totalchars,
51                         byteadjust * 1000000))
52             totalchars = 0
53             starttime = curtime
54         else:
55             totalchars += len(d)
56         lasttime = curtime
57
58 def readserial(infile, logfile, byteadjust):
59     lasttime = 0
60     while 1:
61         # Read data
62         try:
63             res = select.select([infile, sys.stdin], [], [])
64         except KeyboardInterrupt:
65             sys.stdout.write("\n")
66             break
67         if sys.stdin in res[0]:
68             # Got keyboard input - force reset on next serial input
69             sys.stdin.read(1)
70             lasttime = 0
71             if len(res[0]) == 1:
72                 continue
73         d = infile.read(4096)
74         if not d:
75             break
76         datatime = time.time()
77
78         datatime -= len(d) * byteadjust
79
80         # Reset start time if no data for some time
81         if datatime - lasttime > RESTARTINTERVAL:
82             starttime = datatime
83             charcount = 0
84             isnewline = 1
85             msg = "\n\n======= %s (adjust=%.1fus)\n" % (
86                 time.asctime(time.localtime(datatime)), byteadjust * 1000000)
87             sys.stdout.write(msg)
88             logfile.write(msg)
89         lasttime = datatime
90
91         # Translate unprintable chars; add timestamps
92         out = ""
93         for c in d:
94             if isnewline:
95                 delta = datatime - starttime - (charcount * byteadjust)
96                 out += "%06.3f: " % delta
97                 isnewline = 0
98             oc = ord(c)
99             charcount += 1
100             datatime += byteadjust
101             if oc == 0x0d:
102                 continue
103             if oc == 0x00:
104                 out += "<00>\n"
105                 isnewline = 1
106                 continue
107             if oc == 0x0a:
108                 out += "\n"
109                 isnewline = 1
110                 continue
111             if oc < 0x20 or oc >= 0x7f and oc != 0x09:
112                 out += "<%02x>" % oc
113                 continue
114             out += c
115
116         sys.stdout.write(out)
117         sys.stdout.flush()
118         logfile.write(out)
119         logfile.flush()
120
121 def main():
122     usage = "%prog [options] [<serialdevice> [<baud>]]"
123     opts = optparse.OptionParser(usage)
124     opts.add_option("-f", "--file",
125                     action="store_false", dest="serial", default=True,
126                     help="read from file instead of serialdevice")
127     opts.add_option("-n", "--no-adjust",
128                     action="store_false", dest="adjustbaud", default=True,
129                     help="don't adjust times by serial rate")
130     opts.add_option("-c", "--calibrate-read",
131                     action="store_true", dest="calibrate_read", default=False,
132                     help="read from serial port to calibrate it")
133     opts.add_option("-C", "--calibrate-write",
134                     action="store_true", dest="calibrate_write", default=False,
135                     help="write to serial port to calibrate it")
136     opts.add_option("-t", "--time",
137                     type="float", dest="time", default=None,
138                     help="time to write one byte on serial port (in us)")
139     options, args = opts.parse_args()
140     serialport = 0
141     baud = 115200
142     if len(args) > 2:
143         opts.error("Too many arguments")
144     if len(args) > 0:
145         serialport = args[0]
146     if len(args) > 1:
147         baud = int(args[1])
148     byteadjust = float(BITSPERBYTE) / baud
149     if options.time is not None:
150         byteadjust = options.time / 1000000.0
151     if not options.adjustbaud:
152         byteadjust = 0.0
153
154     if options.serial:
155         # Read from serial port
156         try:
157             import serial
158         except ImportError:
159             print """
160 Unable to find pyserial package ( http://pyserial.sourceforge.net/ ).
161 On Linux machines try: yum install pyserial
162 Or: apt-get install python-serial
163 """
164             sys.exit(1)
165         ser = serial.Serial(serialport, baud, timeout=0)
166     else:
167         # Read from a file
168         ser = open(serialport, 'rb')
169         import fcntl
170         import os
171         fcntl.fcntl(ser, fcntl.F_SETFL
172                     , fcntl.fcntl(ser, fcntl.F_GETFL) | os.O_NONBLOCK)
173
174     if options.calibrate_read:
175         calibrateserialread(ser, byteadjust)
176         return
177     if options.calibrate_write:
178         calibrateserialwrite(ser, byteadjust)
179         return
180
181     logname = time.strftime("seriallog-%Y%m%d_%H%M%S.log")
182     f = open(logname, 'wb')
183     readserial(ser, f, byteadjust)
184
185 if __name__ == '__main__':
186     main()