Skip to content

Commit a5431cd

Browse files
committedFeb 28, 2016
flterm: use new aio API
1 parent 6eade8a commit a5431cd

File tree

1 file changed

+50
-44
lines changed

1 file changed

+50
-44
lines changed
 

‎misoc/tools/flterm.py

+50-44
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,19 @@
1212
import msvcrt
1313
import threading
1414

15-
stop_getkey_thread = False
16-
1715
def init_getkey(callback):
18-
global stop_getkey_thread
19-
2016
loop = asyncio.get_event_loop()
2117
def getkey_thread():
2218
while True:
2319
c = msvcrt.getch()
24-
if stop_getkey_thread:
25-
return
20+
# HACK: This may still attempt to use the loop
21+
# after it is closed - see comment below.
2622
loop.call_soon_threadsafe(callback, c)
27-
stop_getkey_thread = False
2823
threading.Thread(target=getkey_thread, daemon=True).start()
2924

3025
def deinit_getkey():
3126
# Python threads suck.
32-
global stop_getkey_thread
33-
stop_getkey_thread = True
27+
pass
3428
else:
3529
import termios
3630

@@ -128,15 +122,23 @@ def encode(self):
128122

129123

130124
class Flterm:
131-
def __init__(self, kernel_image, kernel_address):
125+
def __init__(self, port, speed, kernel_image, kernel_address):
132126
self.kernel_image = kernel_image
133127
self.kernel_address = kernel_address
134-
self.magic_detect_buffer = b"\x00"*len(sfl_magic_req)
128+
129+
self.port = asyncserial.AsyncSerial(port, baudrate=speed)
130+
131+
self.keyqueue = asyncio.Queue(100)
132+
def getkey_callback(c):
133+
self.keyqueue.put_nowait(c)
134+
init_getkey(getkey_callback)
135+
136+
self.main_task = asyncio.ensure_future(self.main_coro())
135137

136138
async def send_frame(self, frame):
137139
while retry:
138-
self.writer.write(frame.encode())
139-
reply = await self.reader.read(1)
140+
await self.port.write(frame.encode())
141+
reply = await self.port.read(1)
140142
if reply == sfl_ack_success:
141143
return
142144
elif reply == sfl_ack_crcerror:
@@ -184,7 +186,7 @@ async def boot(self):
184186

185187
async def answer_magic(self):
186188
print("[FLTERM] Received firmware download request from the device.")
187-
self.writer.write(sfl_magic_ack)
189+
await self.port.write(sfl_magic_ack)
188190
try:
189191
await self.upload(self.kernel_image, self.kernel_address)
190192
except FileNotFoundError:
@@ -193,37 +195,44 @@ async def answer_magic(self):
193195
await self.boot()
194196
print("[FLTERM] Done.");
195197

196-
async def reader_coro(self):
198+
async def main_coro(self):
199+
magic_detect_buffer = b"\x00"*len(sfl_magic_req)
197200
while True:
198-
c = await self.reader.read(1)
199-
if c == b"\r":
200-
sys.stdout.write(b"\n")
201-
else:
202-
sys.stdout.buffer.write(c)
203-
sys.stdout.flush()
201+
fs = [asyncio.ensure_future(self.port.read(1024)),
202+
asyncio.ensure_future(self.keyqueue.get())]
203+
try:
204+
done, pending = await asyncio.wait(
205+
fs, return_when=asyncio.FIRST_COMPLETED)
206+
except:
207+
for f in fs:
208+
f.cancel()
209+
raise
210+
for f in pending:
211+
f.cancel()
212+
await asyncio.wait([f])
213+
214+
if fs[0] in done:
215+
c = fs[0].result()
216+
if c == b"\r":
217+
sys.stdout.write(b"\n")
218+
else:
219+
sys.stdout.buffer.write(c)
220+
sys.stdout.flush()
221+
222+
if fs[1] in done:
223+
c = fs[1].result()
224+
await self.port.write(c)
204225

205226
if self.kernel_image is not None:
206-
self.magic_detect_buffer = self.magic_detect_buffer[1:] + c
207-
if self.magic_detect_buffer == sfl_magic_req:
208-
self.answer_magic()
209-
210-
def getkey_callback(self, c):
211-
self.writer.write(c)
212-
213-
async def open(self, port, baudrate):
214-
self.reader, self.writer = await asyncserial.open_serial_connection(
215-
port, baudrate=baudrate)
216-
self.reader_task = asyncio.ensure_future(self.reader_coro())
217-
init_getkey(self.getkey_callback)
227+
magic_detect_buffer = magic_detect_buffer[1:] + c
228+
if magic_detect_buffer == sfl_magic_req:
229+
await self.answer_magic()
218230

219231
async def close(self):
220232
deinit_getkey()
221-
self.reader_task.cancel()
222-
try:
223-
await asyncio.wait_for(self.reader_task, None)
224-
except asyncio.CancelledError:
225-
pass
226-
self.writer.close()
233+
self.main_task.cancel()
234+
await asyncio.wait([self.main_task])
235+
self.port.close()
227236

228237

229238
def _get_args():
@@ -244,14 +253,11 @@ def main():
244253
loop = asyncio.get_event_loop()
245254
try:
246255
args = _get_args()
247-
flterm = Flterm(args.kernel, args.kernel_adr)
248-
loop.run_until_complete(
249-
flterm.open(args.port, args.speed))
256+
flterm = Flterm(args.port, args.speed, args.kernel, args.kernel_adr)
250257
try:
251258
loop.run_forever()
252259
finally:
253-
loop.run_until_complete(
254-
flterm.close())
260+
loop.run_until_complete(flterm.close())
255261
finally:
256262
loop.close()
257263

0 commit comments

Comments
 (0)
Please sign in to comment.