Skip to content

Support extra files in UUUDriver, and pass usb device path #1632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2541,6 +2541,8 @@ Implements:
UUUDriver:
image: 'mybootloaderkey'
script: 'spl'
extra_files:
- 'fitImage'

images:
mybootloaderkey: 'path/to/mybootloader.img'
Expand All @@ -2549,6 +2551,7 @@ Arguments:
- image (str): optional, key in :ref:`images <labgrid-device-config-images>` containing the path
of an image to bootstrap onto the target
- script (str): optional, run built-in script with ``uuu -b``, called with image as arg0
- extra_files (list): optional, paths to synchronize to exporter before invoking ``uuu``

USBStorageDriver
~~~~~~~~~~~~~~~~
Expand Down
39 changes: 38 additions & 1 deletion labgrid/driver/usbloader.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import hashlib
import subprocess
import attr

Expand Down Expand Up @@ -158,6 +159,7 @@ class UUUDriver(Driver, BootstrapProtocol):

image = attr.ib(default=None)
script = attr.ib(default='', validator=attr.validators.instance_of(str))
extra_files = attr.ib(default=[], validator=attr.validators.instance_of(list))

def __attrs_post_init__(self):
super().__attrs_post_init__()
Expand All @@ -167,6 +169,8 @@ def __attrs_post_init__(self):
else:
self.tool = 'uuu-loader'

self.hash = None

def on_activate(self):
pass

Expand All @@ -178,16 +182,49 @@ def on_deactivate(self):
def load(self, filename=None):
if filename is None and self.image is not None:
filename = self.target.env.config.get_image_path(self.image)

mf = ManagedFile(filename, self.loader)
mf.hash = self.get_hash(filename)
mf.sync_to_resource()

cmd = ['-b', self.script] if self.script else []
for file in self.extra_files or []:
file_mf = ManagedFile(file, self.loader)
file_mf.hash = self.get_hash(filename)
file_mf.sync_to_resource()

# Enable verbose mode to avoid messing up the terminal, and pass the usb device path to `uuu`. Notice that
# `uuu` specifies paths in <bus>:<port><port>... format.
cmd = ["-v", "-m", self.loader.path.replace(".", "").replace("-", ":")]
cmd += ['-b', self.script] if self.script else []

processwrapper.check_output(
self.loader.command_prefix + [self.tool] + cmd + [mf.get_remote_path()],
print_on_silent_log=True
)

def get_hash(self, image):
"""Create a hash of all input files combined to use when synchronizing managed files."""
if self.hash is not None:
return self.hash

hasher = hashlib.sha256()

# Inspired by the implementation of hashlib.file_digest() from CPython, but adapted to read
# multiple files instead of a single one.
buf = bytearray(2**18) # Reusable buffer to reduce allocations.
view = memoryview(buf)

for file in [image] + self.extra_files:
with open(file, 'rb') as fileobj:
while True:
size = fileobj.readinto(buf)
if size == 0:
break # EOF
hasher.update(view[:size])

self.hash = hasher.hexdigest()
return self.hash


@target_factory.reg_driver
@attr.s(eq=False)
Expand Down