openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
6.0 KiB

#!/usr/bin/env python3
# simple pandad wrapper that updates the panda first
import os
import usb1
import time
pandad: reset safety mode on exit (#32103) * boardd: reset safety mode on exit old-commit-hash: dd18ccbf0a9ab72ace0a7533632d5939c0719953 * comment old-commit-hash: 01b598e8dde93548f7783be19b1cb37d22fadc23 * log it old-commit-hash: 181c4d412e9e3a9c576934e16fc26a9b6e07a117 * logmessaged might not be alive old-commit-hash: 7483ba0eac42875a822df97596d23ff277bf3865 * reproduction, manager gets SIGTERM from python_process old-commit-hash: b90402bd776c3933bfe3dd60998f9913b4bd0068 * even smaller repro old-commit-hash: 03dd430b7131da2b48243714df0513c6a1e594f0 * should work old-commit-hash: 388c4273385ee4c67b1a229ccb9abac6dd94dd0f * let's not change that rn old-commit-hash: d057299058503e8fb792b5a765d0da4af6bef943 * something like this old-commit-hash: 123d6ed845d662aec2bd95d1ccf9c2782308d693 * pandad.cc should receive same SIGTERM and exit old-commit-hash: afc5ef6b916c54ac2ec471d144f601ead71250cb * stash old-commit-hash: e02e0dc488de51c5d40d227c4c2202ba40436d8d * remove debugging old-commit-hash: ac170d0ca32a4285be22e28ec7730fcba3d0697d * remove debugging old-commit-hash: 50949600aeed231347cc4c600a8a7d24accde674 * match behavior old-commit-hash: 5f24167c58caf98b641af2f63f839015e404c349 * convention old-commit-hash: 1664113a232c4b1a3aa67073e9e8cebef414518f * systemd option old-commit-hash: 95183ff77842fcb9592715db07396be28d778197 * manager option old-commit-hash: 2071893299cb32c3a7cd8a444d8d386c5fa96511 * just curious if this works, change to ELM327 on exit old-commit-hash: 9674ed525134aa03f995942b18163cb047a59c5b * Revert "just curious if this works, change to ELM327 on exit" This reverts commit d4ae294d419dc3d787d11dee4474799f3fb2acef. old-commit-hash: 6d24edd1635ddd0b8ed68a4a4fc8aaaa88984e45 * check onroad same update * useless * comment * fix * debug * Revert "debug" This reverts commit 2bb138610ea7b26d8610d36ef3f0bbb2d6ada388. * Update common/util.h * double wait does not work, blocking in signal handler not good, exit on do_exit, change to SIGINT, use existing stop to support ctrl+c nope * organize? * no sys * None --------- Co-authored-by: Shane Smiskol <shane@smiskol.com>
3 months ago
import signal
import subprocess
from panda import Panda, PandaDFU, PandaProtocolMismatch, FW_PATH
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
from openpilot.system.hardware import HARDWARE
from openpilot.common.swaglog import cloudlog
def get_expected_signature(panda: Panda) -> bytes:
try:
fn = os.path.join(FW_PATH, panda.get_mcu_type().config.app_fn)
return Panda.get_signature_from_firmware(fn)
except Exception:
cloudlog.exception("Error computing expected signature")
return b""
def flash_panda(panda_serial: str) -> Panda:
try:
panda = Panda(panda_serial)
except PandaProtocolMismatch:
cloudlog.warning("detected protocol mismatch, reflashing panda")
HARDWARE.recover_internal_panda()
raise
fw_signature = get_expected_signature(panda)
internal_panda = panda.is_internal()
panda_version = "bootstub" if panda.bootstub else panda.get_version()
panda_signature = b"" if panda.bootstub else panda.get_signature()
cloudlog.warning(f"Panda {panda_serial} connected, version: {panda_version}, signature {panda_signature.hex()[:16]}, expected {fw_signature.hex()[:16]}")
if panda.bootstub or panda_signature != fw_signature:
cloudlog.info("Panda firmware out of date, update required")
panda.flash()
cloudlog.info("Done flashing")
if panda.bootstub:
bootstub_version = panda.get_version()
cloudlog.info(f"Flashed firmware not booting, flashing development bootloader. {bootstub_version=}, {internal_panda=}")
if internal_panda:
HARDWARE.recover_internal_panda()
panda.recover(reset=(not internal_panda))
cloudlog.info("Done flashing bootstub")
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
return panda
pandad: reset safety mode on exit (#32103) * boardd: reset safety mode on exit old-commit-hash: dd18ccbf0a9ab72ace0a7533632d5939c0719953 * comment old-commit-hash: 01b598e8dde93548f7783be19b1cb37d22fadc23 * log it old-commit-hash: 181c4d412e9e3a9c576934e16fc26a9b6e07a117 * logmessaged might not be alive old-commit-hash: 7483ba0eac42875a822df97596d23ff277bf3865 * reproduction, manager gets SIGTERM from python_process old-commit-hash: b90402bd776c3933bfe3dd60998f9913b4bd0068 * even smaller repro old-commit-hash: 03dd430b7131da2b48243714df0513c6a1e594f0 * should work old-commit-hash: 388c4273385ee4c67b1a229ccb9abac6dd94dd0f * let's not change that rn old-commit-hash: d057299058503e8fb792b5a765d0da4af6bef943 * something like this old-commit-hash: 123d6ed845d662aec2bd95d1ccf9c2782308d693 * pandad.cc should receive same SIGTERM and exit old-commit-hash: afc5ef6b916c54ac2ec471d144f601ead71250cb * stash old-commit-hash: e02e0dc488de51c5d40d227c4c2202ba40436d8d * remove debugging old-commit-hash: ac170d0ca32a4285be22e28ec7730fcba3d0697d * remove debugging old-commit-hash: 50949600aeed231347cc4c600a8a7d24accde674 * match behavior old-commit-hash: 5f24167c58caf98b641af2f63f839015e404c349 * convention old-commit-hash: 1664113a232c4b1a3aa67073e9e8cebef414518f * systemd option old-commit-hash: 95183ff77842fcb9592715db07396be28d778197 * manager option old-commit-hash: 2071893299cb32c3a7cd8a444d8d386c5fa96511 * just curious if this works, change to ELM327 on exit old-commit-hash: 9674ed525134aa03f995942b18163cb047a59c5b * Revert "just curious if this works, change to ELM327 on exit" This reverts commit d4ae294d419dc3d787d11dee4474799f3fb2acef. old-commit-hash: 6d24edd1635ddd0b8ed68a4a4fc8aaaa88984e45 * check onroad same update * useless * comment * fix * debug * Revert "debug" This reverts commit 2bb138610ea7b26d8610d36ef3f0bbb2d6ada388. * Update common/util.h * double wait does not work, blocking in signal handler not good, exit on do_exit, change to SIGINT, use existing stop to support ctrl+c nope * organize? * no sys * None --------- Co-authored-by: Shane Smiskol <shane@smiskol.com>
3 months ago
def main() -> None:
# signal pandad to close the relay and exit
def signal_handler(signum, frame):
cloudlog.info(f"Caught signal {signum}, exiting")
nonlocal do_exit
do_exit = True
if process is not None:
process.send_signal(signal.SIGINT)
process = None
do_exit = False
signal.signal(signal.SIGINT, signal_handler)
count = 0
first_run = True
params = Params()
no_internal_panda_count = 0
pandad: reset safety mode on exit (#32103) * boardd: reset safety mode on exit old-commit-hash: dd18ccbf0a9ab72ace0a7533632d5939c0719953 * comment old-commit-hash: 01b598e8dde93548f7783be19b1cb37d22fadc23 * log it old-commit-hash: 181c4d412e9e3a9c576934e16fc26a9b6e07a117 * logmessaged might not be alive old-commit-hash: 7483ba0eac42875a822df97596d23ff277bf3865 * reproduction, manager gets SIGTERM from python_process old-commit-hash: b90402bd776c3933bfe3dd60998f9913b4bd0068 * even smaller repro old-commit-hash: 03dd430b7131da2b48243714df0513c6a1e594f0 * should work old-commit-hash: 388c4273385ee4c67b1a229ccb9abac6dd94dd0f * let's not change that rn old-commit-hash: d057299058503e8fb792b5a765d0da4af6bef943 * something like this old-commit-hash: 123d6ed845d662aec2bd95d1ccf9c2782308d693 * pandad.cc should receive same SIGTERM and exit old-commit-hash: afc5ef6b916c54ac2ec471d144f601ead71250cb * stash old-commit-hash: e02e0dc488de51c5d40d227c4c2202ba40436d8d * remove debugging old-commit-hash: ac170d0ca32a4285be22e28ec7730fcba3d0697d * remove debugging old-commit-hash: 50949600aeed231347cc4c600a8a7d24accde674 * match behavior old-commit-hash: 5f24167c58caf98b641af2f63f839015e404c349 * convention old-commit-hash: 1664113a232c4b1a3aa67073e9e8cebef414518f * systemd option old-commit-hash: 95183ff77842fcb9592715db07396be28d778197 * manager option old-commit-hash: 2071893299cb32c3a7cd8a444d8d386c5fa96511 * just curious if this works, change to ELM327 on exit old-commit-hash: 9674ed525134aa03f995942b18163cb047a59c5b * Revert "just curious if this works, change to ELM327 on exit" This reverts commit d4ae294d419dc3d787d11dee4474799f3fb2acef. old-commit-hash: 6d24edd1635ddd0b8ed68a4a4fc8aaaa88984e45 * check onroad same update * useless * comment * fix * debug * Revert "debug" This reverts commit 2bb138610ea7b26d8610d36ef3f0bbb2d6ada388. * Update common/util.h * double wait does not work, blocking in signal handler not good, exit on do_exit, change to SIGINT, use existing stop to support ctrl+c nope * organize? * no sys * None --------- Co-authored-by: Shane Smiskol <shane@smiskol.com>
3 months ago
while not do_exit:
try:
count += 1
cloudlog.event("pandad.flash_and_connect", count=count)
params.remove("PandaSignatures")
# TODO: remove this in the next AGNOS
# wait until USB is up before counting
if time.monotonic() < 25.:
no_internal_panda_count = 0
# Handle missing internal panda
if no_internal_panda_count > 0:
if no_internal_panda_count == 3:
cloudlog.info("No pandas found, putting internal panda into DFU")
HARDWARE.recover_internal_panda()
else:
cloudlog.info("No pandas found, resetting internal panda")
HARDWARE.reset_internal_panda()
time.sleep(3) # wait to come back up
# Flash all Pandas in DFU mode
dfu_serials = PandaDFU.list()
if len(dfu_serials) > 0:
for serial in dfu_serials:
cloudlog.info(f"Panda in DFU mode found, flashing recovery {serial}")
PandaDFU(serial).recover()
time.sleep(1)
panda_serials = Panda.list()
if len(panda_serials) == 0:
no_internal_panda_count += 1
continue
cloudlog.info(f"{len(panda_serials)} panda(s) found, connecting - {panda_serials}")
# Flash pandas
pandas: list[Panda] = []
for serial in panda_serials:
pandas.append(flash_panda(serial))
# Ensure internal panda is present if expected
internal_pandas = [panda for panda in pandas if panda.is_internal()]
if HARDWARE.has_internal_panda() and len(internal_pandas) == 0:
cloudlog.error("Internal panda is missing, trying again")
no_internal_panda_count += 1
continue
no_internal_panda_count = 0
# sort pandas to have deterministic order
# * the internal one is always first
# * then sort by hardware type
# * as a last resort, sort by serial number
pandas.sort(key=lambda x: (not x.is_internal(), x.get_type(), x.get_usb_serial()))
panda_serials = [p.get_usb_serial() for p in pandas]
# log panda fw versions
params.put("PandaSignatures", b','.join(p.get_signature() for p in pandas))
for panda in pandas:
# check health for lost heartbeat
health = panda.health()
if health["heartbeat_lost"]:
params.put_bool("PandaHeartbeatLost", True)
cloudlog.event("heartbeat lost", deviceState=health, serial=panda.get_usb_serial())
if health["som_reset_triggered"]:
params.put_bool("PandaSomResetTriggered", True)
cloudlog.event("panda.som_reset_triggered", health=health, serial=panda.get_usb_serial())
if first_run:
# reset panda to ensure we're in a good state
cloudlog.info(f"Resetting panda {panda.get_usb_serial()}")
panda.reset(reconnect=True)
for p in pandas:
p.close()
# TODO: wrap all panda exceptions in a base panda exception
except (usb1.USBErrorNoDevice, usb1.USBErrorPipe):
# a panda was disconnected while setting everything up. let's try again
cloudlog.exception("Panda USB exception while setting up")
continue
except PandaProtocolMismatch:
cloudlog.exception("pandad.protocol_mismatch")
continue
except Exception:
cloudlog.exception("pandad.uncaught_exception")
continue
first_run = False
# run pandad with all connected serials as arguments
os.environ['MANAGER_DAEMON'] = 'pandad'
pandad: reset safety mode on exit (#32103) * boardd: reset safety mode on exit old-commit-hash: dd18ccbf0a9ab72ace0a7533632d5939c0719953 * comment old-commit-hash: 01b598e8dde93548f7783be19b1cb37d22fadc23 * log it old-commit-hash: 181c4d412e9e3a9c576934e16fc26a9b6e07a117 * logmessaged might not be alive old-commit-hash: 7483ba0eac42875a822df97596d23ff277bf3865 * reproduction, manager gets SIGTERM from python_process old-commit-hash: b90402bd776c3933bfe3dd60998f9913b4bd0068 * even smaller repro old-commit-hash: 03dd430b7131da2b48243714df0513c6a1e594f0 * should work old-commit-hash: 388c4273385ee4c67b1a229ccb9abac6dd94dd0f * let's not change that rn old-commit-hash: d057299058503e8fb792b5a765d0da4af6bef943 * something like this old-commit-hash: 123d6ed845d662aec2bd95d1ccf9c2782308d693 * pandad.cc should receive same SIGTERM and exit old-commit-hash: afc5ef6b916c54ac2ec471d144f601ead71250cb * stash old-commit-hash: e02e0dc488de51c5d40d227c4c2202ba40436d8d * remove debugging old-commit-hash: ac170d0ca32a4285be22e28ec7730fcba3d0697d * remove debugging old-commit-hash: 50949600aeed231347cc4c600a8a7d24accde674 * match behavior old-commit-hash: 5f24167c58caf98b641af2f63f839015e404c349 * convention old-commit-hash: 1664113a232c4b1a3aa67073e9e8cebef414518f * systemd option old-commit-hash: 95183ff77842fcb9592715db07396be28d778197 * manager option old-commit-hash: 2071893299cb32c3a7cd8a444d8d386c5fa96511 * just curious if this works, change to ELM327 on exit old-commit-hash: 9674ed525134aa03f995942b18163cb047a59c5b * Revert "just curious if this works, change to ELM327 on exit" This reverts commit d4ae294d419dc3d787d11dee4474799f3fb2acef. old-commit-hash: 6d24edd1635ddd0b8ed68a4a4fc8aaaa88984e45 * check onroad same update * useless * comment * fix * debug * Revert "debug" This reverts commit 2bb138610ea7b26d8610d36ef3f0bbb2d6ada388. * Update common/util.h * double wait does not work, blocking in signal handler not good, exit on do_exit, change to SIGINT, use existing stop to support ctrl+c nope * organize? * no sys * None --------- Co-authored-by: Shane Smiskol <shane@smiskol.com>
3 months ago
process = subprocess.Popen(["./pandad", *panda_serials], cwd=os.path.join(BASEDIR, "selfdrive/pandad"))
process.wait()
if __name__ == "__main__":
main()