aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorBrent Stapleton <brent.stapleton@ettus.com>2017-11-01 15:27:08 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:05:05 -0800
commitfdfe1f4c3cc7c11696e425fc9c13f029c77f79fc (patch)
treee1560890c13fde612d3ab5e439c3e1bb453ee466 /host
parent7cab06dd395928f3cc68560ec3947c181046f017 (diff)
downloaduhd-fdfe1f4c3cc7c11696e425fc9c13f029c77f79fc.tar.gz
uhd-fdfe1f4c3cc7c11696e425fc9c13f029c77f79fc.tar.bz2
uhd-fdfe1f4c3cc7c11696e425fc9c13f029c77f79fc.zip
fpga load: adding MPMD image loader function
uhd_image_loader now supports type=n310, and loads the FPGA provided in the arguments.
Diffstat (limited to 'host')
-rw-r--r--host/lib/usrp/mpmd/CMakeLists.txt1
-rw-r--r--host/lib/usrp/mpmd/mpmd_image_loader.cpp106
2 files changed, 107 insertions, 0 deletions
diff --git a/host/lib/usrp/mpmd/CMakeLists.txt b/host/lib/usrp/mpmd/CMakeLists.txt
index a5f2fb184..0530c9531 100644
--- a/host/lib/usrp/mpmd/CMakeLists.txt
+++ b/host/lib/usrp/mpmd/CMakeLists.txt
@@ -19,5 +19,6 @@ IF(ENABLE_MPMD)
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/mpmd_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mpmd_mboard_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/mpmd_image_loader.cpp
)
ENDIF(ENABLE_MPMD)
diff --git a/host/lib/usrp/mpmd/mpmd_image_loader.cpp b/host/lib/usrp/mpmd/mpmd_image_loader.cpp
new file mode 100644
index 000000000..4c73bc85f
--- /dev/null
+++ b/host/lib/usrp/mpmd/mpmd_image_loader.cpp
@@ -0,0 +1,106 @@
+//
+// Copyright 2017 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0
+//
+
+#include "mpmd_impl.hpp"
+#include <uhd/config.hpp>
+#include <uhd/device.hpp>
+#include <uhd/image_loader.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/types/eeprom.hpp>
+#include <uhd/types/component_file.hpp>
+#include <sstream>
+#include <string>
+#include <fstream>
+#include <iterator>
+#include <streambuf>
+
+using namespace uhd;
+
+namespace uhd{ namespace /*anon*/{
+ const size_t MD5LEN = 32; // Length of a MD5 hash in chars
+
+/*
+ * Function to be registered with uhd_image_loader
+ */
+static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loader_args){
+ // See if any MPM devices with the given args are found
+ device_addrs_t devs = mpmd_find(image_loader_args.args);
+
+ if (devs.size() != 1) {
+ // TODO: Do we want to handle multiple devices here?
+ // Or force uhd_image_loader to only feed us a single device?
+ return false;
+ }
+ // Grab the first device_addr and add the option to skip initialization
+ device_addr_t dev_addr(devs[0]);
+ dev_addr["skip_init"] = "1";
+ // Make the device
+ uhd::device::sptr usrp = uhd::device::make(dev_addr, uhd::device::USRP);
+ uhd::property_tree::sptr tree = usrp->get_tree();
+
+ // Populate the struct that we use to update the FPGA property
+ uhd::usrp::component_file_t component_file;
+ // Add an ID to the metadata
+ component_file.metadata["id"] = "fpga";
+ UHD_LOG_TRACE("MPMD IMAGE LOADER",
+ "FPGA ID added to the component dictionary");
+ // Add the filename to the metadata
+ // TODO: Current this field is the absolute path on the host. We're letting MPM
+ // handle cutting off the filename, but it would be better to just pass what we need to.
+ std::string fpga_filepath = image_loader_args.fpga_path;
+ component_file.metadata["filename"] = fpga_filepath;
+ UHD_LOG_TRACE("MPMD IMAGE LOADER",
+ "FPGA filename added to the component dictionary: " << fpga_filepath);
+ // Add the hash, if a hash file exists
+ std::string fpga_hash_filepath = fpga_filepath + ".md5";
+ std::ifstream fpga_hash_ifstream(fpga_hash_filepath.c_str(), std::ios::binary);
+ std::string fpga_hash;
+ if (fpga_hash_ifstream.is_open()) {
+ // TODO: Verify that the hash read is valid, ie only contains 0-9a-f.
+ fpga_hash.resize(MD5LEN);
+ fpga_hash_ifstream.read( &fpga_hash[0], MD5LEN );
+ fpga_hash_ifstream.close();
+ component_file.metadata["md5"] = fpga_hash;
+ UHD_LOG_TRACE("MPMD IMAGE LOADER", "Added FPGA hash to the component dictionary.");
+ } else {
+ // If there is no hash file, don't worry about it too much
+ UHD_LOG_WARNING("MPMD IMAGE LOADER", "Could not open FPGA hash file: "
+ << fpga_hash_filepath);
+ }
+
+ // Read the FPGA image into a structure suitable to sent as a binary string to MPM
+ // TODO: We don't have a default image specified because the image will depend on the
+ // device and configuration. We'll probably want to fix this later, but it will
+ // depend on how uhd_images_downloader deposits files.
+ std::vector<uint8_t> data;
+ std::ifstream fpga_ifstream(fpga_filepath.c_str(), std::ios::binary);
+ if (fpga_ifstream.is_open()) {
+ data.insert( data.begin(),
+ std::istreambuf_iterator<char>(fpga_ifstream),
+ std::istreambuf_iterator<char>());
+ fpga_ifstream.close();
+ } else {
+ std::string err_msg("FPGA Bitfile does not exist. " + fpga_filepath);
+ throw uhd::runtime_error(err_msg);
+ }
+ component_file.data = data;
+ UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA image read from file.");
+
+ // Call RPC to update the component
+ tree->access<uhd::usrp::component_file_t>("/mboards/0/components/fpga").set(component_file);
+ UHD_LOG_TRACE("MPMD IMAGE LOADER", "Update component function succeeded.");
+
+ return true;
+}
+}} //namespace uhd::/*anon*/
+
+UHD_STATIC_BLOCK(register_mpm_image_loader){
+ // TODO: Update recovery instructions
+ std::string recovery_instructions = "Aborting. Your USRP MPM-enabled device will likely be unusable.";
+
+ //TODO: 'n3xx' doesn't really fit the MPM abstraction, but this is simpler for the time being
+ image_loader::register_image_loader("n3xx", mpmd_image_loader, recovery_instructions);
+}