Skip to content

Commit cd14188

Browse files
Daniel Camporadpgeorge
authored andcommitted
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.
1 parent db109ca commit cd14188

File tree

2 files changed

+89
-71
lines changed

2 files changed

+89
-71
lines changed

tests/run-tests

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,17 +266,19 @@ def run_tests(pyb, tests, args):
266266
def main():
267267
cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.')
268268
cmd_parser.add_argument('--target', default='unix', help='the target platform')
269-
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device of the target board')
269+
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device or the IP address of the pyboard')
270+
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
271+
cmd_parser.add_argument('-u', '--user', default='micro', help='the telnet login username')
272+
cmd_parser.add_argument('-p', '--password', default='python', help='the telnet login password')
270273
cmd_parser.add_argument('-d', '--test-dirs', nargs='*', help='input test directories (if no files given)')
271274
cmd_parser.add_argument('--write-exp', action='store_true', help='save .exp files to run tests w/o CPython')
272275
cmd_parser.add_argument('--emit', default='bytecode', help='Micro Python emitter to use (bytecode or native)')
273-
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
274276
cmd_parser.add_argument('files', nargs='*', help='input test files')
275277
args = cmd_parser.parse_args()
276278

277279
if args.target == 'pyboard' or args.target == 'wipy':
278280
import pyboard
279-
pyb = pyboard.Pyboard(args.device, args.baudrate)
281+
pyb = pyboard.Pyboard(args.device, args.baudrate, args.user, args.password)
280282
pyb.enter_raw_repl()
281283
elif args.target == 'unix':
282284
pyb = None

tools/pyboard.py

Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
1111
import pyboard
1212
pyb = pyboard.Pyboard('/dev/ttyACM0')
13+
14+
Or:
15+
16+
pyb = pyboard.Pyboard('192.168.1.1')
17+
18+
Then:
19+
1320
pyb.enter_raw_repl()
1421
pyb.exec('pyb.LED(1).on()')
1522
pyb.exit_raw_repl()
@@ -31,7 +38,6 @@
3138

3239
import sys
3340
import time
34-
import serial
3541

3642
def stdout_write_bytes(b):
3743
sys.stdout.buffer.write(b)
@@ -40,9 +46,76 @@ def stdout_write_bytes(b):
4046
class PyboardError(BaseException):
4147
pass
4248

49+
class TelnetToSerial:
50+
def __init__(self, ip, user, password, read_timeout=None):
51+
import telnetlib
52+
self.tn = telnetlib.Telnet(ip, timeout=15)
53+
self.read_timeout = read_timeout
54+
if b'Login as:' in self.tn.read_until(b'Login as:', timeout=read_timeout):
55+
self.tn.write(bytes(user, 'ascii') + b"\r\n")
56+
57+
if b'Password:' in self.tn.read_until(b'Password:', timeout=read_timeout):
58+
# needed because of internal implementation details of the telnet server
59+
time.sleep(0.2)
60+
self.tn.write(bytes(password, 'ascii') + b"\r\n")
61+
62+
if b'for more information.' in self.tn.read_until(b'Type "help()" for more information.', timeout=read_timeout):
63+
# login succesful
64+
from collections import deque
65+
self.fifo = deque()
66+
return
67+
68+
raise PyboardError('Failed to establish a telnet connection with the board')
69+
70+
def __del__(self):
71+
self.close()
72+
73+
def close(self):
74+
try:
75+
self.tn.close()
76+
except:
77+
# the telnet object might not exist yet, so ignore this one
78+
pass
79+
80+
def read(self, size=1):
81+
while len(self.fifo) < size:
82+
timeout_count = 0
83+
data = self.tn.read_eager()
84+
if len(data):
85+
self.fifo.extend(data)
86+
timeout_count = 0
87+
else:
88+
time.sleep(0.25)
89+
if self.read_timeout is not None and timeout_count > 4 * self.read_timeout:
90+
break
91+
timeout_count += 1
92+
93+
data = b''
94+
while len(data) < size and len(self.fifo) > 0:
95+
data += bytes([self.fifo.popleft()])
96+
return data
97+
98+
def write(self, data):
99+
self.tn.write(data)
100+
return len(data)
101+
102+
def inWaiting(self):
103+
n_waiting = len(self.fifo)
104+
if not n_waiting:
105+
data = self.tn.read_eager()
106+
self.fifo.extend(data)
107+
return len(data)
108+
else:
109+
return n_waiting
110+
43111
class Pyboard:
44-
def __init__(self, serial_device, baudrate=115200):
45-
self.serial = serial.Serial(serial_device, baudrate=baudrate, interCharTimeout=1)
112+
def __init__(self, device, baudrate=115200, user='micro', password='python'):
113+
if device and device[0].isdigit() and device[-1].isdigit() and device.count('.') == 3:
114+
# device looks like an IP address
115+
self.serial = TelnetToSerial(device, user, password, read_timeout=10)
116+
else:
117+
import serial
118+
self.serial = serial.Serial(device, baudrate=baudrate, interCharTimeout=1)
46119

