Forráskód Böngészése

fwupdate: wait for final messages in flashesp; try better error handling

Stick around for long enough that the final messages can be printed
when flashing over the serial port.

Try to be better about error recovery in the tty code. Still locks up
over USB, though...
H. Peter Anvin 2 éve
szülő
commit
0955b6144c
7 módosított fájl, 75 hozzáadás és 24 törlés
  1. 27 10
      esp32/flashesp.pl
  2. 1 1
      esp32/max80/max80.ino
  3. 37 8
      esp32/max80/tty.cpp
  4. 10 5
      esp32/max80/tty.h
  5. BIN
      esp32/output/max80.ino.bin
  6. BIN
      fpga/output/v1.fw
  7. BIN
      fpga/output/v2.fw

+ 27 - 10
esp32/flashesp.pl

@@ -7,6 +7,7 @@ use File::Temp;
 use File::Spec;
 use Time::HiRes qw(usleep tv_interval);
 use Digest::CRC qw(crc32);
+use v5.10;			# For "state"
 
 my $esptool = ($^O eq 'MSWin32') ? 'esptool.exe' : 'esptool.py';
 $esptool = $ENV{'ESPTOOL'} || $esptool;
@@ -249,7 +250,14 @@ foreach my $o (sort grep (/^flash_/, keys %espopt)) {
 push(@espcmd, @espfiles);
 
 print STDERR join(' ', @espcmd), "\n";
-$err = system(@espcmd);
+my $retries = 4;
+my $err = 0;
+while ($retries--) {
+    # Sometimes esptool tanks out for no reason, with error 256
+    $err = system(@espcmd);
+    last if ($err != 256);
+    usleep(1000000);
+}
 if ($err == -1) {
     print STDERR "$0: $espcmd[0]: $!\n";
 } elsif ($err) {
@@ -282,22 +290,20 @@ $tty->error_msg(1);
 $tty->handshake('none');
 $tty->databits(8);
 $tty->baudrate(115200);
-$tty->parity('none');
 $tty->stopbits(1);
+$tty->parity('none');
+$tty->stty_istrip(0);
+$tty->stty_inpck(0);
 $tty->datatype('raw');
+$tty->stty_icanon(0);
+$tty->stty_opost(0);
 $tty->stty_ignbrk(0);
-#$tty->stty_brkint(0);
-$tty->stty_parmrk(0);
-$tty->stty_istrip(0);
 $tty->stty_inlcr(0);
 $tty->stty_igncr(0);
 $tty->stty_icrnl(0);
-$tty->stty_opost(0);
 $tty->stty_echo(0);
 $tty->stty_echonl(0);
-$tty->stty_icanon(0);
 $tty->stty_isig(0);
-#$tty->stty_iexten(0);
 $tty->read_char_time(0);
 $tty->write_settings;
 
@@ -314,12 +320,16 @@ if ($tty->can_modemlines && !($tty->modemlines & $tty->MS_CTS_ON)) {
 }
 
 sub tty_read {
+    state %old_timeout;
     my($tty,$bufref,$timeout) = @_;
     my $d = $$bufref;
 
     if ($d eq '') {
 	my $c;
-	$tty->read_const_time($timeout);
+	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);
     }
@@ -466,8 +476,15 @@ while ($last_ack < $bytes) {
 }
 
 tty_write($tty, "\004");		# EOT
+
+# Final messages out
+while (1) {
+    my $d = tty_read($tty, \$ttybuf, 1000);
+    last if ($d eq '');
+    print STDERR $d;
+}
 $tty->close;
 
-print STDERR "$0: $port: firmware upload complete\n";
+print STDERR "\n$0: $port: firmware upload complete\n";
 
 exit 0;

+ 1 - 1
esp32/max80/max80.ino

@@ -167,7 +167,7 @@ static void dump_tasks(void)
 }
 
 void loop() {
-    if (0) {
+    if (1) {
 	printf("loop task: %s\n", pcTaskGetName(xTaskGetCurrentTaskHandle()));
 	printf("idle task: %s\n", pcTaskGetName(xTaskGetIdleTaskHandle()));
 	dump_tasks();

+ 37 - 8
esp32/max80/tty.cpp

@@ -44,11 +44,15 @@ void TTY::reset()
     rx.b64_bits = 0;
 }
 
+static void null_flush(void)
+{
+}
 
 TTY::TTY(Stream &port)
 {
     _port = &port;
     rx_sbuf = true ? xStreamBufferCreate(STREAMBUF_SIZE, 1) : NULL;
+    _flush = null_flush;
     reset();
 }
 
@@ -67,21 +71,31 @@ int TTY::rxdata(void *buf, size_t len)
 
     int rcv = 0;
     while (!rcv) {
-	if (tx_credits_reset) {
-	    // Drain input before WRST
-	    rcv = xStreamBufferReceive(rx_sbuf, buf, len, 0);
+	rcv = xStreamBufferReceive(rx_sbuf, buf, len, 0);
+	if (rcv)
+	    break;
 
-	    if (rcv)
-		break;
+	uint32_t now = millis();
+	if (now - last_rx > 500) {
+	    last_rx = now;
+	    tx_credits_reset = true;
+	}
 
+	if (tx_credits_reset) {
+	    // Drain input before WRST
+	    flush();
 	    if (port().write(WRST)) {
-		printf("[UPLD] Resetting window\n");
+		printf("[UPLD] Resetting window, last_ack = %u\n", rx.last_ack);
 		tx_credits_reset = false;
 		tx_credits = STREAMBUF_SIZE - BUF_SLACK;
 	    } else {
 		// Uhm... wait a tiny bit and then try again to sent WRST?
-		printf("[UPLD] Failed to reset window?!\n");
-		rcv = xStreamBufferReceive(rx_sbuf, buf, len, 10);
+		static bool failed_once = false;
+		if (!failed_once) {
+		    printf("[UPLD] Failed to reset window?!\n");
+		    failed_once = true;
+		}
+		rcv = xStreamBufferReceive(rx_sbuf, buf, len, 1);
 	    }
 	} else {
 	    while (tx_credits >= WGO_CHUNK && port().write(WGO))
@@ -181,6 +195,8 @@ void TTY::_onrx()
     int byte, data;
 
     while ((byte = port().read()) >= 0) {
+	last_rx = millis();
+
 	switch (rx.state) {
 	case rx_state::normal:
 	    if (rx.rlen < sizeof fwupload_start &&
@@ -398,17 +414,30 @@ void TTY::uart_onerr(hardwareSerial_error_t err)
     }
 }
 
+static void uart_flush()
+{
+    Serial0.flush(true);
+}
+
+static void usb_flush()
+{
+    Serial.flush();
+}
+
 void TTY::init()
 {
     enq_str[sizeof(enq_str)-5] += max80_board_version;
 
     uart_tty = new TTY(Serial0);
+    uart_tty->_flush = uart_flush;
     Serial0.begin(BAUD_RATE);
     Serial0.onReceive(uart_onrx, false);
     Serial0.onReceiveError(uart_onerr);
 
     usb_tty  = new TTY(Serial);
+    usb_tty->_flush = usb_flush;
     Serial.onEvent(usb_onevent);
+    Serial.enableReboot(true);
 }
 
 void TTY::ping()

+ 10 - 5
esp32/max80/tty.h

@@ -25,29 +25,33 @@ struct tty_packet_hdr {
 } __attribute__((packed));
 
 class TTY {
-private:
-    Stream *_port;		// Android stream
-
 public:
     TTY(Stream &port);
     ~TTY();
     void reset();
     int  rxdata(void *buf, size_t len);
     static int rxdata(token_t me, void *buf, size_t len);
-    inline Stream & port() { return *_port; }
-    inline operator Stream & () { return port(); }
 
     // Global events
     static void init();
     static void ping();
 
 private:
+    Stream *_port;		// Android stream
+
     void _onrx();
     void _onerr();
     void _onbreak();
     void _onconnect();
     void _ondisconnect();
+    void (*_flush)();
+
+public:
+    inline void flush() { _flush(); }
+    inline Stream & port() { return *_port; }
+    inline operator Stream & () { return port(); }
 
+private:
     // Event handler dispatchers
     static void usb_onevent(void *arg, esp_event_base_t event_base,
 			    int32_t event_id, void *event_data);
@@ -80,5 +84,6 @@ private:
     StreamBufferHandle_t rx_sbuf;
     uint32_t tx_credits;
     volatile bool tx_credits_reset;
+    volatile uint32_t last_rx;
     uint8_t rx_data[256];
 };

BIN
esp32/output/max80.ino.bin


BIN
fpga/output/v1.fw


BIN
fpga/output/v2.fw