Commit cd14188b authored by Daniel Campora's avatar Daniel Campora Committed by Damien George
Browse files

tools: Add telnet support to pyboard.py.

The adapter class "TelnetToSerial" is used to access the Telnet
connection using the same API as with the serial connection. The
function pyboard.run-test() has been removed to made the module
generic and because this small test is no longer needed.
parent db109ca0
......@@ -266,17 +266,19 @@ def run_tests(pyb, tests, args):
def main():
cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.')
cmd_parser.add_argument('--target', default='unix', help='the target platform')
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device of the target board')
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device or the IP address of the pyboard')
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
cmd_parser.add_argument('-u', '--user', default='micro', help='the telnet login username')
cmd_parser.add_argument('-p', '--password', default='python', help='the telnet login password')
cmd_parser.add_argument('-d', '--test-dirs', nargs='*', help='input test directories (if no files given)')
cmd_parser.add_argument('--write-exp', action='store_true', help='save .exp files to run tests w/o CPython')
cmd_parser.add_argument('--emit', default='bytecode', help='Micro Python emitter to use (bytecode or native)')
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
cmd_parser.add_argument('files', nargs='*', help='input test files')
args = cmd_parser.parse_args()
if args.target == 'pyboard' or args.target == 'wipy':
import pyboard
pyb = pyboard.Pyboard(args.device, args.baudrate)
pyb = pyboard.Pyboard(args.device, args.baudrate, args.user, args.password)
pyb.enter_raw_repl()
elif args.target == 'unix':
pyb = None
......
......@@ -10,6 +10,13 @@ Example usage:
import pyboard
pyb = pyboard.Pyboard('/dev/ttyACM0')
Or:
pyb = pyboard.Pyboard('192.168.1.1')
Then:
pyb.enter_raw_repl()
pyb.exec('pyb.LED(1).on()')
pyb.exit_raw_repl()
......@@ -31,7 +38,6 @@ Or:
import sys
import time
import serial
def stdout_write_bytes(b):
sys.stdout.buffer.write(b)
......@@ -40,9 +46,76 @@ def stdout_write_bytes(b):
class PyboardError(BaseException):
pass
class TelnetToSerial:
def __init__(self, ip, user, password, read_timeout=None):
import telnetlib
self.tn = telnetlib.Telnet(ip, timeout=15)
self.read_timeout = read_timeout
if b'Login as:' in self.tn.read_until(b'Login as:', timeout=read_timeout):
self.tn.write(bytes(user, 'ascii') + b"\r\n")
if b'Password:' in self.tn.read_until(b'Password:', timeout=read_timeout):
# needed because of internal implementation details of the telnet server
time.sleep(0.2)
self.tn.write(bytes(password, 'ascii') + b"\r\n")
if b'for more information.' in self.tn.read_until(b'Type "help()" for more information.', timeout=read_timeout):
# login succesful
from collections import deque
self.fifo = deque()
return
raise PyboardError('Failed to establish a telnet connection with the board')
def __del__(self):
self.close()
def close(self):
try:
self.tn.close()
except:
# the telnet object might not exist yet, so ignore this one
pass
def read(self, size=1):
while len(self.fifo) < size:
timeout_count = 0
data = self.tn.read_eager()
if len(data):
self.fifo.extend(data)
timeout_count = 0
else:
time.sleep(0.25)
if self.read_timeout is not None and timeout_count > 4 * self.read_timeout:
break
timeout_count += 1
data = b''
while len(data) < size and len(self.fifo) > 0:
data += bytes([self.fifo.popleft()])
return data
def write(self, data):
self.tn.write(data)
return len(data)
def inWaiting(self):
n_waiting = len(self.fifo)
if not n_waiting:
data = self.tn.read_eager()
self.fifo.extend(data)
return len(data)
else:
return n_waiting
class Pyboard:
def __init__(self, serial_device, baudrate=115200):
self.serial = serial.Serial(serial_device, baudrate=baudrate, interCharTimeout=1)
def __init__(self, device, baudrate=115200, user='micro', password='python'):
if device and device[0].isdigit() and device[-1].isdigit() and device.count('.') == 3:
# device looks like an IP address
self.serial = TelnetToSerial(device, user, password, read_timeout=10)
else:
import serial
self.serial = serial.Serial(device, baudrate=baudrate, interCharTimeout=1)
def close(self):
self.serial.close()
......@@ -155,85 +228,28 @@ class Pyboard:
t = str(self.eval('pyb.RTC().datetime()'), encoding='utf8')[1:-1].split(', ')
return int(t[4]) * 3600 + int(t[5]) * 60 + int(t[6])
def execfile(filename, device='/dev/ttyACM0'):
pyb = Pyboard(device)
def execfile(filename, device='/dev/ttyACM0', baudrate=115200, user='micro', password='python'):
pyb = Pyboard(device, baudrate, user, password)
pyb.enter_raw_repl()
output = pyb.execfile(filename)
stdout_write_bytes(output)
pyb.exit_raw_repl()
pyb.close()
def run_test(device):
pyb = Pyboard(device)
pyb.enter_raw_repl()
print('opened device {}'.format(device))
pyb.exec('import pyb') # module pyb no longer imported by default, required for pyboard tests
print('seconds since boot:', pyb.get_time())
pyb.exec('def apply(l, f):\r\n for item in l:\r\n f(item)\r\n')
pyb.exec('leds=[pyb.LED(l) for l in range(1, 5)]')
pyb.exec('apply(leds, lambda l:l.off())')
## USR switch test
pyb.exec('switch = pyb.Switch()')
for i in range(2):
print("press USR button")
pyb.exec('while switch(): pyb.delay(10)')
pyb.exec('while not switch(): pyb.delay(10)')
print('USR switch passed')
## accel test
if True:
print("hold level")
pyb.exec('accel = pyb.Accel()')
pyb.exec('while abs(accel.x()) > 10 or abs(accel.y()) > 10: pyb.delay(10)')
print("tilt left")
pyb.exec('while accel.x() > -10: pyb.delay(10)')
pyb.exec('leds[0].on()')
print("tilt forward")
pyb.exec('while accel.y() < 10: pyb.delay(10)')
pyb.exec('leds[1].on()')
print("tilt right")
pyb.exec('while accel.x() < 10: pyb.delay(10)')
pyb.exec('leds[2].on()')
print("tilt backward")
pyb.exec('while accel.y() > -10: pyb.delay(10)')
pyb.exec('leds[3].on()')
print('accel passed')
print('seconds since boot:', pyb.get_time())
pyb.exec('apply(leds, lambda l:l.off())')
pyb.exit_raw_repl()
pyb.close()
def main():
import argparse
cmd_parser = argparse.ArgumentParser(description='Run scripts on the pyboard.')
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device of the pyboard')
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device or the IP address of the pyboard')
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
cmd_parser.add_argument('-u', '--user', default='micro', help='the telnet login username')
cmd_parser.add_argument('-p', '--password', default='python', help='the telnet login password')
cmd_parser.add_argument('--follow', action='store_true', help='follow the output after running the scripts [default if no scripts given]')
cmd_parser.add_argument('--test', action='store_true', help='run a small test suite on the pyboard')
cmd_parser.add_argument('files', nargs='*', help='input files')
args = cmd_parser.parse_args()
if args.test:
run_test(device=args.device)
for filename in args.files:
try:
pyb = Pyboard(args.device)
pyb = Pyboard(args.device, args.baudrate, args.user, args.password)
pyb.enter_raw_repl()
with open(filename, 'rb') as f:
pyfile = f.read()
......@@ -251,7 +267,7 @@ def main():
if args.follow or len(args.files) == 0:
try:
pyb = Pyboard(args.device)
pyb = Pyboard(args.device, args.baudrate, args.user, args.password)
ret, ret_err = pyb.follow(timeout=None, data_consumer=stdout_write_bytes)
pyb.close()
except PyboardError as er:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment