Skip to content

Commit 0e44624

Browse files
committedFeb 19, 2016
tools/flterm.py: first cleanup pass
1 parent 3d92e3f commit 0e44624

File tree

1 file changed

+61
-101
lines changed

1 file changed

+61
-101
lines changed
 

‎misoc/tools/flterm.py

+61-101
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import threading
88
import argparse
99

10-
10+
# TODO: cleanup getkey function
1111
if sys.platform == "win32":
1212
def getkey():
1313
import msvcrt
@@ -30,27 +30,22 @@ def getkey():
3030
return c
3131

3232

33-
def character(b):
34-
return b.decode('latin1')
35-
33+
sfl_prompt_req = b"F7: boot from serial\n"
34+
sfl_prompt_ack = b"\x06"
3635

37-
sfl_prompt_req = "F7: boot from serial\n"
38-
sfl_prompt_ack = "\x06"
39-
40-
sfl_magic_req = "sL5DdSMmkekro\n"
41-
sfl_magic_ack = "z6IHG7cYDID6o\n"
36+
sfl_magic_req = b"sL5DdSMmkekro\n"
37+
sfl_magic_ack = b"z6IHG7cYDID6o\n"
4238

4339
# General commands
44-
sfl_cmd_abort = 0x00
45-
sfl_cmd_load = 0x01
46-
sfl_cmd_jump = 0x02
47-
40+
sfl_cmd_abort = b"\x00"
41+
sfl_cmd_load = b"\x01"
42+
sfl_cmd_jump = b"\x02"
4843

4944
# Replies
50-
sfl_ack_success = 'K'
51-
sfl_ack_crcerror = 'C'
52-
sfl_ack_unknown = 'U'
53-
sfl_ack_error = 'E'
45+
sfl_ack_success = b"K"
46+
sfl_ack_crcerror = b"C"
47+
sfl_ack_unknown = b"U"
48+
sfl_ack_error = b"E"
5449

5550

