From cd39ce03050f78e82fbf90892cbb203ed9c467f5 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 60920 -> 60820 bytes panda/board/obj/panda_h7.bin.signed | Bin 69748 -> 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 628db1b47d499814a7da12527744e3b5b8350d70..657034f2eff1e26717863b3c85582a4e12355efa 100755 GIT binary patch delta 21 ccmbPJGN)w2En^O2(?m-%GYgB&kBqI@0AOkd%m4rY delta 21 ccmbPJGN)w2En|*kiC8Rl043 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 UIfr*mK7RB_#PvlE$z9n0KPbwP{r~^~ delta 6486 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 diff --git a/panda/board/obj/panda_h7.bin.signed b/panda/board/obj/panda_h7.bin.signed index 8e5194a2bf8fe0230ec0962d4b48d9d89c3285b9..d95c992c738bf54755d6c19e8e8b7a0a1f4d0e59 100644 GIT binary patch delta 7122 zcmb7Jd011|wmSDLc&h$W zpTEoO{JTE>F0=FhPdef4pzV&|?fjo)@9N)ee+30P_)d}5;;SS^zBrpBMh>`~lT0?$ z;Q!)GV2Q|KF?pc|Z*^GBZTXU<;++XWDh_dc;oDF{Qk+6gdJy;8RR7_!qP!HM8SHyI zoe9X>Pg3=+guwd%NoBYYf?Iq-An+grQ*ozLyJ{y$>i{PK-pV_x&<7|=cuT5Pcb-$Z zHIFt}rKBJ)g^cji$=>+9UnS?Z%HCWSRmmM&)txOW7kExpAze_3L|fB&ZfT}GGbvS` zmx6@ddbV#~3YAI-JPpVrT4`u>Pz-KGqOY zwzu>`2Fh{wGH8)^mU$XTGPt?XSpMcCE{X_T7NH~6<29a!Ego*oD4YoIz5Hyu%r|f} zikP;%%ph|D*TV1HOMNq!u49I02kRQu-b# zc_ULU=-2fwk(VUh*7sA~)Vru%luz_7%13%K!n>KPP zw5330fDAwu9>cY|=RvC!um!NM7Eg0o4RfaX-K7Mvb2r1Sm?ih!D%|VApaswhXsg9b zc;#Xv1<~suGC&5%0A%4b4;Ab8zdYu%WDs8- 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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: