mirror of https://github.com/commaai/panda.git
Add multiple pandas selector (#2015)
* multiple Panda cli helper * Don't flash all pandas by default. Use --all arg to flash all.
This commit is contained in:
parent
2037a2ead7
commit
38cab7d501
|
@ -106,7 +106,7 @@ pipeline {
|
||||||
phone_steps("panda-tres", [
|
phone_steps("panda-tres", [
|
||||||
["build", "scons -j4"],
|
["build", "scons -j4"],
|
||||||
["flash", "cd tests/ && ./reflash_internal_panda.py"],
|
["flash", "cd tests/ && ./reflash_internal_panda.py"],
|
||||||
["flash jungle", "cd board/jungle && ./flash.py"],
|
["flash jungle", "cd board/jungle && ./flash.py --all"],
|
||||||
["test", "cd tests/hitl && HW_TYPES=9 pytest -n0 --durations=0 2*.py [5-9]*.py"],
|
["test", "cd tests/hitl && HW_TYPES=9 pytest -n0 --durations=0 2*.py [5-9]*.py"],
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ pipeline {
|
||||||
phone_steps("panda-dos", [
|
phone_steps("panda-dos", [
|
||||||
["build", "scons -j4"],
|
["build", "scons -j4"],
|
||||||
["flash", "cd tests/ && ./reflash_internal_panda.py"],
|
["flash", "cd tests/ && ./reflash_internal_panda.py"],
|
||||||
["flash jungle", "cd board/jungle && ./flash.py"],
|
["flash jungle", "cd board/jungle && ./flash.py --all"],
|
||||||
["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-9]*.py -k 'not test_send_recv'"],
|
["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-9]*.py -k 'not test_send_recv'"],
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,27 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
|
||||||
from panda import Panda
|
from panda import Panda
|
||||||
|
|
||||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--all", action="store_true", help="Recover all Panda devices")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)
|
subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)
|
||||||
|
|
||||||
serials = Panda.list()
|
if args.all:
|
||||||
print(f"found {len(serials)} panda(s) - {serials}")
|
serials = Panda.list()
|
||||||
|
print(f"found {len(serials)} panda(s) - {serials}")
|
||||||
|
else:
|
||||||
|
serials = [None]
|
||||||
|
|
||||||
for s in serials:
|
for s in serials:
|
||||||
print("flashing", s)
|
|
||||||
with Panda(serial=s) as p:
|
with Panda(serial=s) as p:
|
||||||
|
print("flashing", p.get_usb_serial())
|
||||||
p.flash()
|
p.flash()
|
||||||
exit(1 if len(serials) == 0 else 0)
|
exit(1 if len(serials) == 0 else 0)
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
|
||||||
from panda import PandaJungle
|
from panda import PandaJungle
|
||||||
|
|
||||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--all", action="store_true", help="Recover all panda jungle devices")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) {board_path}", shell=True)
|
subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) {board_path}", shell=True)
|
||||||
|
|
||||||
serials = PandaJungle.list()
|
if args.all:
|
||||||
print(f"found {len(serials)} panda jungle(s) - {serials}")
|
serials = PandaJungle.list()
|
||||||
for s in serials:
|
print(f"found {len(serials)} panda jungles(s) - {serials}")
|
||||||
print("flashing", s)
|
else:
|
||||||
with PandaJungle(serial=s) as p:
|
serials = [None]
|
||||||
p.flash()
|
|
||||||
|
|
||||||
|
for s in serials:
|
||||||
|
with PandaJungle(serial=s) as p:
|
||||||
|
print("flashing", p.get_usb_serial())
|
||||||
|
p.flash()
|
||||||
exit(1 if len(serials) == 0 else 0)
|
exit(1 if len(serials) == 0 else 0)
|
||||||
|
|
|
@ -2,17 +2,23 @@
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
|
||||||
from panda import PandaJungle, PandaJungleDFU
|
from panda import PandaJungle, PandaJungleDFU
|
||||||
|
|
||||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--all", action="store_true", help="Recover all panda jungle devices")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) {board_path}", shell=True)
|
subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) {board_path}", shell=True)
|
||||||
|
|
||||||
for s in PandaJungle.list():
|
serials = PandaJungle.list() if args.all else [None]
|
||||||
print("putting", s, "in DFU mode")
|
for s in serials:
|
||||||
with PandaJungle(serial=s) as p:
|
with PandaJungle(serial=s) as p:
|
||||||
|
print(f"putting {p.get_usb_serial()} in DFU mode")
|
||||||
p.reset(enter_bootstub=True)
|
p.reset(enter_bootstub=True)
|
||||||
p.reset(enter_bootloader=True)
|
p.reset(enter_bootloader=True)
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,23 @@
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
|
||||||
from panda import Panda, PandaDFU
|
from panda import Panda, PandaDFU
|
||||||
|
|
||||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--all", action="store_true", help="Recover all Panda devices")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)
|
subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)
|
||||||
|
|
||||||
for s in Panda.list():
|
serials = Panda.list() if args.all else [None]
|
||||||
print("putting", s, "in DFU mode")
|
for s in serials:
|
||||||
with Panda(serial=s) as p:
|
with Panda(serial=s) as p:
|
||||||
|
print(f"putting {p.get_usb_serial()} in DFU mode")
|
||||||
p.reset(enter_bootstub=True)
|
p.reset(enter_bootstub=True)
|
||||||
p.reset(enter_bootloader=True)
|
p.reset(enter_bootloader=True)
|
||||||
|
|
||||||
|
|
|
@ -224,8 +224,7 @@ class Panda:
|
||||||
FLAG_FORD_LONG_CONTROL = 1
|
FLAG_FORD_LONG_CONTROL = 1
|
||||||
FLAG_FORD_CANFD = 2
|
FLAG_FORD_CANFD = 2
|
||||||
|
|
||||||
def __init__(self, serial: str | None = None, claim: bool = True, disable_checks: bool = True, can_speed_kbps: int = 500):
|
def __init__(self, serial: str | None = None, claim: bool = True, disable_checks: bool = True, can_speed_kbps: int = 500, cli: bool = True):
|
||||||
self._connect_serial = serial
|
|
||||||
self._disable_checks = disable_checks
|
self._disable_checks = disable_checks
|
||||||
|
|
||||||
self._handle: BaseHandle
|
self._handle: BaseHandle
|
||||||
|
@ -233,9 +232,38 @@ class Panda:
|
||||||
self.can_rx_overflow_buffer = b''
|
self.can_rx_overflow_buffer = b''
|
||||||
self._can_speed_kbps = can_speed_kbps
|
self._can_speed_kbps = can_speed_kbps
|
||||||
|
|
||||||
|
if cli and serial is None:
|
||||||
|
self._connect_serial = self._cli_select_panda()
|
||||||
|
else:
|
||||||
|
self._connect_serial = serial
|
||||||
|
|
||||||
# connect and set mcu type
|
# connect and set mcu type
|
||||||
self.connect(claim)
|
self.connect(claim)
|
||||||
|
|
||||||
|
def _cli_select_panda(self):
|
||||||
|
dfu_pandas = PandaDFU.list()
|
||||||
|
if len(dfu_pandas) > 0:
|
||||||
|
print("INFO: some attached pandas are in DFU mode.")
|
||||||
|
|
||||||
|
pandas = self.list()
|
||||||
|
if len(pandas) == 0:
|
||||||
|
print("INFO: panda not available")
|
||||||
|
return None
|
||||||
|
if len(pandas) == 1:
|
||||||
|
print(f"INFO: connecting to panda {pandas[0]}")
|
||||||
|
time.sleep(1)
|
||||||
|
return pandas[0]
|
||||||
|
while True:
|
||||||
|
print("Multiple pandas available:")
|
||||||
|
pandas.sort()
|
||||||
|
for idx, serial in enumerate(pandas):
|
||||||
|
print(f"{[idx]}: {serial}")
|
||||||
|
try:
|
||||||
|
choice = int(input("Choose serial [0]:") or "0")
|
||||||
|
return pandas[choice]
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
print("Enter a valid index.")
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -391,6 +419,12 @@ class Panda:
|
||||||
|
|
||||||
return context, usb_handle, usb_serial, bootstub, bcd
|
return context, usb_handle, usb_serial, bootstub, bcd
|
||||||
|
|
||||||
|
def is_connected_spi(self):
|
||||||
|
return isinstance(self._handle, PandaSpiHandle)
|
||||||
|
|
||||||
|
def is_connected_usb(self):
|
||||||
|
return isinstance(self._handle, PandaUsbHandle)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def list(cls):
|
def list(cls):
|
||||||
ret = cls.usb_list()
|
ret = cls.usb_list()
|
||||||
|
|
Loading…
Reference in New Issue