Example #1
0
def update_panda():
    with open(os.path.join(BASEDIR, "VERSION")) as f:
        repo_version = f.read()
    repo_version += "-EON" if os.path.isfile('/EON') else "-DEV"

    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()

        print "waiting for board..."
        time.sleep(1)

    current_version = "bootstub" if panda.bootstub else str(
        panda.get_version())
    cloudlog.info("Panda connected, version: %s, expected %s" %
                  (current_version, repo_version))

    if panda.bootstub or not current_version.startswith(repo_version):
        cloudlog.info("Panda firmware out of date, update required")

        signed_fn = os.path.join(BASEDIR, "board", "obj", "panda.bin.signed")
        if os.path.exists(signed_fn):
            cloudlog.info("Flashing signed firmware")
            panda.flash(fn=signed_fn)
        else:
            cloudlog.info("Building and flashing unsigned firmware")
            panda.flash()

        cloudlog.info("Done flashing")

    if panda.bootstub:
        cloudlog.info(
            "Flashed firmware not booting, flashing development bootloader")
        panda.recover()
        cloudlog.info("Done flashing bootloader")

    if panda.bootstub:
        cloudlog.info("Panda still not booting, exiting")
        raise AssertionError

    version = str(panda.get_version())
    if not version.startswith(repo_version):
        cloudlog.info("Version mismatch after flashing, exiting")
        raise AssertionError
Example #2
0
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:
        cloudlog.info(
            "Flashed firmware not booting, flashing development bootloader")
        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
Example #3
0
def update_panda():
  repo_version = get_expected_version()

  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()

    print("waiting for board...")
    time.sleep(1)

  try:
    serial = panda.get_serial()[0].decode("utf-8")
  except Exception:
    serial = None
  current_version = "bootstub" if panda.bootstub else panda.get_version()
  cloudlog.warning("Panda %s connected, version: %s, expected %s" % (serial, current_version, repo_version))

  if panda.bootstub or not current_version.startswith(repo_version):
    cloudlog.info("Panda firmware out of date, update required")

    signed_fn = os.path.join(BASEDIR, "board", "obj", "panda.bin.signed")
    if os.path.exists(signed_fn):
      cloudlog.info("Flashing signed firmware")
      panda.flash(fn=signed_fn)
    else:
      cloudlog.info("Building and flashing unsigned firmware")
      panda.flash()

    cloudlog.info("Done flashing")

  if panda.bootstub:
    cloudlog.info("Flashed firmware not booting, flashing development bootloader")
    panda.recover()
    cloudlog.info("Done flashing bootloader")

  if panda.bootstub:
    cloudlog.info("Panda still not booting, exiting")
    raise AssertionError

  version = panda.get_version()
  if not version.startswith(repo_version):
    cloudlog.info("Version mismatch after flashing, exiting")
    raise AssertionError
Example #4
0
def main() -> NoReturn:
  first_run = True
  params = Params()

  while True:
    try:
      params.delete("PandaSignatures")

      # Flash all Pandas in DFU mode
      for p in PandaDFU.list():
        cloudlog.info(f"Panda in DFU mode found, flashing recovery {p}")
        PandaDFU(p).recover()
      time.sleep(1)

      panda_serials = Panda.list()
      if len(panda_serials) == 0:
        continue

      cloudlog.info(f"{len(panda_serials)} panda(s) found, connecting - {panda_serials}")

      # Flash pandas
      pandas = []
      for serial in panda_serials:
        pandas.append(flash_panda(serial))

      # check health for lost heartbeat
      for panda in pandas:
        health = panda.health()
        if health["heartbeat_lost"]:
          params.put_bool("PandaHeartbeatLost", True)
          cloudlog.event("heartbeat lost", deviceState=health, serial=panda.get_usb_serial())

        if first_run:
          cloudlog.info(f"Resetting panda {panda.get_usb_serial()}")
          panda.reset()

      # sort pandas to have deterministic order
      pandas.sort(key=cmp_to_key(panda_sort_cmp))
      panda_serials = list(map(lambda p: p.get_usb_serial(), pandas))

      # log panda fw versions
      params.put("PandaSignatures", b','.join(p.get_signature() for p in pandas))

      # close all pandas
      for p in pandas:
        p.close()
    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

    first_run = False

    # run boardd with all connected serials as arguments
    os.environ['MANAGER_DAEMON'] = 'boardd'
    os.chdir(os.path.join(BASEDIR, "selfdrive/boardd"))
    subprocess.run(["./boardd", *panda_serials], check=True)