47120
def close(self):
48121
self.serial.close()
@@ -155,85 +228,28 @@ def get_time(self):
155228
t = str(self.eval('pyb.RTC().datetime()'), encoding='utf8')[1:-1].split(', ')
156229
return int(t[4]) * 3600 + int(t[5]) * 60 + int(t[6])
157230

158-
def execfile(filename, device='/dev/ttyACM0'):
159-
pyb = Pyboard(device)
231+
def execfile(filename, device='/dev/ttyACM0', baudrate=115200, user='micro', password='python'):
232+
pyb = Pyboard(device, baudrate, user, password)
160233
pyb.enter_raw_repl()
161234
output = pyb.execfile(filename)
162235
stdout_write_bytes(output)
163236
pyb.exit_raw_repl()
164237
pyb.close()
165238

166-
def run_test(device):
167-
pyb = Pyboard(device)
168-
pyb.enter_raw_repl()
169-
print('opened device {}'.format(device))
170-
171-
pyb.exec('import pyb') # module pyb no longer imported by default, required for pyboard tests
172-
print('seconds since boot:', pyb.get_time())
173-
174-
pyb.exec('def apply(l, f):\r\n for item in l:\r\n f(item)\r\n')
175-
176-
pyb.exec('leds=[pyb.LED(l) for l in range(1, 5)]')
177-
pyb.exec('apply(leds, lambda l:l.off())')
178-
179-
## USR switch test
180-
181-
pyb.exec('switch = pyb.Switch()')
182-
183-
for i in range(2):
184-
print("press USR button")
185-
pyb.exec('while switch(): pyb.delay(10)')
186-
pyb.exec('while not switch(): pyb.delay(10)')
187-
188-
print('USR switch passed')
189-
190-
## accel test
191-
192-
if True:
193-
print("hold level")
194-
pyb.exec('accel = pyb.Accel()')
195-
pyb.exec('while abs(accel.x()) > 10 or abs(accel.y()) > 10: pyb.delay(10)')
196-
197-
print("tilt left")
198-
pyb.exec('while accel.x() > -10: pyb.delay(10)')
199-
pyb.exec('leds[0].on()')
200-
201-
print("tilt forward")
202-
pyb.exec('while accel.y() < 10: pyb.delay(10)')
203-
pyb.exec('leds[1].on()')
204-
205-
print("tilt right")
206-
pyb.exec('while accel.x() < 10: pyb.delay(10)')
207-
pyb.exec('leds[2].on()')
208-
209-
print("tilt backward")
210-
pyb.exec('while accel.y() > -10: pyb.delay(10)')
211-
pyb.exec('leds[3].on()')
212-
213-
print('accel passed')
214-
215-
print('seconds since boot:', pyb.get_time())
216-
217-
pyb.exec('apply(leds, lambda l:l.off())')
218-
219-
pyb.exit_raw_repl()
220-
pyb.close()
221-
222239
def main():
223240
import argparse
224241
cmd_parser = argparse.ArgumentParser(description='Run scripts on the pyboard.')
225-
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device of the pyboard')
242+
cmd_parser.add_argument('--device', default='/dev/ttyACM0', help='the serial device or the IP address of the pyboard')
243+
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
244+
cmd_parser.add_argument('-u', '--user', default='micro', help='the telnet login username')
245+
cmd_parser.add_argument('-p', '--password', default='python', help='the telnet login password')
226246
cmd_parser.add_argument('--follow', action='store_true', help='follow the output after running the scripts [default if no scripts given]')
227-
cmd_parser.add_argument('--test', action='store_true', help='run a small test suite on the pyboard')
228247
cmd_parser.add_argument('files', nargs='*', help='input files')
229248
args = cmd_parser.parse_args()
230249

231-
if args.test:
232-
run_test(device=args.device)
233-
234250
for filename in args.files:
235251
try:
236-
pyb = Pyboard(args.device)
252+
pyb = Pyboard(args.device, args.baudrate, args.user, args.password)
237253
pyb.enter_raw_repl()
238254
with open(filename, 'rb') as f:
239255
pyfile = f.read()
@@ -251,7 +267,7 @@ def main():
251267

252268
if args.follow or len(args.files) == 0:
253269
try:
254-
pyb = Pyboard(args.device)
270+
pyb = Pyboard(args.device, args.baudrate, args.user, args.password)
255271
ret, ret_err = pyb.follow(timeout=None, data_consumer=stdout_write_bytes)
256272
pyb.close()
257273
except PyboardError as er:

0 commit comments

Comments
 (0)