Skip to content

Commit 7fb642c

Browse files
WangXX-miyangsong8-a1
authored andcommitted
apps/system/ymodem: Optimized ymodem for burn during bootloader
If device automatically enters the ymodem rb mode when it starts up, the PC tool does not need to send rb command anymore. Here, when a specified number of consecutive 'C' are received, the subsequent ymodem protocol content will continue. Signed-off-by: wangxingxing <wangxingxing@xiaomi.com>
1 parent 90cd25b commit 7fb642c

File tree

1 file changed

+81
-21
lines changed

1 file changed

+81
-21
lines changed

system/ymodem/sbrb.py

Lines changed: 81 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import os
2626
import sys
2727
import termios
28+
import time
2829

2930
import serial
3031

@@ -92,25 +93,31 @@ def ymodem_stdprogress(data):
9293

9394

9495
def ymodem_ser_read(size):
95-
global fd_serial
96-
9796
data = fd_serial.read(size)
9897
return data
9998

10099

101100
def ymodem_ser_write(data):
102-
global fd_serial
103101
fd_serial.write(data)
104102
fd_serial.flush()
105103

106104

107105
def ymodem_ser_clear():
108-
global fd_serial
109-
110106
fd_serial.reset_input_buffer()
111107
fd_serial.reset_output_buffer()
112108

113109

110+
def ymodem_ser_recv_repeat_c(num, timeout):
111+
except_data = b"C" * num
112+
start_time = time.time()
113+
114+
while time.time() - start_time < timeout:
115+
read_data = ymodem_ser_read(num)
116+
if read_data == except_data:
117+
return 0
118+
return -1
119+
120+
114121
def calc_crc16(data, crc=0):
115122
crctable = [
116123
0x0000,
@@ -385,7 +392,7 @@ def __init__(
385392
write=ymodem_stdwrite,
386393
progress=ymodem_stdprogress,
387394
clear=ymodem_stdclear,
388-
timeout=100,
395+
timeout=10,
389396
maxretry=RETRIESMAX,
390397
debug="",
391398
customsize=0,
@@ -452,15 +459,30 @@ def get_pkt_size(self):
452459
return PACKET_SIZE
453460

454461
def recv_cmd(self, cmd):
455-
chunk = self.read(1)
456-
if chunk == NAK:
457-
return -EAGAIN
458-
if chunk != cmd:
459-
self.debug("should be " + binascii.hexlify(cmd).decode("utf-8"))
460-
self.debug("but receive " + binascii.hexlify(chunk).decode("utf-8") + "\n")
461-
return -EINVAL
462-
463-
return 0
462+
start_time = time.time()
463+
unexpected_buffer = b""
464+
while time.time() - start_time < self.timeout:
465+
chunk = self.read(1)
466+
if chunk == cmd:
467+
if unexpected_buffer:
468+
# try to decode to UTF-8
469+
decoded = unexpected_buffer.decode("utf-8", errors="replace")
470+
self.progress(f"Ignored unexpected text: {decoded}\n")
471+
return 0
472+
elif chunk == NAK:
473+
if unexpected_buffer:
474+
decoded = unexpected_buffer.decode("utf-8", errors="replace")
475+
self.progress(f"Ignored unexpected text: {decoded}\n")
476+
print("EAGAIN!!!")
477+
return -EAGAIN
478+
elif chunk == b"":
479+
continue
480+
else:
481+
unexpected_buffer += chunk
482+
if unexpected_buffer:
483+
decoded = unexpected_buffer.decode("utf-8", errors="replace")
484+
self.progress(f"Ignored unexpected text: {decoded}\n")
485+
return -EINVAL
464486

465487
def send_handshake(self):
466488
self.write(CRC)
@@ -807,6 +829,29 @@ def recv(self):
807829
help="This opthin set max retry for transmission",
808830
)
809831

832+
parser.add_argument(
833+
"-c",
834+
"--countofc",
835+
type=int,
836+
default=0,
837+
help="""
838+
When this value is greater than 0, it means that the rb command is not sent to
839+
device, but to recevie a specified number of consecutive 'C'.
840+
If do not receive continuous 'C', time out and exit.
841+
""",
842+
)
843+
844+
parser.add_argument(
845+
"-w",
846+
"--waitctimeout",
847+
type=int,
848+
default=30,
849+
help="""
850+
When the -c parameter is valid, this arg will determine whether it has timed out
851+
while waiting for consecutive Cs. The unit is second.
852+
""",
853+
)
854+
810855
parser.add_argument(
811856
"--debug", help="This opthin is save debug log on host", default=""
812857
)
@@ -821,19 +866,34 @@ def recv(self):
821866
for i in args.recvfrom:
822867
recvfile += i + " "
823868

869+
if args.kblocksize:
870+
recvfile += "-k %d " % (args.kblocksize)
871+
824872
fd_serial.write(("sb %s\r\n" % (recvfile)).encode())
825873
fd_serial.flush()
826874
tmp = fd_serial.read(len(("sb %s\r\n" % (recvfile)).encode()) - 1)
827875
fd_serial.reset_input_buffer()
828876
else:
829-
if args.sendto:
830-
cmd = ("rb -f %s\r\n" % (args.sendto[0])).encode()
877+
if args.countofc:
878+
ret = ymodem_ser_recv_repeat_c(args.countofc, args.waitctimeout)
879+
if ret < 0:
880+
print("ser read C timeout")
881+
fd_serial.close()
882+
sys.exit(1)
831883
else:
832-
cmd = ("rb\r\n").encode()
884+
if args.sendto:
885+
cmd = ("rb -f %s" % args.sendto[0]).encode()
886+
else:
887+
cmd = "rb".encode()
833888

834-
fd_serial.write(cmd)
835-
fd_serial.flush()
836-
fd_serial.read(len(cmd))
889+
if args.kblocksize:
890+
cmd += (" -k %d" % args.kblocksize).encode()
891+
892+
cmd += b"\r\n"
893+
894+
fd_serial.write(cmd)
895+
fd_serial.flush()
896+
fd_serial.read(len(cmd))
837897

838898
fd_serial.reset_input_buffer()
839899
sbrb = ymodem(

0 commit comments

Comments
 (0)