def main(): args = get_argparser().parse_args() init_logger(args) if args.verbose == args.quiet == 0: logging.getLogger().setLevel(logging.INFO) def build_dir(*path, target=args.target): return os.path.join("/tmp/", "artiq_" + target, *path) if args.target == "kc705": board_type, firmware = "kc705", "runtime" variant = "nist_clock" if args.variant is None else args.variant elif args.target == "sayma": board_type, firmware = "sayma", "runtime" variant = "standalone" if args.variant is None else args.variant elif args.target == "kasli": board_type, firmware = "kasli", "runtime" variant = "tester" if args.variant is None else args.variant else: raise NotImplementedError("unknown target {}".format(args.target)) board = args.board.format(board_type=board_type) board_file = args.board_file.format(board=board) device = args.device.format(board=board, host=args.host) serial = args.serial.format(board=board) client = SSHClient(args.host, args.jump) flock_acquired = False flock_file = None # GC root def lock(): nonlocal flock_acquired nonlocal flock_file if not flock_acquired: fuser_args = ["fuser", "-u", board_file] fuser = client.spawn_command(fuser_args) fuser_file = fuser.makefile('r') fuser_match = re.search(r"\((.+?)\)", fuser_file.readline()) if fuser_match and fuser_match.group(1) == os.getenv("USER"): logger.info("Lock already acquired by {}".format(os.getenv("USER"))) flock_acquired = True return logger.info("Acquiring device lock") flock_args = ["flock"] if not args.wait: flock_args.append("--nonblock") flock_args += ["--verbose", board_file] flock_args += ["sleep", "86400"] flock = client.spawn_command(flock_args, get_pty=True) flock_file = flock.makefile('r') while not flock_acquired: line = flock_file.readline() if not line: break logger.debug(line.rstrip()) if line.startswith("flock: executing"): flock_acquired = True elif line.startswith("flock: failed"): logger.error("Failed to get lock") sys.exit(1) def command(*args, on_failure="Command failed"): logger.debug("Running {}".format(" ".join([shlex.quote(arg) for arg in args]))) try: subprocess.check_call(args) except subprocess.CalledProcessError: logger.error(on_failure) sys.exit(1) def build(target, *extra_args, output_dir=build_dir(), variant=variant): build_args = ["python3", "-m", "artiq.gateware.targets." + target, *extra_args] if not args.gateware: build_args.append("--no-compile-gateware") if variant: build_args += ["--variant", variant] build_args += ["--output-dir", output_dir] command(*build_args, on_failure="Build failed") def flash(*steps): lock() flash_args = ["artiq_flash"] for _ in range(args.verbose): flash_args.append("-v") flash_args += ["-H", args.host] if args.jump: flash_args += ["-J", args.jump] flash_args += ["-t", board_type] flash_args += ["-V", variant] flash_args += ["-I", "source {}".format(board_file)] flash_args += ["--srcbuild", build_dir()] flash_args += steps command(*flash_args, on_failure="Flashing failed") for action in args.actions: if action == "build": logger.info("Building target") if args.target == "sayma": build("sayma_rtm", output_dir=build_dir("rtm_gateware"), variant=None) build("sayma_amc", "--rtm-csr-csv", build_dir("rtm_gateware", "rtm_csr.csv")) else: build(args.target) elif action == "clean": logger.info("Cleaning build directory") shutil.rmtree(build_dir(), ignore_errors=True) elif action == "reset": logger.info("Resetting device") flash("start") elif action == "flash": gateware = ["gateware"] if args.gateware else [] logger.info("Flashing and booting") flash(*gateware, "bootloader", "firmware", "start") elif action == "flash+log": gateware = ["gateware"] if args.gateware else [] logger.info("Flashing") flash(*gateware, "bootloader", "firmware") flterm = client.spawn_command(["flterm", serial, "--output-only"]) logger.info("Booting") flash("start") client.drain(flterm) elif action == "load": logger.info("Loading gateware") flash("load") elif action == "connect": lock() transport = client.get_transport() transport.set_keepalive(30) def forwarder(local_stream, remote_stream): try: while True: r, _, _ = select.select([local_stream, remote_stream], [], []) if local_stream in r: data = local_stream.recv(65535) if data == b"": break remote_stream.sendall(data) if remote_stream in r: data = remote_stream.recv(65535) if data == b"": break local_stream.sendall(data) except Exception as err: logger.error("Cannot forward on port %s: %s", port, repr(err)) local_stream.close() remote_stream.close() def listener(port): listener = socket.socket() listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listener.bind(('localhost', port)) listener.listen(8) while True: local_stream, peer_addr = listener.accept() logger.info("Accepting %s:%s and opening SSH channel to %s:%s", *peer_addr, device, port) try: remote_stream = \ transport.open_channel('direct-tcpip', (device, port), peer_addr) except Exception: logger.exception("Cannot open channel on port %s", port) continue thread = threading.Thread(target=forwarder, args=(local_stream, remote_stream), name="forward-{}".format(port), daemon=True) thread.start() ports = [1380, 1381, 1382, 1383] for port in ports: thread = threading.Thread(target=listener, args=(port,), name="listen-{}".format(port), daemon=True) thread.start() logger.info("Forwarding ports {} to core device and logs from core device" .format(", ".join(map(str, ports)))) client.run_command(["flterm", serial, "--output-only"]) elif action == "hotswap": lock() logger.info("Hotswapping firmware") firmware = build_dir(variant, "software", firmware, firmware + ".bin") mgmt = CommMgmt(device) mgmt.open(ssh_transport=client.get_transport()) with open(firmware, "rb") as f: mgmt.hotswap(f.read()) else: logger.error("Unknown action {}".format(action)) sys.exit(1)
def main(): args = get_argparser().parse_args() init_logger(args) config = { "kasli": { "programmer": partial(ProgrammerXC7, board="kasli", proxy="bscan_spi_xc7a100t.bit"), "def_variant": "opticlock", "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0x400000), "storage": ("spi0", 0x440000), "firmware": ("spi0", 0x450000), }, "sayma": { "programmer": ProgrammerSayma, "def_variant": "standalone", "gateware": ("spi0", 0x000000), "bootloader": ("spi1", 0x000000), "storage": ("spi1", 0x040000), "firmware": ("spi1", 0x050000), "rtm_gateware": ("spi1", 0x200000), }, "kc705": { "programmer": partial(ProgrammerXC7, board="kc705", proxy="bscan_spi_xc7k325t.bit"), "def_variant": "nist_clock", "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0xaf0000), "storage": ("spi0", 0xb30000), "firmware": ("spi0", 0xb40000), }, }[args.target] variant = args.variant if variant is None: variant = config["def_variant"] bin_dir = args.dir if bin_dir is None: bin_name = args.target if variant: bin_name += "-" + variant bin_dir = os.path.join(artiq_dir, "binaries", bin_name) if args.host is None: client = LocalClient() else: client = SSHClient(args.host, args.jump) programmer = config["programmer"](client, preinit_script=args.preinit_command) def artifact_path(*path_filename): if args.srcbuild is None: *path, filename = path_filename return os.path.join(bin_dir, filename) else: return os.path.join(args.srcbuild, *path_filename) def convert_gateware(bit_filename, header=False): bin_handle, bin_filename = tempfile.mkstemp( prefix="artiq_", suffix="_" + os.path.basename(bit_filename)) with open(bit_filename, "rb") as bit_file, \ open(bin_handle, "wb") as bin_file: if header: bin_file.write(b"\x00" * 8) bit2bin(bit_file, bin_file) if header: magic = 0x5352544d # "SRTM", see sayma_rtm target length = bin_file.tell() - 8 bin_file.seek(0) bin_file.write(magic.to_bytes(4, byteorder="big")) bin_file.write(length.to_bytes(4, byteorder="big")) atexit.register(lambda: os.unlink(bin_filename)) return bin_filename for action in args.action: if action == "gateware": gateware_bin = convert_gateware( artifact_path(variant, "gateware", "top.bit")) programmer.write_binary(*config["gateware"], gateware_bin) if args.target == "sayma" and args.variant != "master": rtm_gateware_bin = convert_gateware(artifact_path( "rtm_gateware", "rtm.bit"), header=True) programmer.write_binary(*config["rtm_gateware"], rtm_gateware_bin) elif action == "bootloader": bootloader_bin = artifact_path(variant, "software", "bootloader", "bootloader.bin") programmer.write_binary(*config["bootloader"], bootloader_bin) elif action == "storage": storage_img = args.storage programmer.write_binary(*config["storage"], storage_img) elif action == "firmware": if variant == "satellite": firmware = "satman" else: firmware = "runtime" firmware_fbi = artifact_path(variant, "software", firmware, firmware + ".fbi") programmer.write_binary(*config["firmware"], firmware_fbi) elif action == "load": if args.target == "sayma": rtm_gateware_bit = artifact_path("rtm_gateware", "rtm.bit") programmer.load(rtm_gateware_bit, 0) gateware_bit = artifact_path(variant, "gateware", "top.bit") programmer.load(gateware_bit, 1) else: gateware_bit = artifact_path(variant, "gateware", "top.bit") programmer.load(gateware_bit, 0) elif action == "start": programmer.start() else: raise ValueError("invalid action", action) if args.dry_run: print("\n".join(programmer.script())) else: programmer.run()
def main(): args = get_argparser().parse_args() init_logger(args) if args.verbose == args.quiet == 0: logging.getLogger().setLevel(logging.INFO) def build_dir(*path, target=args.target): return os.path.join("/tmp/", "artiq_" + target, *path) if args.target == "kc705": board_type, firmware = "kc705", "runtime" variant = "nist_clock" if args.variant is None else args.variant elif args.target == "sayma": board_type, firmware = "sayma", "runtime" variant = "standalone" if args.variant is None else args.variant elif args.target == "kasli": board_type, firmware = "kasli", "runtime" variant = "tester" if args.variant is None else args.variant else: raise NotImplementedError("unknown target {}".format(args.target)) board = args.board.format(board_type=board_type) board_file = args.board_file.format(board=board) device = args.device.format(board=board, host=args.host) serial = args.serial.format(board=board) client = SSHClient(args.host, args.jump) flock_acquired = False flock_file = None # GC root def lock(): nonlocal flock_acquired nonlocal flock_file if not flock_acquired: fuser_args = ["fuser", "-u", board_file] fuser = client.spawn_command(fuser_args) fuser_file = fuser.makefile('r') fuser_match = re.search(r"\((.+?)\)", fuser_file.readline()) if fuser_match and fuser_match.group(1) == os.getenv("USER"): logger.info("Lock already acquired by {}".format( os.getenv("USER"))) flock_acquired = True return logger.info("Acquiring device lock") flock_args = ["flock"] if not args.wait: flock_args.append("--nonblock") flock_args += ["--verbose", board_file] flock_args += ["sleep", "86400"] flock = client.spawn_command(flock_args, get_pty=True) flock_file = flock.makefile('r') while not flock_acquired: line = flock_file.readline() if not line: break logger.debug(line.rstrip()) if line.startswith("flock: executing"): flock_acquired = True elif line.startswith("flock: failed"): logger.error("Failed to get lock") sys.exit(1) def command(*args, on_failure="Command failed"): logger.debug("Running {}".format(" ".join( [shlex.quote(arg) for arg in args]))) try: subprocess.check_call(args) except subprocess.CalledProcessError: logger.error(on_failure) sys.exit(1) def build(target, *extra_args, output_dir=build_dir(), variant=variant): build_args = [ "python3", "-m", "artiq.gateware.targets." + target, *extra_args ] if not args.gateware: build_args.append("--no-compile-gateware") if variant: build_args += ["--variant", variant] build_args += ["--output-dir", output_dir] command(*build_args, on_failure="Build failed") def flash(*steps): lock() flash_args = ["artiq_flash"] for _ in range(args.verbose): flash_args.append("-v") flash_args += ["-H", args.host] if args.jump: flash_args += ["-J", args.jump] flash_args += ["-t", board_type] flash_args += ["-V", variant] flash_args += ["-I", "source {}".format(board_file)] flash_args += ["--srcbuild", build_dir()] flash_args += steps command(*flash_args, on_failure="Flashing failed") for action in args.actions: if action == "build": logger.info("Building target") if args.target == "sayma": build("sayma_rtm", output_dir=build_dir("rtm_gateware"), variant=None) build("sayma_amc", "--rtm-csr-csv", build_dir("rtm_gateware", "rtm_csr.csv")) else: build(args.target) elif action == "clean": logger.info("Cleaning build directory") shutil.rmtree(build_dir(), ignore_errors=True) elif action == "reset": logger.info("Resetting device") flash("start") elif action == "flash": gateware = ["gateware"] if args.gateware else [] logger.info("Flashing and booting") flash(*gateware, "bootloader", "firmware", "start") elif action == "flash+log": gateware = ["gateware"] if args.gateware else [] logger.info("Flashing") flash(*gateware, "bootloader", "firmware") flterm = client.spawn_command(["flterm", serial, "--output-only"]) logger.info("Booting") flash("start") client.drain(flterm) elif action == "load": logger.info("Loading gateware") flash("load") elif action == "connect": lock() transport = client.get_transport() transport.set_keepalive(30) def forwarder(local_stream, remote_stream): try: while True: r, _, _ = select.select([local_stream, remote_stream], [], []) if local_stream in r: data = local_stream.recv(65535) if data == b"": break remote_stream.sendall(data) if remote_stream in r: data = remote_stream.recv(65535) if data == b"": break local_stream.sendall(data) except Exception as err: logger.error("Cannot forward on port %s: %s", port, repr(err)) local_stream.close() remote_stream.close() def listener(port): listener = socket.socket() listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listener.bind(('localhost', port)) listener.listen(8) while True: local_stream, peer_addr = listener.accept() logger.info( "Accepting %s:%s and opening SSH channel to %s:%s", *peer_addr, device, port) try: remote_stream = \ transport.open_channel('direct-tcpip', (device, port), peer_addr) except Exception: logger.exception("Cannot open channel on port %s", port) continue thread = threading.Thread(target=forwarder, args=(local_stream, remote_stream), name="forward-{}".format(port), daemon=True) thread.start() ports = [1380, 1381, 1382, 1383] for port in ports: thread = threading.Thread(target=listener, args=(port, ), name="listen-{}".format(port), daemon=True) thread.start() logger.info( "Forwarding ports {} to core device and logs from core device". format(", ".join(map(str, ports)))) client.run_command(["flterm", serial, "--output-only"]) elif action == "hotswap": lock() logger.info("Hotswapping firmware") firmware = build_dir(variant, "software", firmware, firmware + ".bin") mgmt = CommMgmt(device) mgmt.open(ssh_transport=client.get_transport()) with open(firmware, "rb") as f: mgmt.hotswap(f.read()) else: logger.error("Unknown action {}".format(action)) sys.exit(1)
def main(): args = get_argparser().parse_args() common_args.init_logger_from_args(args) config = { "kasli": { "programmer": partial(ProgrammerXC7, board="kasli", proxy="bscan_spi_xc7a100t.bit"), "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0x400000), "storage": ("spi0", 0x440000), "firmware": ("spi0", 0x450000), }, "sayma": { "programmer": ProgrammerAMCRTM, "gateware": ("spi0", 0x000000), "bootloader": ("spi1", 0x000000), "storage": ("spi1", 0x040000), "firmware": ("spi1", 0x050000), "rtm_gateware": ("spi1", 0x200000), }, "kc705": { "programmer": partial(ProgrammerXC7, board="kc705", proxy="bscan_spi_xc7k325t.bit"), "def_variant": "nist_clock", "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0xaf0000), "storage": ("spi0", 0xb30000), "firmware": ("spi0", 0xb40000), }, }[args.target] bin_dir = args.dir if bin_dir is None: bin_dir = os.path.join(artiq_dir, "board-support") needs_artifacts = not args.action or any( action in args.action for action in [ "gateware", "rtm_gateware", "bootloader", "firmware", "load", "rtm_load" ]) variant = args.variant if needs_artifacts and variant is None: variants = [] if args.srcbuild: for entry in os.scandir(bin_dir): if entry.is_dir(): variants.append(entry.name) else: prefix = args.target + "-" for entry in os.scandir(bin_dir): if entry.is_dir() and entry.name.startswith(prefix): variants.append(entry.name[len(prefix):]) if args.target == "sayma": try: variants.remove("rtm") except ValueError: pass if len(variants) == 0: raise FileNotFoundError( "no variants found, did you install a board binary package?") elif len(variants) == 1: variant = variants[0] else: raise ValueError( "more than one variant found for selected board, specify -V. " "Found variants: {}".format(" ".join(sorted(variants)))) if needs_artifacts: if args.srcbuild: variant_dir = variant else: variant_dir = args.target + "-" + variant if args.target == "sayma": if args.srcbuild: rtm_variant_dir = "rtm" else: rtm_variant_dir = "sayma-rtm" if not args.action: if args.target == "sayma" and variant != "simplesatellite" and variant != "master": args.action = "gateware rtm_gateware bootloader firmware start".split( ) else: args.action = "gateware bootloader firmware start".split() if args.host is None: client = LocalClient() else: client = SSHClient(args.host, args.jump) if args.target == "sayma" and args.no_rtm_jtag: programmer_cls = ProgrammerAMC else: programmer_cls = config["programmer"] programmer = programmer_cls(client, preinit_script=args.preinit_command) def artifact_path(this_variant_dir, *path_filename): if args.srcbuild: # source tree - use path elements to locate file return os.path.join(bin_dir, this_variant_dir, *path_filename) else: # flat tree - all files in the same directory, discard path elements *_, filename = path_filename return os.path.join(bin_dir, this_variant_dir, filename) def convert_gateware(bit_filename, header=False): bin_handle, bin_filename = tempfile.mkstemp( prefix="artiq_", suffix="_" + os.path.basename(bit_filename)) with open(bit_filename, "rb") as bit_file, \ open(bin_handle, "wb") as bin_file: if header: bin_file.write(b"\x00" * 8) bit2bin(bit_file, bin_file) if header: magic = 0x5352544d # "SRTM", see sayma_rtm target length = bin_file.tell() - 8 bin_file.seek(0) bin_file.write(magic.to_bytes(4, byteorder="big")) bin_file.write(length.to_bytes(4, byteorder="big")) atexit.register(lambda: os.unlink(bin_filename)) return bin_filename for action in args.action: if action == "gateware": gateware_bin = convert_gateware( artifact_path(variant_dir, "gateware", "top.bit")) programmer.write_binary(*config["gateware"], gateware_bin) elif action == "rtm_gateware": rtm_gateware_bin = convert_gateware(artifact_path( rtm_variant_dir, "gateware", "top.bit"), header=True) programmer.write_binary(*config["rtm_gateware"], rtm_gateware_bin) elif action == "bootloader": bootloader_bin = artifact_path(variant_dir, "software", "bootloader", "bootloader.bin") programmer.write_binary(*config["bootloader"], bootloader_bin) elif action == "storage": storage_img = args.storage programmer.write_binary(*config["storage"], storage_img) elif action == "firmware": if variant.endswith("satellite"): firmware = "satman" else: firmware = "runtime" firmware_fbi = artifact_path(variant_dir, "software", firmware, firmware + ".fbi") programmer.write_binary(*config["firmware"], firmware_fbi) elif action == "load": if args.target == "sayma": gateware_bit = artifact_path(variant_dir, "gateware", "top.bit") programmer.load(gateware_bit, 1) else: gateware_bit = artifact_path(variant_dir, "gateware", "top.bit") programmer.load(gateware_bit, 0) elif action == "rtm_load": rtm_gateware_bit = artifact_path(rtm_variant_dir, "gateware", "top.bit") programmer.load(rtm_gateware_bit, 0) elif action == "start": programmer.start() elif action == "erase": if args.target == "sayma" or args.target == "metlino": programmer.erase_flash("spi0") programmer.erase_flash("spi1") else: programmer.erase_flash("spi0") else: raise ValueError("invalid action", action) if args.dry_run: print("\n".join(programmer.script())) else: programmer.run()
def main(): args = get_argparser().parse_args() common_args.init_logger_from_args(args) config = { "kasli": { "programmer": partial(ProgrammerXC7, board="kasli", proxy="bscan_spi_xc7a100t.bit"), "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0x400000), "storage": ("spi0", 0x440000), "firmware": ("spi0", 0x450000), }, "sayma": { "programmer": ProgrammerAMCRTM, "gateware": ("spi0", 0x000000), "bootloader": ("spi1", 0x000000), "storage": ("spi1", 0x040000), "firmware": ("spi1", 0x050000), "rtm_gateware": ("spi1", 0x200000), }, "metlino": { "programmer": ProgrammerAMC, "gateware": ("spi0", 0x000000), "bootloader": ("spi1", 0x000000), "storage": ("spi1", 0x040000), "firmware": ("spi1", 0x050000), }, "kc705": { "programmer": partial(ProgrammerXC7, board="kc705", proxy="bscan_spi_xc7k325t.bit"), "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0xaf0000), "storage": ("spi0", 0xb30000), "firmware": ("spi0", 0xb40000), }, }[args.target] if not args.action: if args.target == "sayma": args.action = "gateware rtm_gateware bootloader firmware start".split( ) else: args.action = "gateware bootloader firmware start".split() needs_artifacts = any(action in args.action for action in [ "gateware", "rtm_gateware", "bootloader", "firmware", "load", "rtm_load" ]) if needs_artifacts and args.dir is None: raise ValueError( "the directory containing the binaries need to be specified using -d." ) binary_dir = args.dir if binary_dir is not None: rtm_binary_dir = os.path.join(binary_dir, "rtm") else: rtm_binary_dir = None if args.host is None: client = LocalClient() else: client = SSHClient(args.host, args.jump) if args.target == "sayma" and args.no_rtm_jtag: programmer_cls = ProgrammerAMC else: programmer_cls = config["programmer"] programmer = programmer_cls(client, preinit_script=args.preinit_command) def artifact_path(this_binary_dir, *path_filename): if args.srcbuild: # source tree - use path elements to locate file return os.path.join(this_binary_dir, *path_filename) else: # flat tree - all files in the same directory, discard path elements *_, filename = path_filename return os.path.join(this_binary_dir, filename) def convert_gateware(bit_filename, header=False): bin_handle, bin_filename = tempfile.mkstemp( prefix="artiq_", suffix="_" + os.path.basename(bit_filename)) with open(bit_filename, "rb") as bit_file, \ open(bin_handle, "wb") as bin_file: if header: bin_file.write(b"\x00" * 8) bit2bin(bit_file, bin_file) if header: magic = 0x5352544d # "SRTM", see sayma_rtm target length = bin_file.tell() - 8 bin_file.seek(0) bin_file.write(magic.to_bytes(4, byteorder="little")) bin_file.write(length.to_bytes(4, byteorder="little")) atexit.register(lambda: os.unlink(bin_filename)) return bin_filename for action in args.action: if action == "gateware": gateware_bin = convert_gateware( artifact_path(binary_dir, "gateware", "top.bit")) programmer.write_binary(*config["gateware"], gateware_bin) elif action == "rtm_gateware": rtm_gateware_bin = convert_gateware(artifact_path( rtm_binary_dir, "gateware", "top.bit"), header=True) programmer.write_binary(*config["rtm_gateware"], rtm_gateware_bin) elif action == "bootloader": bootloader_bin = artifact_path(binary_dir, "software", "bootloader", "bootloader.bin") programmer.write_binary(*config["bootloader"], bootloader_bin) elif action == "storage": storage_img = args.storage programmer.write_binary(*config["storage"], storage_img) elif action == "firmware": firmware_fbis = [] for firmware in "satman", "runtime": filename = artifact_path(binary_dir, "software", firmware, firmware + ".fbi") if os.path.exists(filename): firmware_fbis.append(filename) if not firmware_fbis: raise FileNotFoundError("no firmware found") if len(firmware_fbis) > 1: raise ValueError( "more than one firmware file, please clean up your build directory. " "Found firmware files: {}".format(" ".join(firmware_fbis))) programmer.write_binary(*config["firmware"], firmware_fbis[0]) elif action == "load": if args.target == "sayma": gateware_bit = artifact_path(binary_dir, "gateware", "top.bit") programmer.load(gateware_bit, 1) else: gateware_bit = artifact_path(binary_dir, "gateware", "top.bit") programmer.load(gateware_bit, 0) elif action == "rtm_load": rtm_gateware_bit = artifact_path(rtm_binary_dir, "gateware", "top.bit") programmer.load(rtm_gateware_bit, 0) elif action == "start": programmer.start() elif action == "erase": if args.target == "sayma" or args.target == "metlino": programmer.erase_flash("spi0") programmer.erase_flash("spi1") else: programmer.erase_flash("spi0") else: raise ValueError("invalid action", action) if args.dry_run: print("\n".join(programmer.script())) else: programmer.run()
def main(): args = get_argparser().parse_args() init_logger(args) config = { "kc705": { "programmer": partial(ProgrammerXC7, board="kc705", proxy="bscan_spi_xc7k325t.bit"), "variants": ["nist_clock", "nist_qc2"], "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0xaf0000), "storage": ("spi0", 0xb30000), "firmware": ("spi0", 0xb40000), }, "kasli": { "programmer": partial(ProgrammerXC7, board="kasli", proxy="bscan_spi_xc7a100t.bit"), "variants": ["opticlock", "master", "satellite"], "gateware": ("spi0", 0x000000), "bootloader": ("spi0", 0x400000), "storage": ("spi0", 0x440000), "firmware": ("spi0", 0x450000), }, "sayma": { "programmer": ProgrammerSayma, "variants": ["standalone", "master", "satellite"], "gateware": ("spi0", 0x000000), "bootloader": ("spi1", 0x000000), "storage": ("spi1", 0x040000), "firmware": ("spi1", 0x050000), }, }[args.target] variant = args.variant if "variants" in config: if variant is not None and variant not in config["variants"]: raise SystemExit("Invalid variant for this board") if variant is None: variant = config["variants"][0] bin_dir = args.dir if bin_dir is None: bin_name = args.target if variant: bin_name += "-" + variant bin_dir = os.path.join(artiq_dir, "binaries", bin_name) if args.host is None: client = LocalClient() else: client = SSHClient(args.host) programmer = config["programmer"](client, preinit_script=args.preinit_command) def artifact_path(*path_filename): if args.srcbuild is None: *path, filename = path_filename return os.path.join(bin_dir, filename) else: return os.path.join(args.srcbuild, *path_filename) try: for action in args.action: if action == "gateware": gateware_bin = artifact_path("gateware", "top.bin") if not os.access(gateware_bin, os.R_OK): bin_handle, gateware_bin = tempfile.mkstemp() gateware_bit = artifact_path("gateware", "top.bit") with open(gateware_bit, "rb") as bit_file, open(bin_handle, "wb") as bin_file: bit2bin(bit_file, bin_file) atexit.register(lambda: os.unlink(gateware_bin)) programmer.write_binary(*config["gateware"], gateware_bin) elif action == "bootloader": bootloader_bin = artifact_path("software", "bootloader", "bootloader.bin") programmer.write_binary(*config["bootloader"], bootloader_bin) elif action == "storage": storage_img = args.storage programmer.write_binary(*config["storage"], storage_img) elif action == "firmware": if variant == "satellite": firmware = "satman" else: firmware = "runtime" firmware_fbi = artifact_path("software", firmware, firmware + ".fbi") programmer.write_binary(*config["firmware"], firmware_fbi) elif action == "load": if args.target == "sayma": rtm_gateware_bit = artifact_path("rtm_gateware", "rtm.bit") programmer.load(rtm_gateware_bit, 0) gateware_bit = artifact_path("gateware", "top.bit") programmer.load(gateware_bit, 1) else: gateware_bit = artifact_path("gateware", "top.bit") programmer.load(gateware_bit, 0) elif action == "start": programmer.start() else: raise ValueError("invalid action", action) except FileNotFoundError as e: raise SystemExit(e) if args.dry_run: print("\n".join(programmer.script())) else: programmer.run()