Skip to content

Commit 85ae6f0

Browse files
anjiahao1xiaoxiang781216
authored andcommitted
ymodem:set the transport retry as optional
The waiting duration of the rb/sb command can be determined based on the number of retransmissions, so that ymodem can restart to the normal system after running in the bootloader for a short period of time. Signed-off-by: anjiahao <[email protected]>
1 parent e4e46c3 commit 85ae6f0

File tree

5 files changed

+114
-63
lines changed

5 files changed

+114
-63
lines changed

system/ymodem/rb_main.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ static void show_usage(FAR const char *progname)
330330
fprintf(stderr,
331331
"\t-t|--threshold <size>: Threshold for writing asynchronously."
332332
"Threshold must be less than or equal buffersize, Default: 0kB\n");
333+
fprintf(stderr,
334+
"\t-i|--interval <time>: Waiting interval for transmitting data."
335+
"Max:255 Min:1 Default:15 unit: 100 milliseconds\n");
336+
fprintf(stderr,
337+
"\t-r|--retry <retry>: Number of retries."
338+
"Will try <retry> times to transmitting, Default:100\n");
333339
fprintf(stderr,
334340
"\t-k <size>: Use a custom size to tansfer, Default: 1kB\n");
335341

@@ -352,13 +358,17 @@ int main(int argc, FAR char *argv[])
352358
{"buffersize", 1, NULL, 'b'},
353359
{"skip_prefix", 1, NULL, 'p'},
354360
{"skip_suffix", 1, NULL, 's'},
355-
{"threshold", 1, NULL, 't'}
361+
{"threshold", 1, NULL, 't'},
362+
{"interval", 1, NULL, 'i'},
363+
{"retry", 1, NULL, 'r'},
356364
};
357365

