forked from M-Labs/artiq
artiq_flash: add sayma support.
This commit is contained in:
parent
529033e016
commit
6891141fa6
@ -34,7 +34,8 @@ To avoid conflicts for development boards on the server, while using a board you
|
||||
|
||||
To lock the KC705 for 30 minutes or until Ctrl-C is pressed:
|
||||
::
|
||||
flock --verbose /run/boards/kc705 sleep 1800
|
||||
flock --verbose /run/boards/kc705_1 sleep 1800
|
||||
|
||||
Check that the command acquires the lock, i.e. prints something such as:
|
||||
::
|
||||
flock: getting lock took 0.000003 seconds
|
||||
@ -42,7 +43,7 @@ Check that the command acquires the lock, i.e. prints something such as:
|
||||
|
||||
To lock the KC705 for the duration of the execution of a shell:
|
||||
::
|
||||
flock /run/boards/kc705 bash
|
||||
flock /run/boards/kc705_1 bash
|
||||
|
||||
You may also use this script:
|
||||
::
|
||||
@ -53,7 +54,7 @@ If the board is already locked by another user, the ``flock`` commands above wil
|
||||
|
||||
To determine which user is locking a board, use:
|
||||
::
|
||||
fuser -v /run/boards/kc705
|
||||
fuser -v /run/boards/kc705_1
|
||||
|
||||
|
||||
Selecting a development board with artiq_flash
|
||||
|
@ -22,30 +22,33 @@ def get_argparser():
|
||||
|
||||
verbosity_args(parser)
|
||||
|
||||
parser.add_argument("-H", "--host", metavar="HOSTNAME",
|
||||
type=str, default="lab.m-labs.hk",
|
||||
help="SSH host where the development board is located")
|
||||
parser.add_argument("-D", "--device", metavar="HOSTNAME",
|
||||
type=str, default="kc705.lab.m-labs.hk",
|
||||
help="address or domain corresponding to the development board")
|
||||
parser.add_argument("-s", "--serial", metavar="PATH",
|
||||
type=str, default="/dev/ttyUSB_kc705",
|
||||
help="TTY device corresponding to the development board")
|
||||
parser.add_argument("-l", "--lockfile", metavar="PATH",
|
||||
type=str, default="/run/boards/kc705",
|
||||
help="The lockfile to be acquired for the duration of the actions")
|
||||
parser.add_argument("-w", "--wait", action="store_true",
|
||||
help="Wait for the board to unlock instead of aborting the actions")
|
||||
parser.add_argument("-t", "--target", metavar="TARGET",
|
||||
type=str, default="kc705_dds",
|
||||
help="Target to build, one of: "
|
||||
"kc705_dds kasli sayma_amc_standalone "
|
||||
"kc705_dds kasli sayma_rtm sayma_amc_standalone "
|
||||
"sayma_amc_drtio_master sayma_amc_drtio_satellite")
|
||||
parser.add_argument("-H", "--host", metavar="HOSTNAME",
|
||||
type=str, default="lab.m-labs.hk",
|
||||
help="SSH host where the development board is located")
|
||||
parser.add_argument('-b', "--board", metavar="BOARD",
|
||||
type=str, default=None,
|
||||
help="Board to connect to on the development SSH host")
|
||||
parser.add_argument("-d", "--device", metavar="DEVICENAME",
|
||||
type=str, default="{board}.{hostname}",
|
||||
help="Address or domain corresponding to the development board")
|
||||
parser.add_argument("-s", "--serial", metavar="SERIAL",
|
||||
type=str, default="/dev/ttyUSB_{board}",
|
||||
help="TTY device corresponding to the development board")
|
||||
parser.add_argument("-l", "--lockfile", metavar="LOCKFILE",
|
||||
type=str, default="/run/boards/{board}",
|
||||
help="The lockfile to be acquired for the duration of the actions")
|
||||
parser.add_argument("-w", "--wait", action="store_true",
|
||||
help="Wait for the board to unlock instead of aborting the actions")
|
||||
|
||||
parser.add_argument("actions", metavar="ACTION",
|
||||
type=str, default=[], nargs="+",
|
||||
help="actions to perform, sequence of: "
|
||||
"build boot boot+log connect reset hotswap clean")
|
||||
"build clean reset flash flash+log hotswap")
|
||||
|
||||
return parser
|
||||
|
||||
@ -56,19 +59,47 @@ def main():
|
||||
if args.verbose == args.quiet == 0:
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
if args.target in ["kc705_dds", "kasli", "sayma_amc_standalone", "sayma_amc_drtio_master"]:
|
||||
firmware = "runtime"
|
||||
build_args = []
|
||||
if args.target == "kc705_dds":
|
||||
boardtype, firmware = "kc705", "runtime"
|
||||
elif args.target == "sayma_amc_standalone":
|
||||
boardtype, firmware = "sayma", "runtime"
|
||||
build_args += ["--rtm-csr-csv", "/tmp/sayma_rtm/sayma_rtm_csr.csv"]
|
||||
elif args.target == "sayma_amc_drtio_master":
|
||||
boardtype, firmware = "sayma", "runtime"
|
||||
elif args.target == "sayma_amc_drtio_satellite":
|
||||
firmware = "satman"
|
||||
boardtype, firmware = "sayma", "satman"
|
||||
elif args.target == "sayma_rtm":
|
||||
boardtype, firmware = "sayma_rtm", None
|
||||
else:
|
||||
raise NotImplementedError("unknown target {}".format(args.target))
|
||||
|
||||
flash_args = ["-t", boardtype]
|
||||
if boardtype == "sayma":
|
||||
if args.board is None:
|
||||
args.board = "sayma_1"
|
||||
if args.board == "sayma_1":
|
||||
flash_args += ["--preinit-command", "ftdi_location 5:2"]
|
||||
elif args.board == "sayma_2":
|
||||
flash_args += ["--preinit-command", "ftdi_location 3:10"]
|
||||
elif args.board == "sayma_3":
|
||||
flash_args += ["--preinit-command", "ftdi_location 5:1"]
|
||||
else:
|
||||
raise NotImplementedError("unknown --preinit-command for {}".format(boardtype))
|
||||
|
||||
client = SSHClient(args.host)
|
||||
substs = {
|
||||
"env": "bash -c 'export PATH=$HOME/miniconda/bin:$PATH; exec $0 $*' ",
|
||||
"serial": args.serial,
|
||||
"target": args.target,
|
||||
"hostname": args.host,
|
||||
"boardtype": boardtype,
|
||||
"board": args.board if args.board else boardtype + "_1",
|
||||
"firmware": firmware,
|
||||
}
|
||||
substs.update({
|
||||
"devicename": args.device.format(**substs),
|
||||
"lockfile": args.lockfile.format(**substs),
|
||||
"serial": args.serial.format(**substs),
|
||||
})
|
||||
|
||||
flock_acquired = False
|
||||
flock_file = None # GC root
|
||||
@ -80,7 +111,7 @@ def main():
|
||||
logger.info("Acquiring device lock")
|
||||
flock = client.spawn_command("flock --verbose {block} {lockfile} sleep 86400"
|
||||
.format(block="" if args.wait else "--nonblock",
|
||||
lockfile=args.lockfile),
|
||||
**substs),
|
||||
get_pty=True)
|
||||
flock_file = flock.makefile('r')
|
||||
while not flock_acquired:
|
||||
@ -94,43 +125,64 @@ def main():
|
||||
logger.error("Failed to get lock")
|
||||
sys.exit(1)
|
||||
|
||||
def artiq_flash(args, synchronous=True):
|
||||
args = flash_args + args
|
||||
args = ["'{}'".format(arg) if " " in arg else arg for arg in args]
|
||||
cmd = client.spawn_command(
|
||||
"artiq_flash " + " ".join(args),
|
||||
**substs)
|
||||
if synchronous:
|
||||
client.drain(cmd)
|
||||
else:
|
||||
return cmd
|
||||
|
||||
for action in args.actions:
|
||||
if action == "build":
|
||||
logger.info("Building firmware")
|
||||
logger.info("Building target")
|
||||
try:
|
||||
subprocess.check_call(["python3",
|
||||
"-m", "artiq.gateware.targets." + args.target,
|
||||
"--no-compile-gateware",
|
||||
*build_args,
|
||||
"--output-dir",
|
||||
"/tmp/{target}".format(target=args.target)])
|
||||
"/tmp/{target}".format(**substs)])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.error("Build failed")
|
||||
sys.exit(1)
|
||||
|
||||
elif action == "clean":
|
||||
logger.info("Cleaning build directory")
|
||||
target_dir = "/tmp/{target}".format(target=args.target)
|
||||
target_dir = "/tmp/{target}".format(**substs)
|
||||
if os.path.isdir(target_dir):
|
||||
shutil.rmtree(target_dir)
|
||||
|
||||
elif action == "boot" or action == "boot+log":
|
||||
lock()
|
||||
elif action == "reset":
|
||||
logger.info("Resetting device")
|
||||
artiq_flash(["reset"])
|
||||
|
||||
logger.info("Uploading firmware")
|
||||
client.get_sftp().put("/tmp/{target}/software/{firmware}/{firmware}.bin"
|
||||
.format(target=args.target, firmware=firmware),
|
||||
"{tmp}/{firmware}.bin"
|
||||
.format(tmp=client.tmp, firmware=firmware))
|
||||
elif action == "flash" or action == "flash+log":
|
||||
def upload_product(product, ext):
|
||||
logger.info("Uploading {}".format(product))
|
||||
client.get_sftp().put("/tmp/{target}/software/{product}/{product}.{ext}"
|
||||
.format(target=args.target, product=product, ext=ext),
|
||||
"{tmp}/{product}.{ext}"
|
||||
.format(tmp=client.tmp, product=product, ext=ext))
|
||||
|
||||
upload_product("bootloader", "bin")
|
||||
upload_product(firmware, "fbi")
|
||||
|
||||
logger.info("Flashing firmware")
|
||||
artiq_flash(["-d", "{tmp}", "proxy", "bootloader", "firmware",
|
||||
"start" if action == "flash" else ""])
|
||||
|
||||
if action == "flash+log":
|
||||
logger.info("Booting firmware")
|
||||
flterm = client.spawn_command(
|
||||
"{env} python3 flterm.py {serial} " +
|
||||
"flterm {serial} " +
|
||||
"--kernel {tmp}/{firmware}.bin " +
|
||||
("--upload-only" if action == "boot" else "--output-only"),
|
||||
**substs)
|
||||
artiq_flash = client.spawn_command(
|
||||
"{env} artiq_flash start",
|
||||
**substs)
|
||||
artiq_flash(["start"], synchronous=False)
|
||||
client.drain(flterm)
|
||||
|
||||
elif action == "connect":
|
||||
@ -187,13 +239,7 @@ def main():
|
||||
logger.info("Forwarding ports {} to core device and logs from core device"
|
||||
.format(", ".join(map(str, ports))))
|
||||
client.run_command(
|
||||
"{env} python3 flterm.py {serial} --output-only",
|
||||
**substs)
|
||||
|
||||
elif action == "reset":
|
||||
logger.info("Resetting device")
|
||||
client.run_command(
|
||||
"{env} artiq_flash start",
|
||||
"flterm {serial} --output-only",
|
||||
**substs)
|
||||
|
||||
elif action == "hotswap":
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||
@ -182,13 +183,28 @@ class SaymaRTM(Module):
|
||||
|
||||
|
||||
def main():
|
||||
build_dir = "artiq_sayma_rtm"
|
||||
parser = argparse.ArgumentParser(
|
||||
description="ARTIQ device binary builder for Kasli systems")
|
||||
parser.add_argument("--output-dir", default="artiq_sayma_rtm",
|
||||
help="output directory for generated "
|
||||
"source files and binaries")
|
||||
parser.add_argument("--no-compile-gateware", action="store_true",
|
||||
help="do not compile the gateware, only generate "
|
||||
"the CSR map")
|
||||
parser.add_argument("--csr-csv", default=None,
|
||||
help="store CSR map in CSV format into the "
|
||||
"specified file")
|
||||
args = parser.parse_args()
|
||||
|
||||
platform = sayma_rtm.Platform()
|
||||
top = SaymaRTM(platform)
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
with open(os.path.join(build_dir, "sayma_rtm_csr.csv"), "w") as f:
|
||||
|
||||
os.makedirs(args.output_dir, exist_ok=True)
|
||||
with open(os.path.join(args.output_dir, "sayma_rtm_csr.csv"), "w") as f:
|
||||
f.write(get_csr_csv(top.csr_regions))
|
||||
platform.build(top, build_dir=build_dir)
|
||||
|
||||
if not args.no_compile_gateware:
|
||||
platform.build(top, build_dir=args.output_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user