Example #5
0
def ensure_st_up_to_date():
    from panda import Panda, PandaDFU, BASEDIR

    with open(os.path.join(BASEDIR, "VERSION")) as f:
        repo_version = f.read()

    repo_version += "-EON" if os.path.isfile('/EON') else "-DEV"

    panda = None
    panda_dfu = None
    should_flash_recover = False

    while 1:
        # break on normal mode Panda
        panda_list = Panda.list()
        if len(panda_list) > 0:
            panda = Panda(panda_list[0])
            break

        # flash on DFU mode Panda
        panda_dfu = PandaDFU.list()
        if len(panda_dfu) > 0:
            panda_dfu = PandaDFU(panda_dfu[0])
            panda_dfu.recover()

        print("waiting for board...")
        time.sleep(1)

    if panda.bootstub or not panda.get_version().startswith(repo_version):
        panda.flash()

    if panda.bootstub:
        panda.recover()

    assert (not panda.bootstub)
    version = str(panda.get_version())
    print("%s should be %s" % (version, repo_version))
    assert (version.startswith(repo_version))
Example #6
0
FW_FX_FN = "panda.bin"
is_mcu_h7 = False

if __name__ == "__main__":
    cur_dir = os.path.dirname(os.path.realpath(__file__))

    # Open manifest
    manifest_fn = os.path.join(cur_dir, 'latest.json')
    with open(manifest_fn) as manifest:
        latest = json.load(manifest)

    # Open zip file
    zip_fn = os.path.join(cur_dir, latest['version'] + '.zip')
    with zipfile.ZipFile(zip_fn) as zip_file:
        # Wait for panda to connect
        while not PandaDFU.list():
            print("Waiting for panda in DFU mode")

            if Panda.list():
                print("Panda found. Putting in DFU Mode")
                panda = Panda()
                panda.reset(enter_bootstub=True)
                panda.reset(enter_bootloader=True)

            time.sleep(0.5)

        # Flash bootstub
        panda_dfu = PandaDFU(None)
        is_mcu_h7 = panda_dfu._mcu_type == MCU_TYPE_H7
        fn = BOOTSTUB_H7_FN if is_mcu_h7 else BOOTSTUB_FX_FN
        print(f"Detected MCU type {panda_dfu._mcu_type}, flashing {fn}")
def flash_release(path=None, st_serial=None):
    from panda import Panda, PandaDFU
    from zipfile import ZipFile

    def status(x):
        print("\033[1;32;40m" + x + "\033[00m")

    if st_serial is not None:
        # look for Panda
        panda_list = Panda.list()
        if len(panda_list) == 0:
            raise Exception(
                "panda not found, make sure it's connected and your user can access it"
            )
        elif len(panda_list) > 1:
            raise Exception("Please only connect one panda")
        st_serial = panda_list[0]
        print("Using panda with serial %s" % st_serial)

    if path is None:
        print(
            "Fetching latest firmware from github.com/commaai/panda-artifacts")
        r = requests.get(
            "https://raw.githubusercontent.com/commaai/panda-artifacts/master/latest.json"
        )
        url = json.loads(r.text)['url']
        r = requests.get(url)
        print("Fetching firmware from %s" % url)
        path = io.BytesIO(r.content)

    zf = ZipFile(path)
    zf.printdir()

    version = zf.read("version").decode()
    status("0. Preparing to flash " + str(version))

    code_bootstub = zf.read("bootstub.panda.bin")
    code_panda = zf.read("panda.bin")

    # enter DFU mode
    status("1. Entering DFU mode")
    panda = Panda(st_serial)
    panda.reset(enter_bootstub=True)
    panda.reset(enter_bootloader=True)
    time.sleep(1)

    # program bootstub
    status("2. Programming bootstub")
    dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(st_serial))
    dfu.program_bootstub(code_bootstub)
    time.sleep(1)

    # flash main code
    status("3. Flashing main code")
    panda = Panda(st_serial)
    panda.flash(code=code_panda)
    panda.close()

    # check for connection
    status("4. Verifying version")
    panda = Panda(st_serial)
    my_version = panda.get_version()
    print("dongle id: %s" % panda.get_serial()[0])
    print(my_version, "should be", version)
    assert (str(version) == str(my_version))

    # done!
    status("6. Success!")