358366
memset(&priv, 0, sizeof(priv));
359367
memset(&ctx, 0, sizeof(ctx));
360-
while ((ret = getopt_long(argc, argv, "b:d:f:hk:p:s:t:", options, NULL))
361-
!= ERROR)
368+
ctx.interval = 15;
369+
ctx.retry = 100;
370+
while ((ret = getopt_long(argc, argv, "b:d:f:hk:p:s:t:i:r:",
371+
options, NULL)) != ERROR)
362372
{
363373
switch (ret)
364374
{
@@ -391,6 +401,12 @@ int main(int argc, FAR char *argv[])
391401
case 't':
392402
priv.threshold = atoi(optarg) * 1024;
393403
break;
404+
case 'i':
405+
ctx.interval = atoi(optarg);
406+
break;
407+
case 'r':
408+
ctx.retry = atoi(optarg);
409+
break;
394410

395411
case '?':
396412
default:

system/ymodem/sb_main.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ static void show_usage(FAR const char *progname)
275275
fprintf(stderr,
276276
"\t-b|--buffersize <size>: Asynchronously send buffer size."
277277
"If greater than 0, accept data asynchronously, Default: 0kB\n");
278+
fprintf(stderr,
279+
"\t-i|--interval <time>: Waiting interval for transmitting data."
280+
"Max:255 Min:1 Default:15 unit: 100 milliseconds\n");
281+
fprintf(stderr,
282+
"\t-r|--retry <retry>: Number of retries."
283+
"Will try <retry> times to transmitting, Default:100\n");
278284
fprintf(stderr,
279285
"\t-k <size>: Use a custom size to tansfer, Default: 1kB\n");
280286

@@ -294,10 +300,14 @@ int main(int argc, FAR char *argv[])
294300
struct option options[] =
295301
{
296302
{"buffersize", 1, NULL, 'b'},
303+
{"interval", 1, NULL, 'i'},
304+
{"retry", 1, NULL, 'r'},
297305
};
298306

299307
memset(&priv, 0, sizeof(priv));
300308
memset(&ctx, 0, sizeof(ctx));
309+
ctx.interval = 15;
310+
ctx.retry = 100;
301311
while ((ret = getopt_long(argc, argv, "b:d:k:h", options, NULL))
302312
!= ERROR)
303313
{
@@ -317,6 +327,13 @@ int main(int argc, FAR char *argv[])
317327
}
318328

319329
break;
330+
case 'i':
331+
ctx.interval = atoi(optarg);
332+
break;
333+
case 'r':
334+
ctx.retry = atoi(optarg);
335+
break;
336+
320337
case 'h':
321338
case '?':
322339
default:

system/ymodem/sbrb.py

Lines changed: 72 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import datetime
2222
import io
2323
import os
24-
import signal
2524
import sys
2625
import termios
2726

@@ -54,47 +53,35 @@ def format_time(seconds):
5453
return time
5554

5655

57-
class Timeout(Exception):
58-
pass
59-
60-
61-
def timeout_handle(signum, frame):
62-
sys.stderr.write("timeout!\n")
63-
sys.stderr.flush()
64-
raise Timeout("Timeout")
65-
66-
6756
def ymodem_stdread(size):
6857
fd = sys.stdin.fileno()
6958
old_settings = termios.tcgetattr(fd)
70-
signal.signal(signal.SIGALRM, timeout_handle)
71-
signal.alarm(3)
72-
try:
73-
new_settings = termios.tcgetattr(fd)
74-
new_settings[3] &= ~(termios.ICANON | termios.ECHO)
75-
termios.tcsetattr(fd, termios.TCSADRAIN, new_settings)
76-
data = sys.stdin.buffer.read(size)
77-
sys.stdin.flush()
78-
return data
79-
except Timeout:
80-
return
81-
finally:
82-
signal.alarm(0)
83-
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
59+
new_settings = termios.tcgetattr(fd)
60+
new_settings[3] &= ~(termios.ICANON | termios.ECHO)
61+
termios.tcsetattr(fd, termios.TCSADRAIN, new_settings)
62+
data = sys.stdin.buffer.read(size)
63+
termios.tcflush(sys.stdin, termios.TCIFLUSH)
64+
sys.stdin.flush()
65+
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
66+
return data
8467

8568

8669
def ymodem_stdwrite(data):
8770
fd = sys.stdout.fileno()
8871
old_settings = termios.tcgetattr(fd)
89-
try:
90-
new_settings = termios.tcgetattr(fd)
91-
new_settings[3] &= ~(termios.ICANON | termios.ECHO)
92-
termios.tcsetattr(fd, termios.TCSADRAIN, new_settings)
93-
data = sys.stdout.buffer.write(data)
94-
sys.stdout.flush()
95-
return data
96-
finally:
97-
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
72+
new_settings = termios.tcgetattr(fd)
73+
new_settings[3] &= ~(termios.ICANON | termios.ECHO)
74+
termios.tcsetattr(fd, termios.TCSADRAIN, new_settings)
75+
data = sys.stdout.buffer.write(data)
76+
termios.tcflush(sys.stdout, termios.TCIFLUSH)
77+
sys.stdout.flush()
78+
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
79+
return data
80+
81+
82+
def ymodem_stdclear():
83+
sys.stdin.flush()
84+
sys.stdout.flush()
9885

9986

10087
def ymodem_stdprogress(data):
@@ -115,6 +102,13 @@ def ymodem_ser_write(data):
115102
fd_serial.flush()
116103

117104

105+
def ymodem_ser_clear():
106+
global fd_serial
107+
108+
fd_serial.reset_input_buffer()
109+
fd_serial.reset_output_buffer()
110+
111+
118112
def calc_crc16(data, crc=0):
119113
crctable = [
120114
0x0000,
@@ -388,15 +382,21 @@ def __init__(
388382
read=ymodem_stdread,
389383
write=ymodem_stdwrite,
390384
progress=ymodem_stdprogress,
385+
clear=ymodem_stdclear,
391386
timeout=100,
387+
maxretry=RETRIESMAX,
392388
debug="",
393389
customsize=0,
394390
):
395391
self.read = read
396392
self.write = write
393+
self.clear = clear
397394
self.timeout = timeout
395+
self.maxretry = maxretry
398396
self.progress = progress
399397
self.customsize = customsize
398+
self.retries = 0
399+
400400
if debug != "":
401401
self.debugfd = open(debug, "w+")
402402
else:
@@ -460,38 +460,39 @@ def recv_cmd(self, cmd):
460460

461461
return 0
462462

463+
def send_handshake(self):
464+
self.write(CRC)
465+
while self.retries < self.maxretry:
466+
chunk = self.read(1)
467+
if chunk == CRC:
468+
return True
469+
else:
470+
self.retries += 1
471+
self.clear()
472+
473+
self.progress("too many retries\n")
474+
return False
475+
463476
def send(self, filelist):
464-
retries = 0
465477
need_sendfile_num = len(filelist)
466478
cnt = 0
467479
now = datetime.datetime.now()
468480
base = float(int(now.timestamp() * 1000)) / 1000
469481
totolbytes = 0
470482

471-
while retries < 10:
472-
self.write(CRC)
473-
chunk = self.read(1)
474-
if chunk == CRC:
475-
break
476-
else:
477-
retries += 1
478-
479-
if retries == 10:
480-
return False
483+
if not self.send_handshake():
484+
return -EINVAL
481485

482486
while need_sendfile_num != 0:
483487
now = datetime.datetime.now()
484488
start = float(int(now.timestamp() * 1000)) / 1000
485489
self.init_pkt()
486490
self.head = SOH
487491
filename = os.path.basename(filelist[cnt])
488-
489-
self.progress("name:" + filename)
490492
self.data = filename.encode("utf-8")
491493
self.data = self.data + bytes([0x00] * 1)
492494
filesize = os.path.getsize(filelist[cnt])
493495
sendfilesize = 0
494-
self.progress(" filesize:%d\n" % (filesize))
495496
self.data = self.data + str(filesize).encode("utf-8")
496497
self.data = self.data.ljust(self.get_pkt_size(), b"\x00")
497498
self.send_pkt()
@@ -500,14 +501,21 @@ def send(self, filelist):
500501
if ret == -EAGAIN:
501502
continue
502503
elif ret == -EINVAL:
504+
if self.send_handshake():
505+
continue
503506
return ret
504507

505508
ret = self.recv_cmd(CRC)
506509
if ret == -EAGAIN:
507510
continue
508511
elif ret == -EINVAL:
512+
if self.send_handshake():
513+
continue
509514
return ret
510515

516+
self.progress("name:" + filename)
517+
self.progress(" filesize:%d\n" % (filesize))
518+
511519
self.add_seq()
512520
readfd = open(filelist[cnt], "rb")
513521
self.progress(" ")
@@ -656,7 +664,6 @@ def recv_packet(self):
656664
return 0
657665

658666
def recv(self):
659-
retries = 0
660667
now = datetime.datetime.now()
661668
base = float(int(now.timestamp() * 1000)) / 1000
662669
totolbytes = 0
@@ -673,12 +680,12 @@ def recv(self):
673680
continue
674681

675682
elif ret < 0:
676-
if retries > RETRIESMAX:
683+
if self.retries > self.maxretry:
677684
return -1
678685

679686
self.progress("recv ret %d\n" % ret)
680687
self.debug("recv frist packet\n")
681-
retries += 1
688+
self.retries += 1
682689
continue
683690

684691
filename = bytes.decode(self.data.split(b"\x00")[0], "utf-8")
@@ -699,9 +706,9 @@ def recv(self):
699706
ret = self.recv_packet()
700707
if ret < 0:
701708
self.debug("recv a bad data packet\n")
702-
if retries > RETRIESMAX:
709+
if self.retries > self.maxretry:
703710
return -1
704-
retries += 1
711+
self.retries += 1
705712
continue
706713

707714
size = 0
@@ -791,6 +798,13 @@ def recv(self):
791798
""",
792799
)
793800

801+
parser.add_argument(
802+
"--maxretry",
803+
type=int,
804+
default=RETRIESMAX,
805+
help="This opthin set max retry for transmission",
806+
)
807+
794808
parser.add_argument(
795809
"--debug", help="This opthin is save debug log on host", default=""
796810
)
@@ -821,9 +835,13 @@ def recv(self):
821835
customsize=args.kblocksize * 1024,
822836
read=ymodem_ser_read,
823837
write=ymodem_ser_write,
838+
clear=ymodem_ser_clear,
839+
maxretry=args.maxretry,
824840
)
825841
else:
826-
sbrb = ymodem(debug=args.debug, customsize=args.kblocksize * 1024)
842+
sbrb = ymodem(
843+
debug=args.debug, customsize=args.kblocksize * 1024, maxretry=args.maxretry
844+
)
827845

828846
if len(args.filelist) == 0:
829847
sbrb.progress("receiving\n")

system/ymodem/ymodem.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@
6060
#define CAN 0x18 /* Two of these in succession aborts transfer */
6161
#define CRC 0x43 /* 'C' == 0x43, request 16-bit CRC */
6262

63-
#define MAX_RETRIES 100
64-
6563
/****************************************************************************
6664
* Private Functions
6765
****************************************************************************/
@@ -216,7 +214,7 @@ static int ymodem_recv_file(FAR struct ymodem_ctx_s *ctx)
216214
/* other errors, like ETIMEDOUT, EILSEQ, EBADMSG... */
217215

218216
tcflush(ctx->recvfd, TCIOFLUSH);
219-
if (++retries > MAX_RETRIES)
217+
if (++retries > ctx->retry)
220218
{
221219
ymodem_debug("recv_file: too many errors, cancel!!\n");
222220
goto cancel;
@@ -340,7 +338,7 @@ static int ymodem_send_file(FAR struct ymodem_ctx_s *ctx)
340338
int ret;
341339

342340
ymodem_debug("waiting handshake\n");
343-
for (retries = 0; retries < MAX_RETRIES; retries++)
341+
for (retries = 0; retries < ctx->retry; retries++)
344342
{
345343
ret = ymodem_recv_cmd(ctx, CRC);
346344
if (ret >= 0)
@@ -349,7 +347,7 @@ static int ymodem_send_file(FAR struct ymodem_ctx_s *ctx)
349347
}
350348
}
351349

352-
if (retries >= MAX_RETRIES)
350+
if (retries >= ctx->retry)
353351
{
354352
ymodem_debug("waiting handshake error\n");
355353
return -ETIMEDOUT;
@@ -581,7 +579,7 @@ int ymodem_recv(FAR struct ymodem_ctx_s *ctx)
581579
tcgetattr(ctx->recvfd, &term);
582580
memcpy(&saveterm, &term, sizeof(struct termios));
583581
cfmakeraw(&term);
584-
term.c_cc[VTIME] = 15;
582+
term.c_cc[VTIME] = ctx->interval;
585583
term.c_cc[VMIN] = 255;
586584
tcsetattr(ctx->recvfd, TCSANOW, &term);
587585

system/ymodem/ymodem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ struct ymodem_ctx_s
5050
CODE int (*packet_handler)(FAR struct ymodem_ctx_s *ctx);
5151
size_t custom_size;
5252
FAR void *priv;
53+
uint8_t interval;
54+
int retry;
5355

5456
/* Public data */
5557

0 commit comments

Comments
 (0)