aboutsummaryrefslogtreecommitdiffstats
path: root/mpm
diff options
context:
space:
mode:
authorBrent Stapleton <brent.stapleton@ettus.com>2017-11-10 17:34:24 -0800
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:05:43 -0800
commita2029b0439e6474b25c189c3f1741caac8006c11 (patch)
tree1f4e558f714b6ee3bf9f08528ecd387e45dbc065 /mpm
parent61774a09613eed51a42496f8689b707417b360f2 (diff)
downloaduhd-a2029b0439e6474b25c189c3f1741caac8006c11.tar.gz
uhd-a2029b0439e6474b25c189c3f1741caac8006c11.tar.bz2
uhd-a2029b0439e6474b25c189c3f1741caac8006c11.zip
fpga load: Atomic updating of multiple components
- The MPM function update_component now accepts multiple components to be updated in one RPC call. - Updated the property tree and image loader to match this change. - Also added DTS loading to the image loader.
Diffstat (limited to 'mpm')
-rw-r--r--mpm/python/usrp_mpm/periph_manager/base.py69
-rw-r--r--mpm/python/usrp_mpm/periph_manager/n310.py17
2 files changed, 46 insertions, 40 deletions
diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py
index 3cfcc0ce8..4d58b0933 100644
--- a/mpm/python/usrp_mpm/periph_manager/base.py
+++ b/mpm/python/usrp_mpm/periph_manager/base.py
@@ -419,28 +419,24 @@ class PeriphManagerBase(object):
"""
return [dboard.device_info for dboard in self.dboards]
- def update_component(self, file_metadata, data):
+ def update_component(self, metadata_l, data_l):
"""
Updates the device component specified by comp_dict
- :param file_metadata: Dictionary of strings containing metadata
- :param data: Binary string with the file contents to be written
- """
- id_str = file_metadata['id']
- filename = os.path.basename(file_metadata['filename'])
- if id_str not in self.updateable_components:
- self.log.error("{0} not an updateable component ({1})".format(
- id_str, self.updateable_components.keys()
- ))
- raise NotImplementedError("Update component not implemented for {}".format(id_str))
- self.log.trace("Updating component: {}".format(id_str))
- if 'md5' in file_metadata:
- given_hash = file_metadata['md5']
- comp_hash = md5()
- comp_hash.update(data)
- comp_hash = comp_hash.hexdigest()
- if comp_hash == given_hash:
- self.log.trace("FPGA bitfile hash matched: {}".format(
- comp_hash
+ :param metadata_l: List of dictionary of strings containing metadata
+ :param data_l: List of binary string with the file contents to be written
+ """
+ # We need a 'metadata' and a 'data' for each file we want to update
+ assert (len(metadata_l) == len(data_l)),\
+ "update_component arguments must be the same length"
+ # TODO: Update the manifest file
+
+ # Iterate through the components, updating each in turn
+ for metadata, data in zip(metadata_l, data_l):
+ id_str = metadata['id']
+ filename = os.path.basename(metadata['filename'])
+ if id_str not in self.updateable_components:
+ self.log.error("{0} not an updateable component ({1})".format(
+ id_str, self.updateable_components.keys()
))
raise KeyError("Update component not implemented for {}".format(id_str))
self.log.trace("Updating component: {}".format(id_str))
@@ -460,24 +456,19 @@ class PeriphManagerBase(object):
comp_hash, given_hash))
raise RuntimeError("Component file hash mismatch")
else:
- self.log.error("FPGA bitfile hash mismatched:")
- self.log.error("Calculated {}".format(comp_hash))
- self.log.error("Given {}".format(given_hash))
- raise RuntimeError("FPGA Bitfile hash mismatch")
- else:
- self.log.trace("Loading unverified {} image.".format(
- id_str
- ))
- basepath = os.path.join(os.sep, "tmp", "uploads")
- filepath = os.path.join(basepath, filename)
- if not os.path.isdir(basepath):
- self.log.trace("Creating directory {}".format(basepath))
- os.makedirs(basepath)
- self.log.trace("Writing data to {}".format(filepath))
- with open(filepath, 'wb') as f:
- f.write(data)
- update_func = getattr(self, self.updateable_components[id_str]['callback'])
- update_func(filepath, file_metadata)
+ self.log.trace("Loading unverified {} image.".format(
+ id_str
+ ))
+ basepath = os.path.join(os.sep, "tmp", "uploads")
+ filepath = os.path.join(basepath, filename)
+ if not os.path.isdir(basepath):
+ self.log.trace("Creating directory {}".format(basepath))
+ os.makedirs(basepath)
+ self.log.trace("Writing data to {}".format(filepath))
+ with open(filepath, 'wb') as f:
+ f.write(data)
+ update_func = getattr(self, self.updateable_components[id_str]['callback'])
+ update_func(filepath, metadata)
return True
@@ -697,5 +688,3 @@ class PeriphManagerBase(object):
- src_port: IP port the connection is coming from.
"""
raise NotImplementedError("commit_xport() not implemented.")
-
-
diff --git a/mpm/python/usrp_mpm/periph_manager/n310.py b/mpm/python/usrp_mpm/periph_manager/n310.py
index 84ab3ae7e..1dab1b572 100644
--- a/mpm/python/usrp_mpm/periph_manager/n310.py
+++ b/mpm/python/usrp_mpm/periph_manager/n310.py
@@ -472,11 +472,15 @@ class n310(PeriphManagerBase):
# dboard, etc. The host is responsible for providing a compatible image
# for the N310's current setup.
binfile_path = '/lib/firmware/n310.bin'
+ dts_path = '/lib/firmware/n310.dts'
# Override the list of updateable components
updateable_components = {
'fpga': {
'callback': "update_fpga",
},
+ 'dts': {
+ 'callback': "update_dts",
+ },
}
def __init__(self, args):
@@ -913,3 +917,16 @@ class n310(PeriphManagerBase):
raise RuntimeError("Invalid N310 FPGA bitfile")
# TODO: Implement reload procedure
return True
+
+ @no_rpc
+ def update_dts(self, filepath, metadata):
+ """
+ Update the DTS image in the filesystem
+ :param filepath: path to new DTS image
+ :param metadata: Dictionary of strings containing metadata
+ """
+ self.log.trace("Updating DTS with image at {}"
+ .format(filepath))
+ shutil.copy(filepath, self.dts_path)
+ # TODO: Compile the new dts file into a usable dtbo
+ return True