mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-27 04:08:27 +08:00
bit2bin, fetch_bin -> flash_tools
This commit is contained in:
parent
f2c13a5041
commit
de349e4c39
@ -12,8 +12,7 @@ from artiq import __version__ as artiq_version
|
||||
from artiq.master.databases import DeviceDB
|
||||
from artiq.coredevice.comm_kernel import CommKernel
|
||||
from artiq.coredevice.comm_mgmt import CommMgmt
|
||||
from artiq.frontend.bit2bin import bit2bin
|
||||
from artiq.frontend.fetch_bin import fetch_bin
|
||||
from artiq.frontend.flash_tools import bit2bin, fetch_bin
|
||||
|
||||
|
||||
def get_argparser():
|
||||
|
@ -14,8 +14,7 @@ from sipyco import common_args
|
||||
|
||||
from artiq import __version__ as artiq_version
|
||||
from artiq.remoting import SSHClient, LocalClient
|
||||
from artiq.frontend.bit2bin import bit2bin
|
||||
from artiq.frontend.fetch_bin import fetch_bin
|
||||
from artiq.frontend.flash_tools import artifact_path, bit2bin, fetch_bin
|
||||
|
||||
|
||||
def get_argparser():
|
||||
@ -305,10 +304,10 @@ def main():
|
||||
|
||||
for action in args.action:
|
||||
if action == "gateware":
|
||||
gateware_bin = fetch_bin(binary_dir, "gateware", args.srcbuild)
|
||||
gateware_bin = fetch_bin(binary_dir, ["gateware"], args.srcbuild)
|
||||
programmer.write_binary(*config["gateware"], gateware_bin)
|
||||
elif action == "bootloader":
|
||||
bootloader_bin = fetch_bin(binary_dir, "bootloader", args.srcbuild)
|
||||
bootloader_bin = fetch_bin(binary_dir, ["bootloader"], args.srcbuild)
|
||||
programmer.write_binary(*config["bootloader"], bootloader_bin)
|
||||
elif action == "storage":
|
||||
storage_img = args.storage
|
||||
|
@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2014-2017 Robert Jordens <jordens@gmail.com>
|
||||
# after
|
||||
# https://github.com/mfischer/fpgadev-zynq/blob/master/top/python/bit_to_zynq_bin.py
|
||||
|
||||
import struct
|
||||
|
||||
|
||||
def flip32(data):
|
||||
sl = struct.Struct("<I")
|
||||
sb = struct.Struct(">I")
|
||||
b = memoryview(data)
|
||||
d = bytearray(len(data))
|
||||
for offset in range(0, len(data), sl.size):
|
||||
sb.pack_into(d, offset, *sl.unpack_from(b, offset))
|
||||
return d
|
||||
|
||||
|
||||
def bit2bin(bit, bin, flip=False):
|
||||
l, = struct.unpack(">H", bit.read(2))
|
||||
if l != 9:
|
||||
raise ValueError("Missing <0009> header, not a bit file")
|
||||
_ = bit.read(l) # unknown data
|
||||
l, = struct.unpack(">H", bit.read(2))
|
||||
if l != 1:
|
||||
raise ValueError("Missing <0001> header, not a bit file")
|
||||
|
||||
while True:
|
||||
key = bit.read(1).decode()
|
||||
if not key:
|
||||
break
|
||||
if key in "abcd":
|
||||
d = bit.read(*struct.unpack(">H", bit.read(2)))
|
||||
assert d.endswith(b"\x00")
|
||||
d = d[:-1].decode()
|
||||
name = {
|
||||
"a": "Design",
|
||||
"b": "Part name",
|
||||
"c": "Date",
|
||||
"d": "Time"
|
||||
}[key]
|
||||
print("{}: {}".format(name, d))
|
||||
elif key == "e":
|
||||
l, = struct.unpack(">I", bit.read(4))
|
||||
print("Bitstream payload length: {:#x}".format(l))
|
||||
d = bit.read(l)
|
||||
if flip:
|
||||
d = flip32(d)
|
||||
bin.write(d)
|
||||
else:
|
||||
d = bit.read(*struct.unpack(">H", bit.read(2)))
|
||||
print("Unexpected key: {}: {}".format(key, d))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Convert FPGA bit files to raw bin format "
|
||||
"suitable for flashing")
|
||||
parser.add_argument("-f", "--flip", dest="flip", action="store_true",
|
||||
default=False, help="Flip 32-bit endianess (needed for Zynq)")
|
||||
parser.add_argument("bitfile", metavar="BITFILE",
|
||||
help="Input bit file name")
|
||||
parser.add_argument("binfile", metavar="BINFILE",
|
||||
help="Output bin file name")
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.bitfile, "rb") as f, open(args.binfile, "wb") as g:
|
||||
bit2bin(f, g, args.flip)
|
@ -1,59 +0,0 @@
|
||||
import atexit
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from artiq.frontend.bit2bin import bit2bin
|
||||
|
||||
|
||||
def fetch_bin(binary_dir, component, srcbuild=False):
|
||||
def artifact_path(this_binary_dir, *path_filename):
|
||||
if 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):
|
||||
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:
|
||||
bit2bin(bit_file, bin_file)
|
||||
atexit.register(lambda: os.unlink(bin_filename))
|
||||
return bin_filename
|
||||
|
||||
if type(component) == list:
|
||||
bins = []
|
||||
for option in component:
|
||||
try:
|
||||
bins.append(fetch_bin(binary_dir, option, srcbuild))
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
if bins is None:
|
||||
raise FileNotFoundError("multiple components not found: {}".format(
|
||||
" ".join(component)))
|
||||
|
||||
if len(bins) > 1:
|
||||
raise ValueError("more than one file, "
|
||||
"please clean up your build directory. "
|
||||
"Found files: {}".format(
|
||||
" ".join(bins)))
|
||||
|
||||
return bins[0]
|
||||
|
||||
path = artifact_path(binary_dir, *{
|
||||
"gateware": ["gateware", "top.bit"],
|
||||
"bootloader": ["software", "bootloader", "bootloader.bin"],
|
||||
"runtime": ["software", "runtime", "runtime.fbi"],
|
||||
"satman": ["software", "satman", "satman.fbi"],
|
||||
}[component])
|
||||
|
||||
if not os.path.exists(path):
|
||||
raise FileNotFoundError("{} not found".format(component))
|
||||
|
||||
if component == "gateware":
|
||||
path = convert_gateware(path)
|
||||
|
||||
return path
|
114
artiq/frontend/flash_tools.py
Normal file
114
artiq/frontend/flash_tools.py
Normal file
@ -0,0 +1,114 @@
|
||||
import atexit
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
|
||||
def artifact_path(this_binary_dir, *path_filename, srcbuild=False):
|
||||
if 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 fetch_bin(binary_dir, components, srcbuild=False):
|
||||
def convert_gateware(bit_filename):
|
||||
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:
|
||||
bit2bin(bit_file, bin_file)
|
||||
atexit.register(lambda: os.unlink(bin_filename))
|
||||
return bin_filename
|
||||
|
||||
if len(components) > 1:
|
||||
bins = []
|
||||
for option in components:
|
||||
try:
|
||||
bins.append(fetch_bin(binary_dir, [option], srcbuild))
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
if bins is None:
|
||||
raise FileNotFoundError("multiple components not found: {}".format(
|
||||
" ".join(components)))
|
||||
|
||||
if len(bins) > 1:
|
||||
raise ValueError("more than one file, "
|
||||
"please clean up your build directory. "
|
||||
"Found files: {}".format(
|
||||
" ".join(bins)))
|
||||
|
||||
return bins[0]
|
||||
|
||||
else:
|
||||
component = components[0]
|
||||
path = artifact_path(binary_dir, *{
|
||||
"gateware": ["gateware", "top.bit"],
|
||||
"boot": ["boot.bin"],
|
||||
"bootloader": ["software", "bootloader", "bootloader.bin"],
|
||||
"runtime": ["software", "runtime", "runtime.fbi"],
|
||||
"satman": ["software", "satman", "satman.fbi"],
|
||||
}[component], srcbuild=srcbuild)
|
||||
|
||||
if not os.path.exists(path):
|
||||
raise FileNotFoundError("{} not found".format(component))
|
||||
|
||||
if component == "gateware":
|
||||
path = convert_gateware(path)
|
||||
|
||||
return path
|
||||
|
||||
|
||||
# Copyright 2014-2017 Robert Jordens <jordens@gmail.com>
|
||||
# after
|
||||
# https://github.com/mfischer/fpgadev-zynq/blob/master/top/python/bit_to_zynq_bin.py
|
||||
|
||||
import struct
|
||||
|
||||
|
||||
def flip32(data):
|
||||
sl = struct.Struct("<I")
|
||||
sb = struct.Struct(">I")
|
||||
b = memoryview(data)
|
||||
d = bytearray(len(data))
|
||||
for offset in range(0, len(data), sl.size):
|
||||
sb.pack_into(d, offset, *sl.unpack_from(b, offset))
|
||||
return d
|
||||
|
||||
|
||||
def bit2bin(bit, bin, flip=False):
|
||||
l, = struct.unpack(">H", bit.read(2))
|
||||
if l != 9:
|
||||
raise ValueError("Missing <0009> header, not a bit file")
|
||||
_ = bit.read(l) # unknown data
|
||||
l, = struct.unpack(">H", bit.read(2))
|
||||
if l != 1:
|
||||
raise ValueError("Missing <0001> header, not a bit file")
|
||||
|
||||
while True:
|
||||
key = bit.read(1).decode()
|
||||
if not key:
|
||||
break
|
||||
if key in "abcd":
|
||||
d = bit.read(*struct.unpack(">H", bit.read(2)))
|
||||
assert d.endswith(b"\x00")
|
||||
d = d[:-1].decode()
|
||||
name = {
|
||||
"a": "Design",
|
||||
"b": "Part name",
|
||||
"c": "Date",
|
||||
"d": "Time"
|
||||
}[key]
|
||||
print("{}: {}".format(name, d))
|
||||
elif key == "e":
|
||||
l, = struct.unpack(">I", bit.read(4))
|
||||
print("Bitstream payload length: {:#x}".format(l))
|
||||
d = bit.read(l)
|
||||
if flip:
|
||||
d = flip32(d)
|
||||
bin.write(d)
|
||||
else:
|
||||
d = bit.read(*struct.unpack(">H", bit.read(2)))
|
||||
print("Unexpected key: {}: {}".format(key, d))
|
Loading…
Reference in New Issue
Block a user