|
|
@@ -1,14 +1,14 @@ |
|
|
|
#!/usr/bin/python |
|
|
|
# Based on miniterm sample in pyserial |
|
|
|
|
|
|
|
import sys, os, serial, threading |
|
|
|
import sys, os, serial, threading, traceback, time |
|
|
|
|
|
|
|
if os.name == 'nt': |
|
|
|
import msvcrt |
|
|
|
class Console: |
|
|
|
def __enter__(self): |
|
|
|
return self |
|
|
|
def __exit__(self, type, value, traceback): |
|
|
|
def __init__(self): |
|
|
|
pass |
|
|
|
def cleanup(self): |
|
|
|
pass |
|
|
|
def getkey(self): |
|
|
|
while 1: |
|
|
@@ -22,17 +22,24 @@ if os.name == 'nt': |
|
|
|
elif os.name == 'posix': |
|
|
|
import termios, sys, os |
|
|
|
class Console: |
|
|
|
def __enter__(self): |
|
|
|
def __init__(self): |
|
|
|
self.fd = sys.stdin.fileno() |
|
|
|
self.old = termios.tcgetattr(self.fd) |
|
|
|
new = termios.tcgetattr(self.fd) |
|
|
|
new[3] = new[3] & ~termios.ICANON & ~termios.ECHO & ~termios.ISIG |
|
|
|
new[6][termios.VMIN] = 1 |
|
|
|
new[6][termios.VTIME] = 0 |
|
|
|
termios.tcsetattr(self.fd, termios.TCSANOW, new) |
|
|
|
return self |
|
|
|
def __exit__(self, type, value, traceback): |
|
|
|
termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old) |
|
|
|
try: |
|
|
|
self.old = termios.tcgetattr(self.fd) |
|
|
|
new = termios.tcgetattr(self.fd) |
|
|
|
new[3] = new[3] & ~termios.ICANON & ~termios.ECHO & ~termios.ISIG |
|
|
|
new[6][termios.VMIN] = 1 |
|
|
|
new[6][termios.VTIME] = 0 |
|
|
|
termios.tcsetattr(self.fd, termios.TCSANOW, new) |
|
|
|
except termios.error: |
|
|
|
# ignore errors, so we can pipe stuff to this script |
|
|
|
pass |
|
|
|
def cleanup(self): |
|
|
|
try: |
|
|
|
termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old) |
|
|
|
except: |
|
|
|
# ignore errors, so we can pipe stuff to this script |
|
|
|
pass |
|
|
|
def getkey(self): |
|
|
|
c = os.read(self.fd, 1) |
|
|
|
return c |
|
|
@@ -50,6 +57,7 @@ class Miniterm: |
|
|
|
self.receiver_thread.setDaemon(1) |
|
|
|
self.receiver_thread.start() |
|
|
|
#enter console->serial loop |
|
|
|
self.console = Console() |
|
|
|
self.transmitter_thread = threading.Thread(target=self.writer) |
|
|
|
self.transmitter_thread.setDaemon(1) |
|
|
|
self.transmitter_thread.start() |
|
|
@@ -58,45 +66,52 @@ class Miniterm: |
|
|
|
self.alive = False |
|
|
|
|
|
|
|
def join(self, transmit_only=False): |
|
|
|
self.receiver_thread.join() |
|
|
|
self.transmitter_thread.join() |
|
|
|
if not transmit_only: |
|
|
|
self.receiver_thread.join() |
|
|
|
|
|
|
|
def reader(self): |
|
|
|
"""loop and copy serial->console""" |
|
|
|
while self.alive: |
|
|
|
data = self.serial.read(1) |
|
|
|
if data == '\r': |
|
|
|
sys.stdout.write('\n') |
|
|
|
else: |
|
|
|
try: |
|
|
|
while self.alive: |
|
|
|
data = self.serial.read(1) |
|
|
|
sys.stdout.write(data) |
|
|
|
sys.stdout.flush() |
|
|
|
sys.stdout.flush() |
|
|
|
except Exception as e: |
|
|
|
traceback.print_exc() |
|
|
|
self.console.cleanup() |
|
|
|
os._exit(1) |
|
|
|
|
|
|
|
def writer(self): |
|
|
|
"""loop and copy console->serial until ^C""" |
|
|
|
with Console() as console: |
|
|
|
try: |
|
|
|
while self.alive: |
|
|
|
try: |
|
|
|
c = console.getkey() |
|
|
|
c = self.console.getkey() |
|
|
|
except KeyboardInterrupt: |
|
|
|
c = '\x03' |
|
|
|
if c == '\x03': |
|
|
|
self.stop() |
|
|
|
break # exit app |
|
|
|
elif c == '\x00': |
|
|
|
# don't write null, that will stop the other end |
|
|
|
pass |
|
|
|
return |
|
|
|
elif c == '': |
|
|
|
# EOF on input. Wait a tiny bit so we can |
|
|
|
# flush the remaining input, then stop. |
|
|
|
time.sleep(0.25) |
|
|
|
self.stop() |
|
|
|
return |
|
|
|
else: |
|
|
|
self.serial.write(c) # send character |
|
|
|
except Exception as e: |
|
|
|
traceback.print_exc() |
|
|
|
self.console.cleanup() |
|
|
|
os._exit(1) |
|
|
|
|
|
|
|
def run(self): |
|
|
|
saved_timeout = self.serial.timeout |
|
|
|
self.serial.timeout = 0.1 |
|
|
|
self.start() |
|
|
|
self.join(True) |
|
|
|
self.join() |
|
|
|
self.serial.write('\x00') |
|
|
|
self.serial.timeout = saved_timeout |
|
|
|
print "" |
|
|
|
self.console.cleanup() |
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
import argparse |
|
|
|