Example #8
0
if __name__ == "__main__":
  if jungle:
    serials = PandaJungle.list()
  else:
    serials = Panda.list()
  num_senders = len(serials)

  if num_senders == 0:
    print("No senders found. Exiting")
    sys.exit(1)
  else:
    print("%d senders found. Starting broadcast" % num_senders)

  if "FLASH" in os.environ:
    for s in PandaDFU.list():
      PandaDFU(s).recover()

    time.sleep(1)
    for s in serials:
      Panda(s).recover()
      Panda(s).flash()

  pool = Pool(num_senders, initializer=initializer)
  pool.map_async(send_thread, serials)

  while True:
    try:
      time.sleep(10)
    except KeyboardInterrupt:
      pool.terminate()
Example #9
0
from panda import Panda, PandaDFU


if __name__ == "__main__":
  cur_dir = os.path.dirname(os.path.realpath(__file__))

  # Open manifest
  manifest_fn = os.path.join(cur_dir, 'latest.json')
  with open(manifest_fn) as manifest:
    latest = json.load(manifest)

  # Open zip file
  zip_fn = os.path.join(cur_dir, latest['version'] + '.zip')
  with zipfile.ZipFile(zip_fn) as zip_file:
    # Wait for panda to connect
    while not PandaDFU.list():
      print("Waiting for panda in DFU mode")

      if Panda.list():
        print("Panda found. Putting in DFU Mode")
        panda = Panda()
        panda.reset(enter_bootstub=True)
        panda.reset(enter_bootloader=True)

      time.sleep(0.5)

    # Flash bootstub
    bootstub_code = zip_file.open('bootstub.panda.bin').read()
    PandaDFU(None).program_bootstub(bootstub_code)

    # Wait for panda to come back online
Example #10
0
def flash_release(path=None, st_serial=None):
    from panda import Panda, PandaDFU, ESPROM, CesantaFlasher
    from zipfile import ZipFile

    def status(x):
        print("\033[1;32;40m" + x + "\033[00m")

    if st_serial == None:
        # look for Panda
        panda_list = Panda.list()
        if len(panda_list) == 0:
            raise Exception(
                "panda not found, make sure it's connected and your user can access it"
            )
        elif len(panda_list) > 1:
            raise Exception("Please only connect one panda")
        st_serial = panda_list[0]
        print("Using panda with serial %s" % st_serial)

    if path == None:
        print(
            "Fetching latest firmware from github.com/commaai/panda-artifacts")
        r = requests.get(
            "https://raw.githubusercontent.com/commaai/panda-artifacts/master/latest.json"
        )
        url = json.loads(r.text)['url']
        r = requests.get(url)
        print("Fetching firmware from %s" % url)
        path = io.StringIO(r.content)

    zf = ZipFile(path)
    zf.printdir()

    version = zf.read("version")
    status("0. Preparing to flash " + version)

    code_bootstub = zf.read("bootstub.panda.bin")
    code_panda = zf.read("panda.bin")

    code_boot_15 = zf.read("boot_v1.5.bin")
    code_boot_15 = code_boot_15[0:2] + "\x00\x30" + code_boot_15[4:]

    code_user1 = zf.read("user1.bin")
    code_user2 = zf.read("user2.bin")

    # enter DFU mode
    status("1. Entering DFU mode")
    panda = Panda(st_serial)
    panda.enter_bootloader()
    time.sleep(1)

    # program bootstub
    status("2. Programming bootstub")
    dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(st_serial))
    dfu.program_bootstub(code_bootstub)
    time.sleep(1)

    # flash main code
    status("3. Flashing main code")
    panda = Panda(st_serial)
    panda.flash(code=code_panda)
    panda.close()

    # flashing ESP
    if panda.is_white():
        status("4. Flashing ESP (slow!)")
        align = lambda x, sz=0x1000: x + "\xFF" * ((sz - len(x)) % sz)
        esp = ESPROM(st_serial)
        esp.connect()
        flasher = CesantaFlasher(esp, 230400)
        flasher.flash_write(0x0, align(code_boot_15), True)
        flasher.flash_write(0x1000, align(code_user1), True)
        flasher.flash_write(0x81000, align(code_user2), True)
        flasher.flash_write(0x3FE000, "\xFF" * 0x1000)
        flasher.boot_fw()
        del flasher
        del esp
        time.sleep(1)
    else:
        status("4. No ESP in non-white panda")

    # check for connection
    status("5. Verifying version")
    panda = Panda(st_serial)
    my_version = panda.get_version()
    print("dongle id: %s" % panda.get_serial()[0])
    print(my_version, "should be", version)
    assert (str(version) == str(my_version))

    # done!
    status("6. Success!")
