From 09a073c242c99b3b44f6668bbdff686bb61afa36 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:04:15 -0600 Subject: [PATCH] Increase Fault Resilience --- panda/board/obj/bootstub.panda.bin | Bin 14876 -> 14876 bytes panda/board/obj/bootstub.panda_h7.bin | Bin 16944 -> 16944 bytes panda/board/obj/panda.bin.signed | Bin 60612 -> 60820 bytes panda/board/obj/panda_h7.bin.signed | Bin 69440 -> 69652 bytes panda/python/__init__.py | 34 ++++++++++++++------------ panda/python/spi.py | 13 +++++++++- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/panda/board/obj/bootstub.panda.bin b/panda/board/obj/bootstub.panda.bin index 021ae9daf05903a4fd4a49838c67d2b8dca916d1..657034f2eff1e26717863b3c85582a4e12355efa 100755 GIT binary patch delta 21 ccmbPJGN)w2En^O2(?m-%GYgB&kBqI@0AOkd%m4rY delta 21 ccmbPJGN)w2En^M~^Aw{rv&5v$kBqI@0Ay(hQUCw| diff --git a/panda/board/obj/bootstub.panda_h7.bin b/panda/board/obj/bootstub.panda_h7.bin index c2066c76b0006ef4d9590eb5b973c765d15c597e..88f36e1f8be0e9cb07235d1ea31ca653e497f91e 100755 GIT binary patch delta 23 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 D0CsM) delta 6147 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 Q_x$G{sk(NVGlkFo9}x-Y5dZ)H diff --git a/panda/board/obj/panda_h7.bin.signed b/panda/board/obj/panda_h7.bin.signed index 65706ef0c9ccb23bf73e24a52c839c48e9ebed73..d95c992c738bf54755d6c19e8e8b7a0a1f4d0e59 100644 GIT binary patch delta 6653 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 B6kGrR delta 6620 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 diff --git a/panda/python/__init__.py b/panda/python/__init__.py index 9339bfcf8..55a794d54 100644 --- a/panda/python/__init__.py +++ b/panda/python/__init__.py @@ -804,7 +804,8 @@ class Panda: # The panda will NAK CAN writes when there is CAN congestion. # libusb will try to send it again, with a max timeout. # Timeout is in ms. If set to 0, the timeout is infinite. - CAN_SEND_TIMEOUT_MS = 10 + CAN_SEND_TIMEOUT_MS = 5 + CAN_MAX_RETRIES = 3 def can_reset_communications(self): self._handle.controlWrite(Panda.REQUEST_OUT, 0xc0, 0, 0, b'') @@ -812,18 +813,18 @@ class Panda: @ensure_can_packet_version def can_send_many(self, arr, timeout=CAN_SEND_TIMEOUT_MS): snds = pack_can_buffer(arr) - while True: - try: - for tx in snds: - while True: - bs = self._handle.bulkWrite(3, tx, timeout=timeout) - tx = tx[bs:] - if len(tx) == 0: - break - logging.error("CAN: PARTIAL SEND MANY, RETRYING") - break - except (usb1.USBErrorIO, usb1.USBErrorOverflow): - logging.error("CAN: BAD SEND MANY, RETRYING") + for tx in snds: + retries = 0 + while len(tx) > 0: + bs = self._handle.bulkWrite(3, tx, timeout=timeout) + if bs == 0: + retries += 1 + if retries > self.CAN_MAX_RETRIES: + logging.warning("CAN send: no progress after retries, dropping") + break + else: + retries = 0 + tx = tx[bs:] def can_send(self, addr, dat, bus, timeout=CAN_SEND_TIMEOUT_MS): self.can_send_many([[addr, None, dat, bus]], timeout=timeout) @@ -831,13 +832,16 @@ class Panda: @ensure_can_packet_version def can_recv(self): dat = bytearray() - while True: + for _ in range(self.CAN_MAX_RETRIES): try: dat = self._handle.bulkRead(1, 16384) # Max receive batch size + 2 extra reserve frames break except (usb1.USBErrorIO, usb1.USBErrorOverflow): logging.error("CAN: BAD RECV, RETRYING") - time.sleep(0.1) + time.sleep(0.01) + else: + logging.error("CAN: recv failed after retries") + return [] msgs, self.can_rx_overflow_buffer = unpack_can_buffer(self.can_rx_overflow_buffer + dat) return msgs diff --git a/panda/python/spi.py b/panda/python/spi.py index be4f7dcf4..681f44a56 100644 --- a/panda/python/spi.py +++ b/panda/python/spi.py @@ -27,7 +27,10 @@ NACK = 0x1F CHECKSUM_START = 0xAB MIN_ACK_TIMEOUT_MS = 100 +MAX_ACK_TIMEOUT_MS = 500 # like C++ SPI_ACK_TIMEOUT +DEFAULT_TIMEOUT_MS = 500 # default when timeout=0 MAX_XFER_RETRY_COUNT = 5 +MAX_TIMEOUT_RETRIES = 5 # like C++ XFER_SIZE = 0x40*31 @@ -152,6 +155,8 @@ class PandaSpiHandle(BaseHandle): return cksum def _wait_for_ack(self, spi, ack_val: int, timeout: int, tx: int, length: int = 1) -> bytes: + # Original behavior preserved - timeout=0 means wait forever within this function + # The caller (_transfer) handles the overall timeout timeout_s = max(MIN_ACK_TIMEOUT_MS, timeout) * 1e-3 start = time.monotonic() @@ -225,10 +230,15 @@ class PandaSpiHandle(BaseHandle): logging.debug("starting transfer: endpoint=%d, max_rx_len=%d", endpoint, max_rx_len) logging.debug("==============================================") + # Fix timeout=0 infinite loop: default to DEFAULT_TIMEOUT_MS + if timeout == 0: + timeout = DEFAULT_TIMEOUT_MS + n = 0 start_time = time.monotonic() exc = PandaSpiException() - while (timeout == 0) or (time.monotonic() - start_time) < timeout*1e-3: + # Use the timeout for the overall loop, matching original behavior but with timeout=0 fixed + while (time.monotonic() - start_time) < timeout * 1e-3: n += 1 logging.debug("\ntry #%d", n) with self.dev.acquire() as spi: @@ -238,6 +248,7 @@ class PandaSpiHandle(BaseHandle): exc = e logging.debug("SPI transfer failed, retrying", exc_info=True) + logging.error("SPI transfer failed after %d tries, %.2fms", n, (time.monotonic() - start_time) * 1000) raise exc def get_protocol_version(self) -> bytes: