Browse Source

Improve serial read speeds by using a larger nonblocking read on POSIX

master
Jim Paris 10 years ago
parent
commit
b765576283
1 changed files with 36 additions and 15 deletions
  1. +36
    -15
      terminal.py

+ 36
- 15
terminal.py View File

@@ -44,8 +44,11 @@ if os.name == 'nt':
return z return z
if (time.time() - start) > 0.1: if (time.time() - start) > 0.1:
return None return None
class MySerial(serial.Serial):
def nonblocking_read(self, size=1):
return self.read(size)
elif os.name == 'posix': elif os.name == 'posix':
import termios, select
import termios, select, errno
class Console: class Console:
def __init__(self, bufsize = 65536): def __init__(self, bufsize = 65536):
self.bufsize = bufsize self.bufsize = bufsize
@@ -75,6 +78,21 @@ elif os.name == 'posix':
return '' return ''
else: else:
return None return None
class MySerial(serial.Serial):
def nonblocking_read(self, size=1, timeout = 0.1):
[r, w, x] = select.select([self.fd], [], [self.fd], timeout)
if r:
try:
return os.read(self.fd, size)
except OSError as e:
if e.errno == errno.EAGAIN:
return ''
raise
elif x:
raise SerialException("exception (device disconnected?)")
else:
return ''

else: else:
raise ("Sorry, no terminal implementation for your platform (%s) " raise ("Sorry, no terminal implementation for your platform (%s) "
"available." % sys.platform) "available." % sys.platform)
@@ -169,32 +187,35 @@ class Jimterm:
first = True first = True
try: try:
while self.alive: while self.alive:
data = serial.read(1)
if not data:
# For a POSIX system, do a not-retarded read.
data = serial.nonblocking_read(self.bufsize)
if not data or data == "":
continue continue


# don't print a NULL if it's the first character we # don't print a NULL if it's the first character we
# read. This hides startup/port-opening glitches with # read. This hides startup/port-opening glitches with
# some serial devices. # some serial devices.
if self.suppress_read_firstnull and first and data == '\0':
if self.suppress_read_firstnull and first and data[0] == '\0':
first = False first = False
continue
data = data[1:]
first = False first = False


if color != self.last_color: if color != self.last_color:
self.last_color = color self.last_color = color
sys.stdout.write(color) sys.stdout.write(color)


if (self.raw or
(ord(data) >= 32 and ord(data) < 128) or
data == '\r' or data == '\n' or data == '\t'):
if self.add_cr and data == '\n':
sys.stdout.write('\r' + data)
else:
sys.stdout.write(data)
else:
sys.stdout.write('\\x'+("0"+hex(ord(data))[2:])[-2:])
if self.add_cr:
data = data.replace('\n', '\r\n')

if not self.raw:
# Escape unprintable chars
data = data.encode('unicode_escape')
# But these are OK, change them back
data = data.replace("\\n", "\n")
data = data.replace("\\r", "\r")
data = data.replace("\\t", "\t")


sys.stdout.write(data)
sys.stdout.flush() sys.stdout.flush()
except Exception as e: except Exception as e:
sys.stdout.write(color) sys.stdout.write(color)
@@ -346,7 +367,7 @@ if __name__ == "__main__":
sys.stderr.write("error: %s specified more than once\n" % node) sys.stderr.write("error: %s specified more than once\n" % node)
raise SystemExit(1) raise SystemExit(1)
try: try:
dev = serial.Serial(node, baud, rtscts = args.flow)
dev = MySerial(node, baud, rtscts = args.flow)
except serial.serialutil.SerialException: except serial.serialutil.SerialException:
sys.stderr.write("error opening %s\n" % node) sys.stderr.write("error opening %s\n" % node)
raise SystemExit(1) raise SystemExit(1)


Loading…
Cancel
Save