Example #11
0
def flash_release(path=None, st_serial=None):
  from panda import Panda, PandaDFU, ESPROM, CesantaFlasher
  from zipfile import ZipFile

  def status(x):
    print("\033[1;32;40m"+x+"\033[00m")

  if st_serial == None:
    # look for Panda
    panda_list = Panda.list()
    if len(panda_list) == 0:
      raise Exception("panda not found, make sure it's connected and your user can access it")
    elif len(panda_list) > 1:
      raise Exception("Please only connect one panda")
    st_serial = panda_list[0]
    print("Using panda with serial %s" % st_serial)

  if path == None:
    print("Fetching latest firmware from github.com/commaai/panda-artifacts")
    r = requests.get("https://raw.githubusercontent.com/commaai/panda-artifacts/master/latest.json")
    url = json.loads(r.text)['url']
    r = requests.get(url)
    print("Fetching firmware from %s" % url)
    path = StringIO.StringIO(r.content)

  zf = ZipFile(path)
  zf.printdir()

  version = zf.read("version")
  status("0. Preparing to flash "+version)

  code_bootstub = zf.read("bootstub.panda.bin")
  code_panda = zf.read("panda.bin")

  code_boot_15 = zf.read("boot_v1.5.bin")
  code_boot_15 = code_boot_15[0:2] + "\x00\x30" + code_boot_15[4:]

  code_user1 = zf.read("user1.bin")
  code_user2 = zf.read("user2.bin")

  # enter DFU mode
  status("1. Entering DFU mode")
  panda = Panda(st_serial)
  panda.enter_bootloader()
  time.sleep(1)

  # program bootstub
  status("2. Programming bootstub")
  dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(st_serial))
  dfu.program_bootstub(code_bootstub)
  time.sleep(1)

  # flash main code
  status("3. Flashing main code")
  panda = Panda(st_serial)
  panda.flash(code=code_panda)
  panda.close()

  # flashing ESP
  status("4. Flashing ESP (slow!)")
  align = lambda x, sz=0x1000: x+"\xFF"*((sz-len(x)) % sz)
  esp = ESPROM(st_serial)
  esp.connect()
  flasher = CesantaFlasher(esp, 230400)
  flasher.flash_write(0x0, align(code_boot_15), True)
  flasher.flash_write(0x1000, align(code_user1), True)
  flasher.flash_write(0x81000, align(code_user2), True)
  flasher.flash_write(0x3FE000, "\xFF"*0x1000)
  flasher.boot_fw()
  del flasher
  del esp
  time.sleep(1)

  # check for connection
  status("5. Verifying version")
  panda = Panda(st_serial)
  my_version = panda.get_version()
  print("dongle id: %s" % panda.get_serial()[0])
  print(my_version, "should be", version)
  assert(str(version) == str(my_version))

  # done!
  status("6. Success!")