mirror of https://github.com/commaai/openpilot.git
125 lines
3.3 KiB
Python
Executable File
125 lines
3.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# simple boardd wrapper that updates the panda first
|
|
import os
|
|
import time
|
|
|
|
from panda import BASEDIR as PANDA_BASEDIR, Panda, PandaDFU, build_st
|
|
from common.basedir import BASEDIR
|
|
from common.gpio import gpio_init, gpio_set
|
|
from selfdrive.hardware import TICI
|
|
from selfdrive.hardware.tici.pins import GPIO_HUB_RST_N, GPIO_STM_BOOT0, GPIO_STM_RST_N
|
|
from selfdrive.swaglog import cloudlog
|
|
|
|
def is_legacy_panda_reset():
|
|
return os.path.isfile("/persist/LEGACY_PANDA_RESET")
|
|
|
|
def set_panda_power(power=True):
|
|
if not TICI:
|
|
return
|
|
|
|
gpio_init(GPIO_STM_RST_N, True)
|
|
gpio_init(GPIO_STM_BOOT0, True)
|
|
|
|
gpio_set(GPIO_STM_RST_N, False if is_legacy_panda_reset() else True)
|
|
gpio_set(GPIO_HUB_RST_N, True)
|
|
|
|
time.sleep(0.1)
|
|
|
|
gpio_set(GPIO_STM_RST_N, power if is_legacy_panda_reset() else (not power))
|
|
|
|
|
|
def get_firmware_fn():
|
|
signed_fn = os.path.join(PANDA_BASEDIR, "board", "obj", "panda.bin.signed")
|
|
if os.path.exists(signed_fn):
|
|
cloudlog.info("Using prebuilt signed firmware")
|
|
return signed_fn
|
|
else:
|
|
cloudlog.info("Building panda firmware")
|
|
fn = "obj/panda.bin"
|
|
build_st(fn, clean=False)
|
|
return os.path.join(PANDA_BASEDIR, "board", fn)
|
|
|
|
|
|
def get_expected_signature(fw_fn=None):
|
|
if fw_fn is None:
|
|
fw_fn = get_firmware_fn()
|
|
|
|
try:
|
|
return Panda.get_signature_from_firmware(fw_fn)
|
|
except Exception:
|
|
cloudlog.exception("Error computing expected signature")
|
|
return b""
|
|
|
|
|
|
def update_panda():
|
|
panda = None
|
|
panda_dfu = None
|
|
|
|
cloudlog.info("Connecting to panda")
|
|
|
|
while True:
|
|
# break on normal mode Panda
|
|
panda_list = Panda.list()
|
|
if len(panda_list) > 0:
|
|
cloudlog.info("Panda found, connecting")
|
|
panda = Panda(panda_list[0])
|
|
break
|
|
|
|
# flash on DFU mode Panda
|
|
panda_dfu = PandaDFU.list()
|
|
if len(panda_dfu) > 0:
|
|
cloudlog.info("Panda in DFU mode found, flashing recovery")
|
|
panda_dfu = PandaDFU(panda_dfu[0])
|
|
panda_dfu.recover()
|
|
|
|
time.sleep(1)
|
|
|
|
fw_fn = get_firmware_fn()
|
|
fw_signature = get_expected_signature(fw_fn)
|
|
|
|
try:
|
|
serial = panda.get_serial()[0].decode("utf-8")
|
|
except Exception:
|
|
serial = None
|
|
|
|
panda_version = "bootstub" if panda.bootstub else panda.get_version()
|
|
panda_signature = b"" if panda.bootstub else panda.get_signature()
|
|
cloudlog.warning("Panda %s connected, version: %s, signature %s, expected %s" % (
|
|
serial,
|
|
panda_version,
|
|
panda_signature.hex(),
|
|
fw_signature.hex(),
|
|
))
|
|
|
|
if panda.bootstub or panda_signature != fw_signature:
|
|
cloudlog.info("Panda firmware out of date, update required")
|
|
panda.flash(fw_fn)
|
|
cloudlog.info("Done flashing")
|
|
|
|
if panda.bootstub:
|
|
bootstub_version = panda.get_version()
|
|
cloudlog.info(f"Flashed firmware not booting, flashing development bootloader. Bootstub version: {bootstub_version}")
|
|
panda.recover()
|
|
cloudlog.info("Done flashing bootloader")
|
|
|
|
if panda.bootstub:
|
|
cloudlog.info("Panda still not booting, exiting")
|
|
raise AssertionError
|
|
|
|
panda_signature = panda.get_signature()
|
|
if panda_signature != fw_signature:
|
|
cloudlog.info("Version mismatch after flashing, exiting")
|
|
raise AssertionError
|
|
|
|
|
|
def main():
|
|
set_panda_power()
|
|
update_panda()
|
|
|
|
os.chdir(os.path.join(BASEDIR, "selfdrive/boardd"))
|
|
os.execvp("./boardd", ["./boardd"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|