Quellcode durchsuchen

flashmax.pl: try harder to avoid deadlocks

Unlikely to ever matter, but do try to avoid deadlocks by continuing
to receive during transmit congestion.

Unfortunately that doesn't solve the USB-CDC deadlock problem in
Arduino core 2.0.9.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
H. Peter Anvin vor 1 Jahr
Ursprung
Commit
e12131e19b
1 geänderte Dateien mit 20 neuen und 18 gelöschten Zeilen
  1. 20 18
      tools/flashmax.pl

+ 20 - 18
tools/flashmax.pl

@@ -541,35 +541,35 @@ sub read_fwfile($$) {
     return ([@espfiles], $fpgadata);
 }
 
-sub tty_read {
+sub tty_read($$$;$) {
     state %old_timeout;
-    my($tty,$bufref,$timeout) = @_;
-    my $d = $$bufref;
+    my($tty,$bufref,$timeout,$count) = @_;
 
-    if ($d eq '') {
-	my $c;
+    $count = 1 unless (defined($count));
+
+    if ($$bufref eq '' || !$count) {
 	if (!defined($old_timeout{$tty}) || $timeout != $old_timeout{$tty}) {
 	    $tty->read_const_time($timeout);
 	    $old_timeout{$tty} = $timeout;
 	}
-	($c,$d) = $tty->read(256);
-	return '' if (!$c);
+	my($c,$d) = $tty->read(256);
+	$$bufref .= $d;
     }
 
-    my $r = substr($d,0,1);
-    $$bufref = substr($d,1);
+    my $r = substr($$bufref,0,$count);
+    $$bufref = substr($$bufref,$count);
 
     return $r;
 }
 
-sub tty_write($$) {
-    my($tty,$data) = @_;
+sub tty_write($$$) {
+    my($tty,$bufref,$data) = @_;
     my $bytes = length($data);
     my $offs  = 0;
 
     while ($bytes) {
 	my $cnt = $tty->write(substr($data,$offs,$bytes));
-	usleep(10000) unless ($cnt);
+	tty_read($tty, $bufref, 100, 0) unless ($cnt);
 	$offs  += $cnt;
 	$bytes -= $cnt;
     }
@@ -640,11 +640,11 @@ sub upload_fpgadata($$) {
     my $found = 0;
     my $tt = time();
     my $start_enq = $tt;
-    tty_write($tty, "\005");	# ENQ
+    tty_write($tty, \$ttybuf, "\005");	# ENQ
     while (($tt = time()) - $start_enq < 30) {
 	my $d = tty_read($tty, \$ttybuf, 1000);
 	if ($d eq '') {
-	    tty_write($tty, "\005");	# ENQ
+	    tty_write($tty, \$ttybuf, "\005");	# ENQ
 	} else {
 	    my $ix = index("\026\004\027", $d);
 	    if ($ix < 0) {
@@ -669,7 +669,8 @@ sub upload_fpgadata($$) {
 	    die "$0: $port: failed to start FPGA firmware upload\n";
 	}
 	if ($tt != $last_req) {
-	    tty_write($tty, "\034\001: /// MAX80 FW UPLOAD \~\@\~ \$\r\n\035");
+	    tty_write($tty, \$ttybuf,
+		      "\034\001: /// MAX80 FW UPLOAD \~\@\~ \$\r\n\035");
 	    $last_req = $tt;
 	}
 	my $d;
@@ -743,7 +744,8 @@ sub upload_fpgadata($$) {
 	if (!$chunk) {
 	    if ($bytes > $offset) {
 		if ($now != $last_enq) {
-		    tty_write($tty, "\026"); # SYN: request window resync
+		    # SYN: request window resync
+		    tty_write($tty, \$ttybuf, "\026");
 		    $last_enq = $now;
 		}
 	    }
@@ -753,14 +755,14 @@ sub upload_fpgadata($$) {
 	my $data = substr($fpgadata, $offset, $chunk);
 	my $hdr = pack("CvVV", $chunk-1, 0, $offset, crc32($data));
 
-	tty_write($tty, "\002".mybaseencode($hdr, $data));
+	tty_write($tty, \$ttybuf, "\002".mybaseencode($hdr, $data));
 
 	push(@pktends, $offset + $chunk);
 	$offset += $chunk;
 	$winspc -= $chunk;
     }
 
-    tty_write($tty, "\004");		# EOT
+    tty_write($tty, \$ttybuf, "\004"); # EOT
 
     # Final messages out
     while (1) {