5651
crc16_table = [
@@ -98,40 +93,18 @@ def crc16(l):
9893

9994
class SFLFrame:
10095
def __init__(self):
101-
self.length = None
102-
self.cmd = None
103-
self.payload = []
104-
self.crc = None
105-
self.raw = []
96+
self.cmd = bytes()
97+
self.payload = bytes()
10698

10799
def compute_crc(self):
108-
crc_data = []
109-
crc_data.append(self.cmd)
110-
for d in self.payload:
111-
crc_data.append(d)
112-
self.crc = crc16(crc_data)
113-
return self.crc
100+
return crc16(self.cmd + self.payload)
114101

115102
def encode(self):
116-
self.raw = []
117-
self.raw.append(self.length)
118-
self.compute_crc()
119-
for d in self.crc.to_bytes(2, "big"):
120-
self.raw.append(d)
121-
self.raw.append(self.cmd)
122-
for d in self.payload:
123-
self.raw.append(d)
124-
125-
126-
def get_file_data(filename):
127-
with open(filename, "rb") as f:
128-
data = []
129-
while True:
130-
w = f.read(1)
131-
if not w:
132-
break
133-
data.append(int.from_bytes(w, "big"))
134-
return data
103+
packet = bytes([len(self.payload)])
104+
packet += self.compute_crc().to_bytes(2, "big")
105+
packet += self.cmd
106+
packet += self.payload
107+
return packet
135108

136109

137110
class Flterm:
@@ -143,39 +116,26 @@ def __init__(self, serial_boot, kernel_image, kernel_address):
143116
self.reader_alive = False
144117
self.writer_alive = False
145118

146-
self.detect_prompt_str = " "*len(sfl_prompt_req)
147-
self.detect_magic_str = " "*len(sfl_magic_req)
148-
149-
def open(self, port, speed):
150-
self.serial = serial.serial_for_url(
151-
port,
152-
baudrate=speed,
153-
bytesize=8,
154-
parity="N",
155-
stopbits=1,
156-
xonxoff=0,
157-
timeout=0.25)
158-
self.serial.flushOutput()
159-
self.serial.flushInput()
160-
self.serial.close() # in case port was not correctly closed
161-
self.serial.open()
119+
self.promp_detect_buffer = bytes(len(sfl_prompt_req))
Has a conversation. Original line has a conversation.
120+
self.magic_detect_buffer = bytes(len(sfl_magic_req))
162121

163-
def close(self):
164-
self.serial.close()
122+
def open(self, port, baudrate):
Has a conversation. Original line has a conversation.
123+
if hasattr(self, "port"):
124+
return
125+
self.port = serial.serial_for_url(port, baudrate)
165126

166-
def write_exact(self, data):
167-
if isinstance(data, str):
168-
self.serial.write(bytes(data, "utf-8"))
169-
else:
170-
self.serial.write(serial.to_bytes(data))
127+
def close(self):
128+
if not hasattr(self, "port"):
129+
return
130+
self.port.close()
131+
del self.port
171132

172133
def send_frame(self, frame):
173-
frame.encode()
174134
retry = 1
175135
while retry:
176-
self.write_exact(frame.raw)
136+
self.port.write(frame.encode())
177137
# Get the reply from the device
178-
reply = character(self.serial.read())
138+
reply = self.port.read()
179139
if reply == sfl_ack_success:
180140
retry = 0
181141
elif reply == sfl_ack_crcerror:
@@ -186,22 +146,20 @@ def send_frame(self, frame):
186146
return 1
187147

188148
def upload(self, filename, address):
189-
data = get_file_data(filename)
149+
with open(filename, "rb") as f:
150+
data = f.read()
190151
print("[FLTERM] Uploading {} ({} bytes)...".format(filename, len(data)))
191152
current_address = address
192153
position = 0
193154
length = len(data)
194155
start = time.time()
195-
while len(data) != 0:
156+
while len(data):
196157
print("{}%\r".format(100*position//length), end="")
197158
frame = SFLFrame()
198159
frame_data = data[:251]
199-
frame.length = len(frame_data) + 4
200160
frame.cmd = sfl_cmd_load
201-
for d in current_address.to_bytes(4, "big"):
202-
frame.payload.append(d)
203-
for d in frame_data:
204-
frame.payload.append(d)
161+
frame.payload = current_address.to_bytes(4, "big")
162+
frame.payload += frame_data
205163
if self.send_frame(frame) == 0:
206164
return
207165
current_address += len(frame_data)
@@ -218,46 +176,48 @@ def upload(self, filename, address):
218176
def boot(self):
219177
print("[FLTERM] Booting the device.")
220178
frame = SFLFrame()
221-
frame.length = 4
222179
frame.cmd = sfl_cmd_jump
223-
for d in self.kernel_address.to_bytes(4, "big"):
224-
frame.payload.append(d)
180+
frame.payload = self.kernel_address.to_bytes(4, "big")
225181
self.send_frame(frame)
226182

227183
def detect_prompt(self, data):
228-
if data is not "":
229-
self.detect_prompt_str = self.detect_prompt_str[1:] + data
230-
return self.detect_prompt_str == sfl_prompt_req
184+
if len(data):
185+
self.promp_detect_buffer = self.promp_detect_buffer[1:] + data
186+
return self.promp_detect_buffer == sfl_prompt_req
231187
else:
232188
return False
233189

234190
def answer_prompt(self):
235191
print("[FLTERM] Received serial boot prompt from the device.")
236-
self.write_exact(sfl_prompt_ack)
192+
self.port.write(sfl_prompt_ack)
237193

238194
def detect_magic(self, data):
239-
if data is not "":
240-
self.detect_magic_str = self.detect_magic_str[1:] + data
241-
return self.detect_magic_str == sfl_magic_req
195+
if len(data):
196+
self.magic_detect_buffer = self.magic_detect_buffer[1:] + data
197+
return self.magic_detect_buffer == sfl_magic_req
242198
else:
243199
return False
244200

245201
def answer_magic(self):
246202
print("[FLTERM] Received firmware download request from the device.")
247203
if os.path.exists(self.kernel_image):
248-
self.write_exact(sfl_magic_ack)
204+
self.port.write(sfl_magic_ack)
249205
self.upload(self.kernel_image, self.kernel_address)
250206
self.boot()
251207
print("[FLTERM] Done.");
252208

253209
def reader(self):
254210
try:
255211
while self.reader_alive:
256-
c = character(self.serial.read())
257-
if c == '\r':
258-
sys.stdout.write('\n')
212+
c = self.port.read()
213+
if c == b"\r":
214+
sys.stdout.write(b"\n")
259215
else:
260-
sys.stdout.write(c)
216+
try:
217+
# TODO: cleanup
Has conversations. Original line has conversations.
218+
sys.stdout.write(c.decode())
219+
except:
220+
pass
261221
sys.stdout.flush()
262222

263223
if self.kernel_image is not None:
@@ -286,14 +246,13 @@ def writer(self):
286246
try:
287247
b = getkey()
288248
except KeyboardInterrupt:
289-
b = serial.to_bytes([3])
290-
c = character(b)
291-
if c == chr(0x03):
249+
b = b"\x03"
250+
if b == b"\x03":
Has conversations. Original line has conversations.
292251
self.stop()
293-
elif c == '\n':
294-
self.serial.write(serial.to_bytes([10]))
252+
elif b == b"\n":
253+
self.port.write(b"\x0a")
295254
else:
296-
self.serial.write(b)
255+
self.port.write(b)
297256
except:
298257
self.writer_alive = False
299258
raise
@@ -343,6 +302,7 @@ def main():
343302
flterm.join(True)
344303
except KeyboardInterrupt:
345304
pass
305+
flterm.close()
Has conversations. Original line has conversations.
346306

347307

348308
if __name__ == "__main__":

0 commit comments

Comments
 (0)
Please sign in to comment.