mirror of
https://github.com/infiniteCable2/panda.git
synced 2026-02-18 09:13:52 +08:00
python: assume F4 MCU for bootstubs without bcdDevice set (#1229)
* python: assume F4 MCU for bootstubs without bcdDevice set * cleanup
This commit is contained in:
@@ -227,8 +227,6 @@ class Panda:
|
||||
self._disable_checks = disable_checks
|
||||
|
||||
self._handle = None
|
||||
self._bcd_device = None
|
||||
|
||||
self.can_rx_overflow_buffer = b''
|
||||
|
||||
# connect and set mcu type
|
||||
@@ -253,13 +251,30 @@ class Panda:
|
||||
self._handle = None
|
||||
|
||||
# try USB first, then SPI
|
||||
self._handle, serial, self.bootstub, self._bcd_device = self.usb_connect(self._serial, claim=claim, wait=wait)
|
||||
self._handle, serial, self.bootstub, bcd = self.usb_connect(self._serial, claim=claim, wait=wait)
|
||||
if self._handle is None:
|
||||
self._handle, serial, self.bootstub, _ = self.spi_connect(self._serial)
|
||||
self._handle, serial, self.bootstub, bcd = self.spi_connect(self._serial)
|
||||
|
||||
if self._handle is None:
|
||||
raise Exception("failed to connect to panda")
|
||||
|
||||
# Some fallback logic to determine panda and MCU type for old bootstubs,
|
||||
# since we now support multiple MCUs and need to know which fw to flash.
|
||||
# Three cases to consider:
|
||||
# A) oldest bootstubs don't have any way to distinguish
|
||||
# MCU or panda type
|
||||
# B) slightly newer (~2 weeks after first C3's built) bootstubs
|
||||
# have the panda type set in the USB bcdDevice
|
||||
# C) latest bootstubs also implement the endpoint for panda type
|
||||
self._bcd_hw_type = None
|
||||
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40)
|
||||
missing_hw_type_endpoint = self.bootstub and ret.startswith(b'\xff\x00\xc1\x3e\xde\xad\xd0\x0d')
|
||||
if missing_hw_type_endpoint and bcd is not None:
|
||||
self._bcd_hw_type = bcd
|
||||
|
||||
# For case A, we assume F4 MCU type, since all H7 pandas should be case B at worst
|
||||
self._assume_f4_mcu = (self._bcd_hw_type is None) and missing_hw_type_endpoint
|
||||
|
||||
self._serial = serial
|
||||
self._mcu_type = self.get_mcu_type()
|
||||
self.health_version, self.can_version, self.can_health_version = self.get_packets_versions()
|
||||
@@ -584,10 +599,9 @@ class Panda:
|
||||
def get_type(self):
|
||||
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40)
|
||||
|
||||
# bootstub doesn't implement this call, so fallback to bcdDevice
|
||||
invalid_type = self.bootstub and (ret is None or len(ret) != 1)
|
||||
if invalid_type and self._bcd_device is not None:
|
||||
ret = self._bcd_device
|
||||
# old bootstubs don't implement this endpoint, see comment in Panda.device
|
||||
if self._bcd_hw_type is not None and (ret is None or len(ret) != 1):
|
||||
ret = self._bcd_hw_type
|
||||
|
||||
return ret
|
||||
|
||||
@@ -608,6 +622,11 @@ class Panda:
|
||||
return McuType.F4
|
||||
elif hw_type in Panda.H7_DEVICES:
|
||||
return McuType.H7
|
||||
else:
|
||||
# have to assume F4, see comment in Panda.connect
|
||||
if self._assume_f4_mcu:
|
||||
return McuType.F4
|
||||
|
||||
raise ValueError(f"unknown HW type: {hw_type}")
|
||||
|
||||
def has_obd(self):
|
||||
|
||||
@@ -5,6 +5,8 @@ from panda import Panda, PandaDFU, McuType, BASEDIR
|
||||
from .helpers import test_all_pandas, panda_connect_and_init, check_signature
|
||||
|
||||
|
||||
# TODO: make more comprehensive bootstub tests and run on a few production ones + current
|
||||
# TODO: also test release-signed app
|
||||
@test_all_pandas
|
||||
@panda_connect_and_init
|
||||
def test_a_known_bootstub(p):
|
||||
@@ -12,25 +14,44 @@ def test_a_known_bootstub(p):
|
||||
Test that compiled app can work with known production bootstub
|
||||
"""
|
||||
known_bootstubs = {
|
||||
McuType.F4: "bootstub.panda.bin",
|
||||
McuType.H7: "bootstub.panda_h7.bin",
|
||||
# covers the two cases listed in Panda.connect
|
||||
McuType.F4: [
|
||||
# case A - no bcdDevice or panda type, has to assume F4
|
||||
"bootstub_f4_first_dos_production.panda.bin",
|
||||
|
||||
# case B - just bcdDevice
|
||||
"bootstub_f4_only_bcd.panda.bin",
|
||||
],
|
||||
McuType.H7: ["bootstub.panda_h7.bin"],
|
||||
}
|
||||
|
||||
p.reset(enter_bootstub=True)
|
||||
p.reset(enter_bootloader=True)
|
||||
for kb in known_bootstubs[p.get_mcu_type()]:
|
||||
app_ids = (p.get_mcu_type(), p.get_usb_serial())
|
||||
assert None not in app_ids
|
||||
|
||||
dfu_serial = PandaDFU.st_serial_to_dfu_serial(p._serial, p._mcu_type)
|
||||
assert Panda.wait_for_dfu(dfu_serial, timeout=30)
|
||||
p.reset(enter_bootstub=True)
|
||||
p.reset(enter_bootloader=True)
|
||||
|
||||
dfu = PandaDFU(dfu_serial)
|
||||
fn = known_bootstubs[p._mcu_type]
|
||||
with open(os.path.join(BASEDIR, "tests/hitl/known_bootstub", fn), "rb") as f:
|
||||
code = f.read()
|
||||
dfu_serial = PandaDFU.st_serial_to_dfu_serial(p._serial, p._mcu_type)
|
||||
assert Panda.wait_for_dfu(dfu_serial, timeout=30)
|
||||
|
||||
dfu.program_bootstub(code)
|
||||
p.connect(True, True)
|
||||
p.flash()
|
||||
check_signature(p)
|
||||
dfu = PandaDFU(dfu_serial)
|
||||
with open(os.path.join(BASEDIR, "tests/hitl/known_bootstub", kb), "rb") as f:
|
||||
code = f.read()
|
||||
|
||||
dfu.program_bootstub(code)
|
||||
|
||||
p.connect(claim=False, wait=True)
|
||||
|
||||
# check for MCU or serial mismatch
|
||||
with Panda(p._serial, claim=False) as np:
|
||||
bootstub_ids = (np.get_mcu_type(), np.get_usb_serial())
|
||||
assert app_ids == bootstub_ids
|
||||
|
||||
# ensure we can flash app and it jumps to app
|
||||
p.flash()
|
||||
check_signature(p)
|
||||
assert not p.bootstub
|
||||
|
||||
@test_all_pandas
|
||||
@panda_connect_and_init
|
||||
|
||||
Binary file not shown.
0
tests/hitl/known_bootstub/bootstub.panda_h7.bin
Executable file → Normal file
0
tests/hitl/known_bootstub/bootstub.panda_h7.bin
Executable file → Normal file
Binary file not shown.
BIN
tests/hitl/known_bootstub/bootstub_f4_only_bcd.panda.bin
Executable file
BIN
tests/hitl/known_bootstub/bootstub_f4_only_bcd.panda.bin
Executable file
Binary file not shown.
Reference in New Issue
Block a user