mirror of https://github.com/commaai/panda.git
jungle HITL tests setup (#1665)
* setup new zoo * run * fix --------- Co-authored-by: Bruce Wayne <batman@comma.ai>
This commit is contained in:
parent
b6e37f25b6
commit
43bed1aa47
|
@ -99,7 +99,6 @@ pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
stage ('Acquire resource locks') {
|
||||
options {
|
||||
lock(resource: "pandas")
|
||||
|
@ -115,15 +114,16 @@ pipeline {
|
|||
}
|
||||
}
|
||||
}
|
||||
stage('prep') {
|
||||
stage('jungle tests') {
|
||||
steps {
|
||||
script {
|
||||
retry (3) {
|
||||
docker_run("reset hardware", 3, "python ./tests/ci_reset_hw.py")
|
||||
docker_run("reset hardware", 3, "python ./tests/hitl/reset_jungles.py")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
stage('pedal tests') {
|
||||
steps {
|
||||
script {
|
||||
|
@ -146,9 +146,9 @@ pipeline {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ class McuConfig(NamedTuple):
|
|||
mcu: str
|
||||
mcu_idcode: int
|
||||
sector_sizes: List[int]
|
||||
sector_count: int # total sector count, used for MCU identification in DFU mode
|
||||
uid_address: int
|
||||
block_size: int
|
||||
serial_number_address: int
|
||||
|
@ -32,13 +33,14 @@ Fx = (
|
|||
0x8000000,
|
||||
"bootstub.panda.bin",
|
||||
)
|
||||
F2Config = McuConfig("STM32F2", 0x411, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(7)], *Fx)
|
||||
F4Config = McuConfig("STM32F4", 0x463, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(11)], *Fx)
|
||||
F2Config = McuConfig("STM32F2", 0x411, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(7)], 12, *Fx)
|
||||
F4Config = McuConfig("STM32F4", 0x463, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(11)], 16, *Fx)
|
||||
|
||||
H7Config = McuConfig(
|
||||
"STM32H7",
|
||||
0x483,
|
||||
[0x20000 for _ in range(7)],
|
||||
8,
|
||||
0x1FF1E800,
|
||||
0x400,
|
||||
# there is an 8th sector, but we use that for the provisioning chunk, so don't program over that!
|
||||
|
|
|
@ -34,13 +34,14 @@ class STBootloaderUSBHandle(BaseSTBootloaderHandle):
|
|||
def __init__(self, libusb_device, libusb_handle):
|
||||
self._libusb_handle = libusb_handle
|
||||
|
||||
# lsusb -v | grep Flash
|
||||
# example from F4: lsusb -v | grep Flash
|
||||
# iInterface 4 @Internal Flash /0x08000000/04*016Kg,01*064Kg,011*128Kg
|
||||
out = libusb_handle.controlRead(0x80, 0x06, 0x0300 | 4, 0, 255)
|
||||
flash_desc = bytes(out[2:]).decode('utf-16le')
|
||||
sector_count = sum([int(s.split('*')[0]) for s in flash_desc.split('/')[-1].split(',')])
|
||||
|
||||
mcu_by_sector_count = {len(m.config.sector_sizes): m for m in McuType}
|
||||
for i in range(20):
|
||||
desc = libusb_handle.getStringDescriptor(i, 0)
|
||||
if desc is not None and desc.startswith("@Internal Flash"):
|
||||
sector_count = sum([int(s.split('*')[0]) for s in desc.split('/')[-1].split(',')])
|
||||
break
|
||||
mcu_by_sector_count = {m.config.sector_count: m for m in McuType}
|
||||
assert sector_count in mcu_by_sector_count, f"Unkown MCU: {sector_count=}"
|
||||
self._mcu_type = mcu_by_sector_count[sector_count]
|
||||
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
import concurrent.futures
|
||||
|
||||
from panda import Panda, PandaDFU, PandaJungle
|
||||
from panda.tests.libs.resetter import Resetter
|
||||
|
||||
# all jungles used in the HITL tests
|
||||
JUNGLES = [
|
||||
"058010800f51363038363036",
|
||||
"23002d000851393038373731"
|
||||
]
|
||||
|
||||
|
||||
# Reset + flash all CI hardware to get it into a consistent state
|
||||
# * ports 1-2 are jungles
|
||||
# * port 3 is for the USB hubs
|
||||
if __name__ == "__main__":
|
||||
r = Resetter()
|
||||
|
||||
r.enable_boot(True)
|
||||
r.cycle_power(delay=7, ports=[1, 2, 3])
|
||||
r.enable_boot(False)
|
||||
|
||||
pandas = PandaDFU.list()
|
||||
print("DFU pandas:", pandas)
|
||||
assert len(pandas) == 7
|
||||
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=len(pandas)) as exc:
|
||||
def recover(serial):
|
||||
PandaDFU(serial).recover()
|
||||
list(exc.map(recover, pandas, timeout=20))
|
||||
|
||||
r.cycle_power(delay=7, ports=[1, 2])
|
||||
|
||||
pandas = Panda.list()
|
||||
print(pandas)
|
||||
assert len(pandas) >= 7
|
||||
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=len(pandas)) as exc:
|
||||
def flash(serial):
|
||||
with Panda(serial) as pf:
|
||||
if pf.bootstub:
|
||||
pf.flash()
|
||||
list(exc.map(flash, pandas, timeout=20))
|
||||
|
||||
print("flashing jungle")
|
||||
# flash jungles
|
||||
pjs = PandaJungle.list()
|
||||
assert set(pjs) == set(JUNGLES), f"Got different jungles than expected:\ngot {set(pjs)}\nexpected {set(JUNGLES)}"
|
||||
for s in pjs:
|
||||
with PandaJungle(serial=s) as pj:
|
||||
print(f"- flashing {s}")
|
||||
pj.flash()
|
||||
|
||||
r.cycle_power(delay=0, ports=[1, 2])
|
||||
r.close()
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python3
|
||||
import concurrent.futures
|
||||
|
||||
from panda import PandaJungle, PandaJungleDFU, McuType
|
||||
from panda.tests.libs.resetter import Resetter
|
||||
|
||||
def recover(s):
|
||||
with PandaJungleDFU(s) as pd:
|
||||
pd.recover()
|
||||
|
||||
def flash(s):
|
||||
with PandaJungle(s) as p:
|
||||
p.flash()
|
||||
return p.get_mcu_type()
|
||||
|
||||
# Reset + flash all CI hardware to get it into a consistent state
|
||||
# * port 1: jungles-under-test
|
||||
# * port 2: USB hubs
|
||||
# * port 3: HITL pandas and their jungles
|
||||
if __name__ == "__main__":
|
||||
with Resetter() as r:
|
||||
# everything off
|
||||
for i in range(1, 4):
|
||||
r.enable_power(i, 0)
|
||||
r.cycle_power(ports=[1, 2], dfu=True)
|
||||
|
||||
dfu_serials = PandaJungleDFU.list()
|
||||
assert len(dfu_serials) == 2
|
||||
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=len(dfu_serials)) as exc:
|
||||
list(exc.map(recover, dfu_serials, timeout=30))
|
||||
|
||||
# power cycle for H7 bootloader bug
|
||||
r.cycle_power(ports=[1, 2])
|
||||
|
||||
serials = PandaJungle.list()
|
||||
assert len(serials) == len(dfu_serials)
|
||||
mcu_types = list(exc.map(flash, serials, timeout=20))
|
||||
assert set(mcu_types) == {McuType.F4, McuType.H7}
|
|
@ -7,6 +7,12 @@ class Resetter():
|
|||
self._handle = None
|
||||
self.connect()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
self._handle.close()
|
||||
self._context.close()
|
||||
|
@ -36,16 +42,16 @@ class Resetter():
|
|||
def enable_boot(self, enabled):
|
||||
self._handle.controlWrite((usb1.ENDPOINT_OUT | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE), 0xff, 0, enabled, b'')
|
||||
|
||||
def cycle_power(self, delay=5, ports=None):
|
||||
def cycle_power(self, delay=5, dfu=False, ports=None):
|
||||
if ports is None:
|
||||
ports = [1, 2, 3]
|
||||
|
||||
self.enable_boot(dfu)
|
||||
for port in ports:
|
||||
self.enable_power(port, False)
|
||||
|
||||
time.sleep(1)
|
||||
time.sleep(0.5)
|
||||
|
||||
for port in ports:
|
||||
self.enable_power(port, True)
|
||||
|
||||
time.sleep(delay)
|
||||
self.enable_boot(False)
|
||||
|
|
Loading…
Reference in New Issue