Some serial ports have slightly different timing. These timing variations result in less accurate boot time reporting. So, add a calibration mechanism to the tool so that one can determine how much time a specific machine's serial port uses.
Also, extend the main part of the tool to allow the user to specify an exact timing parameter. --- tools/readserial.py | 73 ++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 61 insertions(+), 12 deletions(-)
diff --git a/tools/readserial.py b/tools/readserial.py index 9c955c6..d85392e 100755 --- a/tools/readserial.py +++ b/tools/readserial.py @@ -15,18 +15,48 @@ import optparse
# Reset time counter after this much idle time. RESTARTINTERVAL = 60 -# Alter timing reports based on how much time would be spent writing -# to serial. -ADJUSTBAUD = 1 # Number of bits in a transmitted byte - 8N1 is 1 start bit + 8 data # bits + 1 stop bit. BITSPERBYTE = 10
-def readserial(infile, logfile, baudrate): +def calibrateserialwrite(outfile, byteadjust): + # Build 4000 bytes of dummy data. + data = "0123456789" * 4 + "012345678" + "\n" + data = data * 80 + while 1: + st = time.time() + outfile.write(data) + outfile.flush() + et = time.time() + sys.stdout.write( + "Wrote %d - %.1fus per char (theory states %.1fus)\n" % ( + len(data), (et-st) / len(data) * 1000000, byteadjust * 1000000)) + sys.stdout.flush() + time.sleep(3) + +def calibrateserialread(infile, byteadjust): + starttime = lasttime = 0 + totalchars = 0 + while 1: + select.select([infile], [], []) + d = infile.read(4096) + curtime = time.time() + if curtime - lasttime > 1.0: + if starttime and totalchars: + sys.stdout.write( + "Calibrating on %d bytes - %.1fus per char" + " (theory states %.1fus)\n" % ( + totalchars, + float(lasttime - starttime) * 1000000 / totalchars, + byteadjust * 1000000)) + totalchars = 0 + starttime = curtime + else: + totalchars += len(d) + lasttime = curtime + +def readserial(infile, logfile, byteadjust): lasttime = 0 - byteadjust = 0.0 - if ADJUSTBAUD: - byteadjust = float(BITSPERBYTE) / baudrate while 1: # Read data try: @@ -52,8 +82,8 @@ def readserial(infile, logfile, baudrate): starttime = datatime charcount = 0 isnewline = 1 - msg = "\n\n======= %s (adjust=%d)\n" % ( - time.asctime(time.localtime(datatime)), ADJUSTBAUD) + msg = "\n\n======= %s (adjust=%.1fus)\n" % ( + time.asctime(time.localtime(datatime)), byteadjust * 1000000) sys.stdout.write(msg) logfile.write(msg) lasttime = datatime @@ -97,6 +127,15 @@ def main(): opts.add_option("-n", "--no-adjust", action="store_false", dest="adjustbaud", default=True, help="don't adjust times by serial rate") + opts.add_option("-c", "--calibrate-read", + action="store_true", dest="calibrate_read", default=False, + help="read from serial port to calibrate it") + opts.add_option("-C", "--calibrate-write", + action="store_true", dest="calibrate_write", default=False, + help="write to serial port to calibrate it") + opts.add_option("-t", "--time", + type="float", dest="time", default=None, + help="time to write one byte on serial port (in us)") options, args = opts.parse_args() serialport = 0 baud = 115200 @@ -106,8 +145,11 @@ def main(): serialport = args[0] if len(args) > 1: baud = int(args[1]) - global ADJUSTBAUD - ADJUSTBAUD=options.adjustbaud + byteadjust = float(BITSPERBYTE) / baud + if options.time is not None: + byteadjust = options.time / 1000000.0 + if not options.adjustbaud: + byteadjust = 0.0
if options.serial: # Read from serial port @@ -129,9 +171,16 @@ Or: apt-get install python-serial fcntl.fcntl(ser, fcntl.F_SETFL , fcntl.fcntl(ser, fcntl.F_GETFL) | os.O_NONBLOCK)
+ if options.calibrate_read: + calibrateserialread(ser, byteadjust) + return + if options.calibrate_write: + calibrateserialwrite(ser, byteadjust) + return + logname = time.strftime("seriallog-%Y%m%d_%H%M%S.log") f = open(logname, 'wb') - readserial(ser, f, baud) + readserial(ser, f, byteadjust)
if __name__ == '__main__': main()