aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/mpmd
diff options
context:
space:
mode:
authorVirendra Kakade <virendra.kakade@ni.com>2019-04-30 17:05:28 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2021-01-11 13:18:22 -0600
commitfab4a5dd1708de6c5dc5fb4dc50b396a4adfeb51 (patch)
treec051515b67bbf12921d5c83ae6ac80337632f508 /host/lib/usrp/mpmd
parent643dd4f9d103da89feaa600214f2dab9d3c64bdc (diff)
downloaduhd-fab4a5dd1708de6c5dc5fb4dc50b396a4adfeb51.tar.gz
uhd-fab4a5dd1708de6c5dc5fb4dc50b396a4adfeb51.tar.bz2
uhd-fab4a5dd1708de6c5dc5fb4dc50b396a4adfeb51.zip
mpmd: Add support to delay and trigger fpga/dts load after update
Add a new image_loader argument delay_reload to provide a way to update components but optionally delay the actual load. Similarly add a new argument, just_reload, to enable uhd to reload the fpga/dts components. Signed-off-by: Virendra Kakade <virendra.kakade@ni.com>
Diffstat (limited to 'host/lib/usrp/mpmd')
-rw-r--r--host/lib/usrp/mpmd/mpmd_image_loader.cpp192
-rw-r--r--host/lib/usrp/mpmd/mpmd_prop_tree.cpp18
2 files changed, 130 insertions, 80 deletions
diff --git a/host/lib/usrp/mpmd/mpmd_image_loader.cpp b/host/lib/usrp/mpmd/mpmd_image_loader.cpp
index 3a285da3e..a44ca7713 100644
--- a/host/lib/usrp/mpmd/mpmd_image_loader.cpp
+++ b/host/lib/usrp/mpmd/mpmd_image_loader.cpp
@@ -122,91 +122,123 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t& image_loa
// Generate the component files
uhd::usrp::component_files_t all_component_files;
- // check if a component was provided
- if (not image_loader_args.id.empty() && not image_loader_args.component.empty()) {
- uhd::usrp::component_file_t component = generate_component(image_loader_args.id,
- image_loader_args.component,
- image_loader_args.metadata);
- all_component_files.push_back(component);
+ // Determine if we need to just reload the currently-loaded components.
+ // Typically called after doing delayed reload.
+ if (image_loader_args.just_reload) {
+ UHD_LOG_TRACE("MPMD IMAGE LOADER",
+ "Just reloading components. Creating stub components for reset operation.");
+ uhd::usrp::component_file_t comp_fpga_stub;
+ comp_fpga_stub.metadata["id"] = "fpga";
+ // Set the "just_reload" field to force a MPM reset leading to
+ // component reload.
+ comp_fpga_stub.metadata["just_reload"] = "true";
+
+ all_component_files.push_back(comp_fpga_stub);
} else {
- // FPGA component struct
- const auto fpga_path = [image_loader_args, dev_addr, tree]() -> std::string {
- // If the user provided a path to an fpga image, use that
- if (not image_loader_args.fpga_path.empty()) {
- if (boost::filesystem::exists(image_loader_args.fpga_path)) {
- return image_loader_args.fpga_path;
- } else {
- throw uhd::runtime_error(
- str(boost::format("FPGA file provided does not exist: %s")
- % image_loader_args.fpga_path));
- }
- }
- // Otherwise, we need to generate one
- else {
- /*
- * The user can specify an FPGA type (HG, XG, AA), rather than a filename.
- * If the user does not specify one, this will default to the type
- * currently on the device. If this cannot be determined, then the user is
- * forced to specify a filename.
- */
- const auto fpga_type = [image_loader_args, tree]() -> std::string {
- // If the user didn't provide a type, use the type of currently loaded
- // image on the device
- if (image_loader_args.args.has_key("fpga")) {
- return image_loader_args.args.get("fpga");
- } else if (tree->exists("/mboards/0/components/fpga")) {
- // Pull the FPGA info from the property tree
- // The getter should return a vector of a single component_file_t,
- // so grab the metadata from that
- auto fpga_metadata = tree->access<uhd::usrp::component_files_t>(
- "/mboards/0/components/fpga")
- .get()[0]
- .metadata;
- return fpga_metadata.get("type", "");
- // TODO: Do we want to pull the type from the filename if its not
- // available in the metadata directly?
+ // check if a component was provided
+ if (not image_loader_args.id.empty() && not image_loader_args.component.empty()) {
+ uhd::usrp::component_file_t component =
+ generate_component(image_loader_args.id,
+ image_loader_args.component,
+ image_loader_args.metadata);
+ all_component_files.push_back(component);
+ } else {
+ // Determine if we need to delay the reload of fpga/dts components.
+ bool delay_reload = image_loader_args.delay_reload;
+ UHD_LOG_TRACE(
+ "MPMD IMAGE LOADER", "Delay reload?: " << (delay_reload ? "Yes" : "No"));
+
+ // FPGA component struct
+ const auto fpga_path = [image_loader_args, dev_addr, tree]() -> std::string {
+ // If the user provided a path to an fpga image, use that
+ if (not image_loader_args.fpga_path.empty()) {
+ if (boost::filesystem::exists(image_loader_args.fpga_path)) {
+ return image_loader_args.fpga_path;
+ } else {
+ throw uhd::runtime_error(
+ str(boost::format("FPGA file provided does not exist: %s")
+ % image_loader_args.fpga_path));
}
- return "";
- }(); // generate_fpga_type lambda function
- UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA type: " << fpga_type);
-
- if (!dev_addr.has_key("product")) {
- throw uhd::runtime_error(
- "Found a device but could not auto-generate an image filename.");
- } else if (fpga_type == "") {
- return find_image_path(
- str(boost::format("usrp_%s_fpga.bit")
+ }
+ // Otherwise, we need to generate one
+ else {
+ /*
+ * The user can specify an FPGA type (HG, XG, AA), rather than a
+ * filename. If the user does not specify one, this will default to
+ * the type currently on the device. If this cannot be determined,
+ * then the user is forced to specify a filename.
+ */
+ const auto fpga_type = [image_loader_args, tree]() -> std::string {
+ // If the user didn't provide a type, use the type of currently
+ // loaded image on the device
+ if (image_loader_args.args.has_key("fpga")) {
+ return image_loader_args.args.get("fpga");
+ } else if (tree->exists("/mboards/0/components/fpga")) {
+ // Pull the FPGA info from the property tree
+ // The getter should return a vector of a single
+ // component_file_t, so grab the metadata from that
+ auto fpga_metadata =
+ tree->access<uhd::usrp::component_files_t>(
+ "/mboards/0/components/fpga")
+ .get()[0]
+ .metadata;
+ return fpga_metadata.get("type", "");
+ // TODO: Do we want to pull the type from the filename if its
+ // not available in the metadata directly?
+ }
+ return "";
+ }(); // generate_fpga_type lambda function
+ UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA type: " << fpga_type);
+
+ if (!dev_addr.has_key("product")) {
+ throw uhd::runtime_error("Found a device but could not "
+ "auto-generate an image filename.");
+ } else if (fpga_type == "") {
+ return find_image_path(str(
+ boost::format("usrp_%s_fpga.bit")
% (boost::algorithm::to_lower_copy(dev_addr["product"]))));
- } else {
- return find_image_path(
- str(boost::format("usrp_%s_fpga_%s.bit")
- % (boost::algorithm::to_lower_copy(dev_addr["product"]))
- % fpga_type));
+ } else {
+ return find_image_path(
+ str(boost::format("usrp_%s_fpga_%s.bit")
+ % (boost::algorithm::to_lower_copy(dev_addr["product"]))
+ % fpga_type));
+ }
}
+ }(); // generate_fpga_path lambda function
+ UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA path: " << fpga_path);
+ uhd::usrp::component_file_t comp_fpga = generate_component("fpga", fpga_path);
+ // If we want to delay the image reloading, explicitly turn off the
+ // component reset flag
+ if (delay_reload) {
+ comp_fpga.metadata.set("reset", "false");
+ }
+ all_component_files.push_back(comp_fpga);
+ // DTS component struct
+ // First, we need to determine the name
+ const std::string base_name =
+ boost::filesystem::change_extension(fpga_path, "").string();
+ if (base_name == fpga_path) {
+ const std::string err_msg(
+ "Can't cut extension from FPGA filename... " + fpga_path);
+ throw uhd::runtime_error(err_msg);
+ }
+ const std::string dts_path = base_name + ".dts";
+ // Then try to generate it
+ try {
+ uhd::usrp::component_file_t comp_dts =
+ generate_component("dts", dts_path);
+ // If we want to delay the image reloading, explicitly turn off the
+ // component reset flag
+ if (delay_reload) {
+ comp_dts.metadata.set("reset", "false");
+ }
+ all_component_files.push_back(comp_dts);
+ UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA and DTS images read from file.");
+ } catch (const uhd::runtime_error& ex) {
+ // If we can't find the DTS file, that's fine, continue without it
+ UHD_LOG_WARNING("MPMD IMAGE LOADER", ex.what());
+ UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA images read from file.");
}
- }(); // generate_fpga_path lambda function
- UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA path: " << fpga_path);
- uhd::usrp::component_file_t comp_fpga = generate_component("fpga", fpga_path);
- all_component_files.push_back(comp_fpga);
- // DTS component struct
- // First, we need to determine the name
- const std::string base_name =
- boost::filesystem::change_extension(fpga_path, "").string();
- if (base_name == fpga_path) {
- const std::string err_msg(
- "Can't cut extension from FPGA filename... " + fpga_path);
- throw uhd::runtime_error(err_msg);
- }
- const std::string dts_path = base_name + ".dts";
- // Then try to generate it
- try {
- uhd::usrp::component_file_t comp_dts = generate_component("dts", dts_path);
- all_component_files.push_back(comp_dts);
- UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA and DTS images read from file.");
- } catch (const uhd::runtime_error& ex) {
- // If we can't find the DTS file, that's fine, continue without it
- UHD_LOG_WARNING("MPMD IMAGE LOADER", ex.what());
- UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA images read from file.");
}
}
// Call RPC to update the component
diff --git a/host/lib/usrp/mpmd/mpmd_prop_tree.cpp b/host/lib/usrp/mpmd/mpmd_prop_tree.cpp
index 556e2e48d..2bd955194 100644
--- a/host/lib/usrp/mpmd/mpmd_prop_tree.cpp
+++ b/host/lib/usrp/mpmd/mpmd_prop_tree.cpp
@@ -13,6 +13,8 @@
#include <uhd/types/eeprom.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
+#include <uhd/utils/cast.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
using namespace uhd;
using namespace uhd::mpmd;
@@ -34,6 +36,7 @@ uhd::usrp::component_files_t _update_component(
// Also construct a copy of just the metadata to store in the property tree
uhd::usrp::component_files_t all_comps_copy;
+ bool just_reload = false;
for (const auto& comp : comps) {
// Make a map for update components args
std::map<std::string, std::string> metadata;
@@ -43,6 +46,12 @@ uhd::usrp::component_files_t _update_component(
for (const auto& key : comp.metadata.keys()) {
metadata[key] = comp.metadata[key];
comp_copy.metadata[key] = comp.metadata[key];
+ if (key == "just_reload") {
+ just_reload =
+ just_reload
+ | uhd::cast::from_str<bool>(metadata.at("just_reload"));
+ //| (boost::to_lower_copy(metadata.at("just_reload")) == "true");
+ }
}
// Copy to the update component args
all_data.push_back(comp.data);
@@ -51,6 +60,15 @@ uhd::usrp::component_files_t _update_component(
all_comps_copy.push_back(comp_copy);
}
+ // If reset is specified we presume that the fpga/dts
+ // components were updated in the last uhd::image_loader::load()
+ // call and just reload the fpga/dts by resetting the peripheral
+ // manager.
+ if (just_reload) {
+ mb->rpc->notify_with_token(MPMD_DEFAULT_INIT_TIMEOUT, "reset_timer_and_mgr");
+ return all_comps_copy;
+ }
+
// Now call update component
mb->rpc->notify_with_token(
MPMD_DEFAULT_INIT_TIMEOUT, "update_component", all_metadata, all_data);