diff options
Diffstat (limited to 'host/lib/usrp/mpmd')
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_devices.hpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_find.cpp | 175 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_image_loader.cpp | 121 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_impl.cpp | 369 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_impl.hpp | 90 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_mboard_impl.cpp | 516 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_prop_tree.cpp | 280 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport.cpp | 61 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp | 16 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp | 117 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp | 31 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp | 350 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp | 20 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport_mgr.cpp | 87 | ||||
-rw-r--r-- | host/lib/usrp/mpmd/mpmd_xport_mgr.hpp | 32 |
15 files changed, 983 insertions, 1284 deletions
diff --git a/host/lib/usrp/mpmd/mpmd_devices.hpp b/host/lib/usrp/mpmd/mpmd_devices.hpp index ab0cc1271..9cc046037 100644 --- a/host/lib/usrp/mpmd/mpmd_devices.hpp +++ b/host/lib/usrp/mpmd/mpmd_devices.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_MPMD_DEVICES_HPP #define INCLUDED_MPMD_DEVICES_HPP -#include <vector> #include <string> +#include <vector> static constexpr char MPM_CATCHALL_DEVICE_TYPE[] = "mpm"; diff --git a/host/lib/usrp/mpmd/mpmd_find.cpp b/host/lib/usrp/mpmd/mpmd_find.cpp index 26230e396..5d2406b30 100644 --- a/host/lib/usrp/mpmd/mpmd_find.cpp +++ b/host/lib/usrp/mpmd/mpmd_find.cpp @@ -6,11 +6,11 @@ // find-related code for MPM devices -#include "mpmd_impl.hpp" #include "mpmd_devices.hpp" -#include <uhd/types/device_addr.hpp> -#include <uhd/transport/udp_simple.hpp> +#include "mpmd_impl.hpp" #include <uhd/transport/if_addrs.hpp> +#include <uhd/transport/udp_simple.hpp> +#include <uhd/types/device_addr.hpp> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <future> @@ -19,60 +19,50 @@ using namespace uhd; using namespace uhd::mpmd; namespace { - //! How long we wait for discovery responses (in seconds) - constexpr double MPMD_FIND_TIMEOUT = 0.5; - constexpr char MPMD_CHDR_REACHABILITY_KEY[] = "reachable"; - constexpr char MPMD_CHDR_REACHABILITY_NEGATIVE[] = "No"; - //! The preamble for any response on the discovery port. Can be used to - // verify that the response is actually an MPM device. - constexpr char MPM_DISC_RESPONSE_PREAMBLE[] = "USRP-MPM"; - - device_addr_t flag_dev_as_unreachable(const device_addr_t& device_args) - { - device_addr_t flagged_device_args(device_args); - flagged_device_args[MPMD_CHDR_REACHABILITY_KEY] = - MPMD_CHDR_REACHABILITY_NEGATIVE; - return flagged_device_args; - } +//! How long we wait for discovery responses (in seconds) +constexpr double MPMD_FIND_TIMEOUT = 0.5; +constexpr char MPMD_CHDR_REACHABILITY_KEY[] = "reachable"; +constexpr char MPMD_CHDR_REACHABILITY_NEGATIVE[] = "No"; +//! The preamble for any response on the discovery port. Can be used to +// verify that the response is actually an MPM device. +constexpr char MPM_DISC_RESPONSE_PREAMBLE[] = "USRP-MPM"; + +device_addr_t flag_dev_as_unreachable(const device_addr_t& device_args) +{ + device_addr_t flagged_device_args(device_args); + flagged_device_args[MPMD_CHDR_REACHABILITY_KEY] = MPMD_CHDR_REACHABILITY_NEGATIVE; + return flagged_device_args; } +} // namespace device_addrs_t mpmd_find_with_addr( - const std::string& mgmt_addr, - const device_addr_t& hint_ -) { + const std::string& mgmt_addr, const device_addr_t& hint_) +{ UHD_ASSERT_THROW(not mgmt_addr.empty()); const std::string mpm_discovery_port = hint_.get( - mpmd_impl::MPM_DISCOVERY_PORT_KEY, - std::to_string(mpmd_impl::MPM_DISCOVERY_PORT) - ); - UHD_LOG_DEBUG("MPMD", - "Discovering MPM devices on port " << mpm_discovery_port); + mpmd_impl::MPM_DISCOVERY_PORT_KEY, std::to_string(mpmd_impl::MPM_DISCOVERY_PORT)); + UHD_LOG_DEBUG("MPMD", "Discovering MPM devices on port " << mpm_discovery_port); device_addrs_t addrs; - transport::udp_simple::sptr comm = transport::udp_simple::make_broadcast( - mgmt_addr, mpm_discovery_port); - comm->send( - boost::asio::buffer( - mpmd_impl::MPM_DISCOVERY_CMD.c_str(), - mpmd_impl::MPM_DISCOVERY_CMD.size() - ) - ); + transport::udp_simple::sptr comm = + transport::udp_simple::make_broadcast(mgmt_addr, mpm_discovery_port); + comm->send(boost::asio::buffer( + mpmd_impl::MPM_DISCOVERY_CMD.c_str(), mpmd_impl::MPM_DISCOVERY_CMD.size())); while (true) { const size_t MAX_MTU = 8000; - char buff[MAX_MTU] = {}; - const size_t nbytes = comm->recv( - boost::asio::buffer(buff, MAX_MTU), - MPMD_FIND_TIMEOUT - ); + char buff[MAX_MTU] = {}; + const size_t nbytes = + comm->recv(boost::asio::buffer(buff, MAX_MTU), MPMD_FIND_TIMEOUT); if (nbytes == 0) { break; } - const char* reply = (const char*)buff; + const char* reply = (const char*)buff; std::string reply_string = std::string(reply); std::vector<std::string> result; - boost::algorithm::split(result, reply_string, - [](const char& in) { return in == ';'; }, - boost::token_compress_on); + boost::algorithm::split(result, + reply_string, + [](const char& in) { return in == ';'; }, + boost::token_compress_on); if (result.empty()) { continue; } @@ -86,9 +76,8 @@ device_addrs_t mpmd_find_with_addr( // remove external iface addrs if executed directly on device bool external_iface = false; for (const auto& addr : transport::get_if_addrs()) { - if ((addr.inet == comm->get_recv_addr()) && - recv_addr != - boost::asio::ip::address_v4::loopback().to_string()) { + if ((addr.inet == comm->get_recv_addr()) + && recv_addr != boost::asio::ip::address_v4::loopback().to_string()) { external_iface = true; break; } @@ -100,41 +89,40 @@ device_addrs_t mpmd_find_with_addr( // Create result to return device_addr_t new_addr; new_addr[xport::MGMT_ADDR_KEY] = recv_addr; - new_addr["type"] = "mpmd"; // hwd will overwrite this + new_addr["type"] = "mpmd"; // hwd will overwrite this // remove ident string and put other informations into device_args dict result.erase(result.begin()); // parse key-value pairs in the discovery string and add them to the // device_args for (const auto& el : result) { std::vector<std::string> value; - boost::algorithm::split(value, el, - [](const char& in) { return in == '='; }, - boost::token_compress_on); + boost::algorithm::split(value, + el, + [](const char& in) { return in == '='; }, + boost::token_compress_on); if (value[0] != xport::MGMT_ADDR_KEY) { new_addr[value[0]] = value[1]; } } // filter the discovered device below by matching optional keys - if ( - (not hint_.has_key("name") or hint_["name"] == new_addr["name"]) - and (not hint_.has_key("serial") or hint_["serial"] == new_addr["serial"]) - and (not hint_.has_key("type") or hint_["type"] == new_addr["type"] or hint_["type"] == MPM_CATCHALL_DEVICE_TYPE) - and (not hint_.has_key("product") or hint_["product"] == new_addr["product"]) - ){ - UHD_LOG_TRACE("MPMD FIND", - "Found device that matches hints: " << new_addr.to_string()); + if ((not hint_.has_key("name") or hint_["name"] == new_addr["name"]) + and (not hint_.has_key("serial") or hint_["serial"] == new_addr["serial"]) + and (not hint_.has_key("type") or hint_["type"] == new_addr["type"] + or hint_["type"] == MPM_CATCHALL_DEVICE_TYPE) + and (not hint_.has_key("product") + or hint_["product"] == new_addr["product"])) { + UHD_LOG_TRACE( + "MPMD FIND", "Found device that matches hints: " << new_addr.to_string()); addrs.push_back(new_addr); } else { - UHD_LOG_DEBUG("MPMD FIND", - "Found device, but does not match hint: " << recv_addr - ); + UHD_LOG_DEBUG( + "MPMD FIND", "Found device, but does not match hint: " << recv_addr); } } return addrs; }; - // Implements scenario 1) (see below) device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) { @@ -142,10 +130,9 @@ device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) device_addrs_t found_devices; found_devices.reserve(hints.size()); for (const auto& hint : hints) { - if (not (hint.has_key(xport::FIRST_ADDR_KEY) or - hint.has_key(xport::MGMT_ADDR_KEY))) { - UHD_LOG_DEBUG("MPMD FIND", - "No address given in hint " << hint.to_string()); + if (not(hint.has_key(xport::FIRST_ADDR_KEY) + or hint.has_key(xport::MGMT_ADDR_KEY))) { + UHD_LOG_DEBUG("MPMD FIND", "No address given in hint " << hint.to_string()); continue; } const std::string mgmt_addr = @@ -154,13 +141,12 @@ device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) if (reply_addrs.size() > 1) { UHD_LOG_ERROR("MPMD", "Could not resolve device hint \"" << hint.to_string() - << "\" to a unique device."); + << "\" to a unique device."); continue; } else if (reply_addrs.empty()) { continue; } - UHD_LOG_TRACE("MPMD FIND", - "Device responded: " << reply_addrs[0].to_string()); + UHD_LOG_TRACE("MPMD FIND", "Device responded: " << reply_addrs[0].to_string()); found_devices.push_back(reply_addrs[0]); } if (found_devices.size() == 0) { @@ -175,17 +161,14 @@ device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) device_addrs_t mpmd_find_with_bcast(const device_addr_t& hint) { device_addrs_t addrs; - UHD_LOG_TRACE("MPMD FIND", - "Broadcasting on all available interfaces to find MPM devices."); + UHD_LOG_TRACE( + "MPMD FIND", "Broadcasting on all available interfaces to find MPM devices."); std::vector<std::future<device_addrs_t>> task_list; for (const auto& if_addr : transport::get_if_addrs()) { task_list.emplace_back(std::async(std::launch::async, - [if_addr, hint](){ - return mpmd_find_with_addr(if_addr.bcast, hint); - } - )); + [if_addr, hint]() { return mpmd_find_with_addr(if_addr.bcast, hint); })); } - for (auto &task : task_list) { + for (auto& task : task_list) { auto reply_addrs = task.get(); addrs.insert(addrs.begin(), reply_addrs.begin(), reply_addrs.end()); } @@ -212,21 +195,19 @@ device_addrs_t mpmd_find(const device_addr_t& hint_) { device_addrs_t hints = separate_device_addr(hint_); if (hint_.has_key("type")) { - if (std::find(MPM_DEVICE_TYPES.cbegin(), - MPM_DEVICE_TYPES.cend(), - hint_["type"]) == MPM_DEVICE_TYPES.cend()) { - UHD_LOG_TRACE("MPMD FIND", - "Returning early, type does not match an MPM device."); + if (std::find(MPM_DEVICE_TYPES.cbegin(), MPM_DEVICE_TYPES.cend(), hint_["type"]) + == MPM_DEVICE_TYPES.cend()) { + UHD_LOG_TRACE( + "MPMD FIND", "Returning early, type does not match an MPM device."); return {}; } } - UHD_LOG_TRACE("MPMD FIND", - "Finding with " << hints.size() << " different hint(s)."); + UHD_LOG_TRACE("MPMD FIND", "Finding with " << hints.size() << " different hint(s)."); // Scenario 1): User gave us at least one address - if (not hints.empty() and - (hints[0].has_key(xport::FIRST_ADDR_KEY) or - hints[0].has_key(xport::MGMT_ADDR_KEY))) { + if (not hints.empty() + and (hints[0].has_key(xport::FIRST_ADDR_KEY) + or hints[0].has_key(xport::MGMT_ADDR_KEY))) { // Note: We don't try and connect to the devices in this mode, because // we only get here if the user specified addresses, and we assume she // knows what she's doing. @@ -238,33 +219,31 @@ device_addrs_t mpmd_find(const device_addr_t& hint_) hints.resize(1); } const auto bcast_mpm_devs = mpmd_find_with_bcast(hints[0]); - UHD_LOG_TRACE("MPMD FIND", - "Found " << bcast_mpm_devs.size() << " device via broadcast."); + UHD_LOG_TRACE( + "MPMD FIND", "Found " << bcast_mpm_devs.size() << " device via broadcast."); const bool find_all = hint_.has_key(mpmd_impl::MPM_FINDALL_KEY); if (find_all) { UHD_LOG_TRACE("MPMD FIND", - "User provided " << mpmd_impl::MPM_FINDALL_KEY << ", will not " - "check devices for CHDR accessibility."); + "User provided " << mpmd_impl::MPM_FINDALL_KEY + << ", will not " + "check devices for CHDR accessibility."); } // Filter found devices for those that we can actually talk to via CHDR device_addrs_t filtered_mpm_devs; - for (const auto &mpm_dev : bcast_mpm_devs) { - const auto reachable_device_addr = - mpmd_mboard_impl::is_device_reachable(mpm_dev); + for (const auto& mpm_dev : bcast_mpm_devs) { + const auto reachable_device_addr = mpmd_mboard_impl::is_device_reachable(mpm_dev); if (bool(reachable_device_addr)) { filtered_mpm_devs.push_back(reachable_device_addr.get()); } else if (find_all) { - filtered_mpm_devs.emplace_back( - flag_dev_as_unreachable(mpm_dev) - ); + filtered_mpm_devs.emplace_back(flag_dev_as_unreachable(mpm_dev)); } } if (filtered_mpm_devs.empty() and not bcast_mpm_devs.empty()) { UHD_LOG_INFO("MPMD FIND", "Found MPM devices, but none are reachable for a UHD session. " - "Specify " << mpmd_impl::MPM_FINDALL_KEY << " to find all devices." - ); + "Specify " + << mpmd_impl::MPM_FINDALL_KEY << " to find all devices."); } return filtered_mpm_devs; diff --git a/host/lib/usrp/mpmd/mpmd_image_loader.cpp b/host/lib/usrp/mpmd/mpmd_image_loader.cpp index e0b85f897..7553b1df4 100644 --- a/host/lib/usrp/mpmd/mpmd_image_loader.cpp +++ b/host/lib/usrp/mpmd/mpmd_image_loader.cpp @@ -7,66 +7,68 @@ #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/image_loader.hpp> #include <uhd/types/component_file.hpp> +#include <uhd/types/eeprom.hpp> #include <uhd/utils/paths.hpp> #include <boost/algorithm/string.hpp> #include <boost/filesystem/convenience.hpp> -#include <sstream> -#include <string> #include <fstream> #include <iterator> +#include <sstream> #include <streambuf> +#include <string> using namespace uhd; -namespace uhd{ namespace /*anon*/{ - const size_t MD5LEN = 32; // Length of a MD5 hash in chars +namespace uhd { namespace /*anon*/ { +const size_t MD5LEN = 32; // Length of a MD5 hash in chars /* * Helper function to generate a component_file_t using the input ID and path to file. */ uhd::usrp::component_file_t generate_component( - const std::string& id, - const std::string& filepath -) { + const std::string& id, const std::string& filepath) +{ uhd::usrp::component_file_t component_file; // Add an ID to the metadata component_file.metadata["id"] = id; - UHD_LOG_TRACE("MPMD IMAGE LOADER", - "Component ID added to the component dictionary: " << id); + UHD_LOG_TRACE( + "MPMD IMAGE LOADER", "Component ID added to the component dictionary: " << id); // Add the filename to the metadata // Remove the path to the filename - component_file.metadata["filename"] = boost::filesystem::path(filepath).filename().string(); + component_file.metadata["filename"] = + boost::filesystem::path(filepath).filename().string(); UHD_LOG_TRACE("MPMD IMAGE LOADER", - "Component filename added to the component dictionary: " << filepath); + "Component filename added to the component dictionary: " << filepath); // Add the hash, if a hash file exists const std::string component_hash_filepath = filepath + ".md5"; - std::ifstream component_hash_ifstream(component_hash_filepath.c_str(), std::ios::binary); + std::ifstream component_hash_ifstream( + component_hash_filepath.c_str(), std::ios::binary); std::string component_hash; if (component_hash_ifstream.is_open()) { // TODO: Verify that the hash read is valid, ie only contains 0-9a-f. component_hash.resize(MD5LEN); - component_hash_ifstream.read( &component_hash[0], MD5LEN ); + component_hash_ifstream.read(&component_hash[0], MD5LEN); component_hash_ifstream.close(); component_file.metadata["md5"] = component_hash; UHD_LOG_TRACE("MPMD IMAGE LOADER", - "Added component file hash to the component dictionary."); + "Added component file hash to the component dictionary."); } else { // If there is no hash file, don't worry about it too much - UHD_LOG_DEBUG("MPMD IMAGE LOADER", "Could not open component file hash file: " - << component_hash_filepath); + UHD_LOG_DEBUG("MPMD IMAGE LOADER", + "Could not open component file hash file: " << component_hash_filepath); } - // Read the component file image into a structure suitable to sent as a binary string to MPM + // Read the component file image into a structure suitable to sent as a binary string + // to MPM std::vector<uint8_t> data; std::ifstream component_ifstream(filepath.c_str(), std::ios::binary); if (component_ifstream.is_open()) { - data.insert( data.begin(), - std::istreambuf_iterator<char>(component_ifstream), - std::istreambuf_iterator<char>()); + data.insert(data.begin(), + std::istreambuf_iterator<char>(component_ifstream), + std::istreambuf_iterator<char>()); component_ifstream.close(); } else { const std::string err_msg("Component file does not exist: " + filepath); @@ -79,7 +81,8 @@ uhd::usrp::component_file_t generate_component( /* * Function to be registered with uhd_image_loader */ -static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loader_args){ +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_addr_t find_hint = image_loader_args.args; find_hint.set("find_all", "1"); // We need to find all devices @@ -94,7 +97,7 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa 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::device::sptr usrp = uhd::device::make(dev_addr, uhd::device::USRP); uhd::property_tree::sptr tree = usrp->get_tree(); // Generate the component files @@ -107,44 +110,44 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa 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 - )); + 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. - */ + * 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 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? + // 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") or fpga_type == ""){ + if (!dev_addr.has_key("product") or fpga_type == "") { throw uhd::runtime_error( - "Found a device but could not auto-generate an image filename."); - } - else { + "Found a device but could not auto-generate an image filename."); + } else { return find_image_path( str(boost::format("usrp_%s_fpga_%s.bit") % (boost::algorithm::to_lower_copy(dev_addr["product"])) @@ -157,9 +160,11 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa 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(); + 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); + 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"; @@ -176,20 +181,24 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa // Call RPC to update the component UHD_LOG_INFO("MPMD IMAGE LOADER", "Starting update. This may take a while."); - tree->access<uhd::usrp::component_files_t>("/mboards/0/components/fpga").set(all_component_files); + tree->access<uhd::usrp::component_files_t>("/mboards/0/components/fpga") + .set(all_component_files); UHD_LOG_INFO("MPMD IMAGE LOADER", "Update component function succeeded."); return true; } -}} //namespace uhd::/*anon*/ +}} // namespace uhd:: -UHD_STATIC_BLOCK(register_mpm_image_loader){ +UHD_STATIC_BLOCK(register_mpm_image_loader) +{ // TODO: Update recovery instructions - const std::string recovery_instructions = "Aborting. Your USRP MPM-enabled device's update may or may not have\n" - "completed. The contents of the image files may have been corrupted.\n" - "Please verify those files as soon as possible."; + const std::string recovery_instructions = + "Aborting. Your USRP MPM-enabled device's update may or may not have\n" + "completed. The contents of the image files may have been corrupted.\n" + "Please verify those files as soon as possible."; - //TODO: 'n3xx' doesn't really fit the MPM abstraction, but this is simpler for the time being + // 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); image_loader::register_image_loader("e3xx", mpmd_image_loader, recovery_instructions); } diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp index 87e911e17..b8ce6cabd 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_impl.cpp @@ -5,189 +5,166 @@ // #include "mpmd_impl.hpp" -#include <../device3/device3_impl.hpp> #include <uhd/exception.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/tasks.hpp> -#include <uhd/types/sensors.hpp> -#include <uhd/types/eeprom.hpp> #include <uhd/types/component_file.hpp> +#include <uhd/types/eeprom.hpp> +#include <uhd/types/sensors.hpp> #include <uhd/usrp/mboard_eeprom.hpp> -#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> +#include <uhd/utils/static.hpp> +#include <uhd/utils/tasks.hpp> #include <uhdlib/rfnoc/radio_ctrl_impl.hpp> +#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> +#include <../device3/device3_impl.hpp> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <boost/make_shared.hpp> #include <boost/thread.hpp> +#include <future> #include <memory> #include <mutex> #include <random> #include <string> -#include <vector> -#include <future> #include <thread> +#include <vector> using namespace uhd; using namespace uhd::mpmd; namespace { - /************************************************************************* - * Local constants - ************************************************************************/ - const size_t MPMD_CROSSBAR_MAX_LADDR = 255; - //! Most pessimistic time for a CHDR query to go to device and back - const double MPMD_CHDR_MAX_RTT = 0.02; - //! MPM Compatibility number - const std::vector<size_t> MPM_COMPAT_NUM = {1, 2}; +/************************************************************************* + * Local constants + ************************************************************************/ +const size_t MPMD_CROSSBAR_MAX_LADDR = 255; +//! Most pessimistic time for a CHDR query to go to device and back +const double MPMD_CHDR_MAX_RTT = 0.02; +//! MPM Compatibility number +const std::vector<size_t> MPM_COMPAT_NUM = {1, 2}; - /************************************************************************* - * Helper functions - ************************************************************************/ - void reset_time_synchronized(uhd::property_tree::sptr tree) - { - const size_t n_mboards = tree->list("/mboards").size(); - UHD_LOGGER_DEBUG("MPMD") - << "Synchronizing " << n_mboards <<" timekeepers..."; - auto get_time_last_pps = [tree](){ - return tree->access<time_spec_t>( - fs_path("/mboards/0/time/pps") - ).get(); - }; - auto end_time = std::chrono::steady_clock::now() - + std::chrono::milliseconds(1100); - auto time_last_pps = get_time_last_pps(); - UHD_LOG_DEBUG("MPMD", "Waiting for PPS clock edge..."); - while (time_last_pps == get_time_last_pps()) - { - if (std::chrono::steady_clock::now() > end_time) { - throw uhd::runtime_error( - "Board 0 may not be getting a PPS signal!\n" - "No PPS detected within the time interval.\n" - "See the application notes for your device.\n" - ); - } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - UHD_LOG_DEBUG("MPMD", "Setting all timekeepers to 0..."); - for (size_t mboard_idx = 0; mboard_idx < n_mboards; mboard_idx++) { - tree->access<time_spec_t>( - fs_path("/mboards") / mboard_idx / "time" / "pps" - ).set(time_spec_t(0.0)); +/************************************************************************* + * Helper functions + ************************************************************************/ +void reset_time_synchronized(uhd::property_tree::sptr tree) +{ + const size_t n_mboards = tree->list("/mboards").size(); + UHD_LOGGER_DEBUG("MPMD") << "Synchronizing " << n_mboards << " timekeepers..."; + auto get_time_last_pps = [tree]() { + return tree->access<time_spec_t>(fs_path("/mboards/0/time/pps")).get(); + }; + auto end_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(1100); + auto time_last_pps = get_time_last_pps(); + UHD_LOG_DEBUG("MPMD", "Waiting for PPS clock edge..."); + while (time_last_pps == get_time_last_pps()) { + if (std::chrono::steady_clock::now() > end_time) { + throw uhd::runtime_error("Board 0 may not be getting a PPS signal!\n" + "No PPS detected within the time interval.\n" + "See the application notes for your device.\n"); } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + UHD_LOG_DEBUG("MPMD", "Setting all timekeepers to 0..."); + for (size_t mboard_idx = 0; mboard_idx < n_mboards; mboard_idx++) { + tree->access<time_spec_t>(fs_path("/mboards") / mboard_idx / "time" / "pps") + .set(time_spec_t(0.0)); + } - UHD_LOG_DEBUG("MPMD", "Waiting for next PPS edge..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); + UHD_LOG_DEBUG("MPMD", "Waiting for next PPS edge..."); + std::this_thread::sleep_for(std::chrono::seconds(1)); - UHD_LOG_DEBUG("MPMD", "Verifying all timekeepers are aligned..."); - auto get_time_now = [tree](const size_t mb_index){ - return tree->access<time_spec_t>( - fs_path("/mboards") / mb_index / "time/now" - ).get(); - }; - for (size_t m = 1; m < n_mboards; m++){ - time_spec_t time_0 = get_time_now(0); - time_spec_t time_i = get_time_now(m); - if (time_i < time_0 - or (time_i - time_0) > time_spec_t(MPMD_CHDR_MAX_RTT)) { - UHD_LOGGER_WARNING("MULTI_USRP") << boost::format( - "Detected time deviation between board %d and board 0.\n" - "Board 0 time is %f seconds.\n" - "Board %d time is %f seconds.\n" - ) % m % time_0.get_real_secs() % m % time_i.get_real_secs(); - } + UHD_LOG_DEBUG("MPMD", "Verifying all timekeepers are aligned..."); + auto get_time_now = [tree](const size_t mb_index) { + return tree->access<time_spec_t>(fs_path("/mboards") / mb_index / "time/now") + .get(); + }; + for (size_t m = 1; m < n_mboards; m++) { + time_spec_t time_0 = get_time_now(0); + time_spec_t time_i = get_time_now(m); + if (time_i < time_0 or (time_i - time_0) > time_spec_t(MPMD_CHDR_MAX_RTT)) { + UHD_LOGGER_WARNING("MULTI_USRP") + << boost::format("Detected time deviation between board %d and board 0.\n" + "Board 0 time is %f seconds.\n" + "Board %d time is %f seconds.\n") + % m % time_0.get_real_secs() % m % time_i.get_real_secs(); } } +} - /*! Throw an exception if compat numbers don't match. - * - * \param component Name of the component for which we're checking the - * compat number (for logging and exceptions strings). - * \param expected Tuple of 2 integers representing MAJOR.MINOR compat - * number. - * \param actual Tuple of 2 integers representing MAJOR.MINOR compat - * number. - * \param advice_on_failure A string that is appended to the error message - * when compat number mismatches have occurred. - */ - void assert_compat_number_throw( - const std::string &component, - const std::vector<size_t> &expected, - const std::vector<size_t> &actual, - const std::string& advice_on_failure="" - ) { - UHD_ASSERT_THROW(expected.size() == 2); - UHD_ASSERT_THROW(actual.size() == 2); - UHD_LOGGER_TRACE("MPMD") - << "Checking " << component << " compat number. Expected: " - << expected[0] << "." << expected[1] - << " Actual: " - << actual[0] << "." << actual[1] - ; +/*! Throw an exception if compat numbers don't match. + * + * \param component Name of the component for which we're checking the + * compat number (for logging and exceptions strings). + * \param expected Tuple of 2 integers representing MAJOR.MINOR compat + * number. + * \param actual Tuple of 2 integers representing MAJOR.MINOR compat + * number. + * \param advice_on_failure A string that is appended to the error message + * when compat number mismatches have occurred. + */ +void assert_compat_number_throw(const std::string& component, + const std::vector<size_t>& expected, + const std::vector<size_t>& actual, + const std::string& advice_on_failure = "") +{ + UHD_ASSERT_THROW(expected.size() == 2); + UHD_ASSERT_THROW(actual.size() == 2); + UHD_LOGGER_TRACE("MPMD") << "Checking " << component + << " compat number. Expected: " << expected[0] << "." + << expected[1] << " Actual: " << actual[0] << "." + << actual[1]; - if (actual[0] != expected[0]) { - const std::string err_msg = - str(boost::format("%s major compat number mismatch. " - "Expected: %i.%i Actual: %i.%i.%s%s") - % component - % expected[0] % expected[1] - % actual[0] % actual[1] - % (advice_on_failure.empty() ? "" : " ") - % advice_on_failure); - UHD_LOG_ERROR("MPMD", err_msg); - throw uhd::runtime_error(err_msg); - } - if (actual[1] < expected[1]) { - const std::string err_msg = - str(boost::format("%s minor compat number mismatch. " - "Expected: %i.%i Actual: %i.%i.%s%s") - % component - % expected[0] % expected[1] - % actual[0] % actual[1] - % (advice_on_failure.empty() ? "" : " ") - % advice_on_failure); - UHD_LOG_ERROR("MPMD", err_msg); - throw uhd::runtime_error(err_msg); - } - if (actual[1] > expected[1]) { - const std::string err_msg = - str(boost::format("%s minor compat number mismatch. " - "Expected: %i.%i Actual: %i.%i") - % component - % expected[0] % expected[1] - % actual[0] % actual[1]); - UHD_LOG_WARNING("MPMD", err_msg); - } + if (actual[0] != expected[0]) { + const std::string err_msg = + str(boost::format("%s major compat number mismatch. " + "Expected: %i.%i Actual: %i.%i.%s%s") + % component % expected[0] % expected[1] % actual[0] % actual[1] + % (advice_on_failure.empty() ? "" : " ") % advice_on_failure); + UHD_LOG_ERROR("MPMD", err_msg); + throw uhd::runtime_error(err_msg); + } + if (actual[1] < expected[1]) { + const std::string err_msg = + str(boost::format("%s minor compat number mismatch. " + "Expected: %i.%i Actual: %i.%i.%s%s") + % component % expected[0] % expected[1] % actual[0] % actual[1] + % (advice_on_failure.empty() ? "" : " ") % advice_on_failure); + UHD_LOG_ERROR("MPMD", err_msg); + throw uhd::runtime_error(err_msg); + } + if (actual[1] > expected[1]) { + const std::string err_msg = + str(boost::format("%s minor compat number mismatch. " + "Expected: %i.%i Actual: %i.%i") + % component % expected[0] % expected[1] % actual[0] % actual[1]); + UHD_LOG_WARNING("MPMD", err_msg); } } +} // namespace /***************************************************************************** * Static class attributes ****************************************************************************/ -const std::string mpmd_impl::MPM_FINDALL_KEY = "find_all"; -const size_t mpmd_impl::MPM_DISCOVERY_PORT = 49600; -const std::string mpmd_impl::MPM_DISCOVERY_PORT_KEY = "discovery_port"; -const size_t mpmd_impl::MPM_RPC_PORT = 49601; -const std::string mpmd_impl::MPM_RPC_PORT_KEY = "rpc_port"; +const std::string mpmd_impl::MPM_FINDALL_KEY = "find_all"; +const size_t mpmd_impl::MPM_DISCOVERY_PORT = 49600; +const std::string mpmd_impl::MPM_DISCOVERY_PORT_KEY = "discovery_port"; +const size_t mpmd_impl::MPM_RPC_PORT = 49601; +const std::string mpmd_impl::MPM_RPC_PORT_KEY = "rpc_port"; const std::string mpmd_impl::MPM_RPC_GET_LAST_ERROR_CMD = "get_last_error"; -const std::string mpmd_impl::MPM_DISCOVERY_CMD = "MPM-DISC"; -const std::string mpmd_impl::MPM_ECHO_CMD = "MPM-ECHO"; +const std::string mpmd_impl::MPM_DISCOVERY_CMD = "MPM-DISC"; +const std::string mpmd_impl::MPM_ECHO_CMD = "MPM-ECHO"; /***************************************************************************** * Structors ****************************************************************************/ mpmd_impl::mpmd_impl(const device_addr_t& device_args) - : usrp::device3_impl() - , _device_args(device_args) + : usrp::device3_impl(), _device_args(device_args) { const device_addrs_t mb_args = separate_device_addr(device_args); - const size_t num_mboards = mb_args.size(); + const size_t num_mboards = mb_args.size(); _mb.reserve(num_mboards); const bool serialize_init = device_args.has_key("serialize_init"); - const bool skip_init = device_args.has_key("skip_init"); - UHD_LOGGER_INFO("MPMD") - << "Initializing " << num_mboards << " device(s) " - << (serialize_init ? "serially " : "in parallel ") - << "with args: " << device_args.to_string(); + const bool skip_init = device_args.has_key("skip_init"); + UHD_LOGGER_INFO("MPMD") << "Initializing " << num_mboards << " device(s) " + << (serialize_init ? "serially " : "in parallel ") + << "with args: " << device_args.to_string(); // First, claim all the devices (so we own them and no one else can claim // them). @@ -202,8 +179,8 @@ mpmd_impl::mpmd_impl(const device_addr_t& device_args) // can run _mb[*]->init() in parallel on all the _mb. // This can *not* be parallelized. std::vector<size_t> base_xport_addr(num_mboards, 2); // Starts at 2 [sic] - for (size_t mb_i = 0; mb_i < num_mboards-1; ++mb_i) { - base_xport_addr[mb_i+1] = base_xport_addr[mb_i] + _mb[mb_i]->num_xbars; + for (size_t mb_i = 0; mb_i < num_mboards - 1; ++mb_i) { + base_xport_addr[mb_i + 1] = base_xport_addr[mb_i] + _mb[mb_i]->num_xbars; } if (not skip_init) { @@ -260,35 +237,28 @@ mpmd_impl::~mpmd_impl() /***************************************************************************** * Private methods ****************************************************************************/ -mpmd_mboard_impl::uptr mpmd_impl::claim_and_make( - const uhd::device_addr_t& device_args -) { +mpmd_mboard_impl::uptr mpmd_impl::claim_and_make(const uhd::device_addr_t& device_args) +{ const std::string rpc_addr = device_args.get(xport::MGMT_ADDR_KEY); - UHD_LOGGER_DEBUG("MPMD") - << "Device args: `" << device_args.to_string() - << "'. RPC address: " << rpc_addr - ; + UHD_LOGGER_DEBUG("MPMD") << "Device args: `" << device_args.to_string() + << "'. RPC address: " << rpc_addr; if (rpc_addr.empty()) { UHD_LOG_ERROR("MPMD", "Could not determine RPC address from device args: " - << device_args.to_string()); + << device_args.to_string()); throw uhd::runtime_error("Could not determine device RPC address."); } return mpmd_mboard_impl::make(device_args, rpc_addr); } void mpmd_impl::setup_mb( - mpmd_mboard_impl *mb, - const size_t mb_index, - const size_t base_xport_addr -) { - assert_compat_number_throw( - "MPM", + mpmd_mboard_impl* mb, const size_t mb_index, const size_t base_xport_addr) +{ + assert_compat_number_throw("MPM", MPM_COMPAT_NUM, mb->rpc->request<std::vector<size_t>>("get_mpm_compat_num"), - "Please update the version of MPM on your USRP device." - ); + "Please update the version of MPM on your USRP device."); UHD_LOG_DEBUG("MPMD", "Initializing mboard " << mb_index); mb->init(); @@ -297,94 +267,83 @@ void mpmd_impl::setup_mb( } } -void mpmd_impl::setup_rfnoc_blocks( - mpmd_mboard_impl* mb, +void mpmd_impl::setup_rfnoc_blocks(mpmd_mboard_impl* mb, const size_t mb_index, - const uhd::device_addr_t& ctrl_xport_args -) { - UHD_LOG_TRACE("MPMD", - "Mboard " << mb_index << " reports " << mb->num_xbars << " crossbar(s)." - ); + const uhd::device_addr_t& ctrl_xport_args) +{ + UHD_LOG_TRACE( + "MPMD", "Mboard " << mb_index << " reports " << mb->num_xbars << " crossbar(s)."); // TODO: The args apply to all xbars, which may or may not be true for (size_t xbar_index = 0; xbar_index < mb->num_xbars; xbar_index++) { // Pull the number of blocks and base port from the args, if available. // Otherwise, get the values from MPM. - const size_t num_blocks = ctrl_xport_args.has_key("rfnoc_num_blocks") - ? ctrl_xport_args.cast<size_t>("rfnoc_num_blocks", 0) - : mb->rpc->request<size_t>("get_num_blocks", xbar_index); - const size_t base_port = ctrl_xport_args.has_key("rfnoc_base_port") - ? ctrl_xport_args.cast<size_t>("rfnoc_base_port", 0) - : mb->rpc->request<size_t>("get_base_port", xbar_index); + const size_t num_blocks = + ctrl_xport_args.has_key("rfnoc_num_blocks") + ? ctrl_xport_args.cast<size_t>("rfnoc_num_blocks", 0) + : mb->rpc->request<size_t>("get_num_blocks", xbar_index); + const size_t base_port = + ctrl_xport_args.has_key("rfnoc_base_port") + ? ctrl_xport_args.cast<size_t>("rfnoc_base_port", 0) + : mb->rpc->request<size_t>("get_base_port", xbar_index); const size_t local_addr = mb->get_xbar_local_addr(xbar_index); UHD_LOGGER_TRACE("MPMD") << "Enumerating RFNoC blocks for xbar " << xbar_index - << ". Total blocks: " << num_blocks - << " Base port: " << base_port - << " Local address: " << local_addr - ; - if (ctrl_xport_args.has_key("rfnoc_num_blocks") or - ctrl_xport_args.has_key("rfnoc_base_port")) { + << ". Total blocks: " << num_blocks << " Base port: " << base_port + << " Local address: " << local_addr; + if (ctrl_xport_args.has_key("rfnoc_num_blocks") + or ctrl_xport_args.has_key("rfnoc_base_port")) { // TODO: Remove this warning once we're confident this is // (relatively) safe and useful. Also add documentation to // usrp_n3xx.dox UHD_LOGGER_WARNING("MPMD") << "Overriding default RFNoC configuration. You are using an " << "experimental development feature, which may go away in " - << "future versions." - ; + << "future versions."; } try { - enumerate_rfnoc_blocks( - mb_index, - num_blocks, - base_port, - uhd::sid_t(0, 0, local_addr, 0), - ctrl_xport_args - ); - } catch (const std::exception &ex) { - UHD_LOGGER_ERROR("MPMD") - << "Failure during block enumeration: " - << ex.what(); + enumerate_rfnoc_blocks(mb_index, + num_blocks, + base_port, + uhd::sid_t(0, 0, local_addr, 0), + ctrl_xport_args); + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("MPMD") << "Failure during block enumeration: " << ex.what(); throw uhd::runtime_error("Failed to run enumerate_rfnoc_blocks()"); } } } void mpmd_impl::setup_rpc_blocks( - const device_addr_t &block_args, - const bool serialize_init -) { + const device_addr_t& block_args, const bool serialize_init) +{ std::vector<std::future<void>> task_list; // If we don't force async, most compilers, at least now, will default to // deferred. - const auto launch_policy = serialize_init ? - std::launch::deferred : - std::launch::async; + const auto launch_policy = serialize_init ? std::launch::deferred + : std::launch::async; // Preload all the tasks (they might start running on emplace_back) - for (const auto &block_ctrl: _rfnoc_block_ctrl) { + for (const auto& block_ctrl : _rfnoc_block_ctrl) { auto rpc_block_id = block_ctrl->get_block_id(); if (has_block<uhd::rfnoc::rpc_block_ctrl>(rpc_block_id)) { const size_t mboard_idx = rpc_block_id.get_device_no(); auto rpc_block_ctrl = get_block_ctrl<uhd::rfnoc::rpc_block_ctrl>(rpc_block_id); auto rpc_sptr = _mb[mboard_idx]->rpc; - task_list.emplace_back(std::async(launch_policy, - [rpc_block_id, rpc_block_ctrl, &block_args, rpc_sptr](){ + task_list.emplace_back(std::async( + launch_policy, [rpc_block_id, rpc_block_ctrl, &block_args, rpc_sptr]() { UHD_LOGGER_DEBUG("MPMD") << "Adding RPC access to block: " << rpc_block_id - << " Block args: " << block_args.to_string() - ; + << " Block args: " << block_args.to_string(); rpc_block_ctrl->set_rpc_client(rpc_sptr, block_args); - } - )); + })); } } // Execute all the calls to set_rpc_client(), either concurrently, or // serially - for (auto &task : task_list) { + for (auto& task : task_list) { task.get(); } } diff --git a/host/lib/usrp/mpmd/mpmd_impl.hpp b/host/lib/usrp/mpmd/mpmd_impl.hpp index e9d942c9d..f3328dc6f 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.hpp +++ b/host/lib/usrp/mpmd/mpmd_impl.hpp @@ -7,14 +7,14 @@ #ifndef INCLUDED_MPMD_IMPL_HPP #define INCLUDED_MPMD_IMPL_HPP -#include "mpmd_xport_mgr.hpp" #include "../device3/device3_impl.hpp" +#include "mpmd_xport_mgr.hpp" +#include <uhd/property_tree.hpp> #include <uhd/stream.hpp> +#include <uhd/transport/muxed_zero_copy_if.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/types/dict.hpp> #include <uhd/utils/tasks.hpp> -#include <uhd/transport/muxed_zero_copy_if.hpp> -#include <uhd/property_tree.hpp> #include <uhdlib/utils/rpc.hpp> #include <boost/optional.hpp> #include <map> @@ -24,16 +24,16 @@ * RPC timeout constants for MPMD ************************************************************************/ //! Time between reclaims (ms) -static constexpr size_t MPMD_RECLAIM_INTERVAL_MS = 1000; +static constexpr size_t MPMD_RECLAIM_INTERVAL_MS = 1000; //! Default timeout value for the init() RPC call (ms) -static constexpr size_t MPMD_DEFAULT_INIT_TIMEOUT = 120000; +static constexpr size_t MPMD_DEFAULT_INIT_TIMEOUT = 120000; //! Default timeout value for RPC calls (ms) -static constexpr size_t MPMD_DEFAULT_RPC_TIMEOUT = 2000; +static constexpr size_t MPMD_DEFAULT_RPC_TIMEOUT = 2000; //! Short timeout value for RPC calls (ms), used for calls that shouldn't // take long. This value can be used to quickly determine a link status. -static constexpr size_t MPMD_SHORT_RPC_TIMEOUT = 2000; +static constexpr size_t MPMD_SHORT_RPC_TIMEOUT = 2000; //! Claimer loop timeout value for RPC calls (ms). -static constexpr size_t MPMD_CLAIMER_RPC_TIMEOUT = 10000; +static constexpr size_t MPMD_CLAIMER_RPC_TIMEOUT = 10000; namespace uhd { namespace mpmd { @@ -41,9 +41,9 @@ namespace uhd { namespace mpmd { */ class mpmd_mboard_impl { - public: +public: /*** Types ***************************************************************/ - using uptr = std::unique_ptr<mpmd_mboard_impl>; + using uptr = std::unique_ptr<mpmd_mboard_impl>; using dev_info = std::map<std::string, std::string>; /*** Static helper *******************************************************/ @@ -53,8 +53,7 @@ class mpmd_mboard_impl * \param device_addr Device args. Must contain an mgmt_addr. */ static boost::optional<device_addr_t> is_device_reachable( - const device_addr_t& device_addr - ); + const device_addr_t& device_addr); /*** Structors ***********************************************************/ /*! Ctor: Claim device or throw an exception on failure. @@ -64,10 +63,7 @@ class mpmd_mboard_impl * \param mb_args Device args that pertain to this motherboard * \param ip_addr RPC client will attempt to connect to this IP address */ - mpmd_mboard_impl( - const uhd::device_addr_t &mb_args, - const std::string& ip_addr - ); + mpmd_mboard_impl(const uhd::device_addr_t& mb_args, const std::string& ip_addr); ~mpmd_mboard_impl(); /*** Factory *************************************************************/ @@ -75,10 +71,7 @@ class mpmd_mboard_impl * \param mb_args Device args that pertain to this motherboard * \param ip_addr RPC client will attempt to connect to this IP address */ - static uptr make( - const uhd::device_addr_t &mb_args, - const std::string& addr - ); + static uptr make(const uhd::device_addr_t& mb_args, const std::string& addr); /*** Init ****************************************************************/ void init(); @@ -112,7 +105,8 @@ class mpmd_mboard_impl void set_xbar_local_addr(const size_t xbar_index, const size_t local_addr); //! Return the local address of a given crossbar - size_t get_xbar_local_addr(const size_t xbar_index) const { + size_t get_xbar_local_addr(const size_t xbar_index) const + { return xbar_local_addrs.at(xbar_index); } @@ -126,11 +120,9 @@ class mpmd_mboard_impl // \param sid The full SID of this transport (UHD to device) // \param xport_type Transport type (CTRL, RX_DATA, ...) // \param args Any kind of args passed in via get_?x_stream() - uhd::both_xports_t make_transport( - const sid_t& sid, + uhd::both_xports_t make_transport(const sid_t& sid, usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& args - ); + const uhd::device_addr_t& args); size_t get_mtu(const uhd::direction_t dir) const; @@ -138,7 +130,7 @@ class mpmd_mboard_impl uhd::device_addr_t get_rx_hints() const; uhd::device_addr_t get_tx_hints() const; - private: +private: /*! Reference to the RPC client that handles claiming */ uhd::rpc_client::sptr _claim_rpc; @@ -152,21 +144,18 @@ class mpmd_mboard_impl */ bool claim(); - /*! Set RPC client timeout value - * - * \param timeout_ms time limit (in ms) that a rpc client waits for a single call - */ - void set_rpcc_timeout( - const uint64_t timeout_ms - ); + /*! Set RPC client timeout value + * + * \param timeout_ms time limit (in ms) that a rpc client waits for a single call + */ + void set_rpcc_timeout(const uint64_t timeout_ms); - uhd::task::sptr claim_device_and_make_task( - ); + uhd::task::sptr claim_device_and_make_task(); /*! Read out the log buffer from the MPM device and send it to native * logging system. */ - void dump_logs(const bool dump_to_null=false); + void dump_logs(const bool dump_to_null = false); /************************************************************************* * Private attributes @@ -224,10 +213,10 @@ public: * API ************************************************************************/ uhd::both_xports_t make_transport(const uhd::sid_t&, - uhd::usrp::device3_impl::xport_type_t, - const uhd::device_addr_t&); + uhd::usrp::device3_impl::xport_type_t, + const uhd::device_addr_t&); - private: +private: uhd::device_addr_t get_rx_hints(size_t mb_index); uhd::device_addr_t get_tx_hints(size_t mb_index); @@ -238,9 +227,7 @@ public: * * Does not initialize the device (see setup_mb() for that). */ - mpmd_mboard_impl::uptr claim_and_make( - const uhd::device_addr_t& dev_args - ); + mpmd_mboard_impl::uptr claim_and_make(const uhd::device_addr_t& dev_args); /*! Initialize a single motherboard * @@ -253,23 +240,15 @@ public: * */ void setup_mb( - mpmd_mboard_impl *mb, - const size_t mb_index, - const size_t base_xport_addr - ); + mpmd_mboard_impl* mb, const size_t mb_index, const size_t base_xport_addr); //! Setup all RFNoC blocks running on mboard \p mb_i void setup_rfnoc_blocks( - mpmd_mboard_impl* mb, - const size_t mb_i, - const uhd::device_addr_t& block_args - ); + mpmd_mboard_impl* mb, const size_t mb_i, const uhd::device_addr_t& block_args); //! Configure all blocks that require access to an RPC client void setup_rpc_blocks( - const uhd::device_addr_t &block_args, - const bool serialize_init - ); + const uhd::device_addr_t& block_args, const bool serialize_init); /*! Return the index of the motherboard given the local address of a * crossbar @@ -283,10 +262,7 @@ public: * \param mb Reference to the actual device */ static void init_property_tree( - uhd::property_tree::sptr tree, - fs_path mb_path, - mpmd_mboard_impl *mb - ); + uhd::property_tree::sptr tree, fs_path mb_path, mpmd_mboard_impl* mb); /************************************************************************* diff --git a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp index a49651f10..261b6f2aa 100644 --- a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp @@ -5,209 +5,166 @@ // #include "mpmd_impl.hpp" -#include <uhd/utils/safe_call.hpp> -#include <uhd/utils/log.hpp> #include <uhd/transport/udp_simple.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/safe_call.hpp> #include <chrono> #include <thread> namespace { - /************************************************************************* - * Local constants - ************************************************************************/ - //! Timeout for pings (seconds). - constexpr double MPMD_PING_TIMEOUT = 0.1; - //! Default session ID (MPM will recognize a session by this name) - const std::string MPMD_DEFAULT_SESSION_ID = "UHD"; - //! Key to initialize a ping/measurement latency test - const std::string MPMD_MEAS_LATENCY_KEY = "measure_rpc_latency"; - //! Duration of a latency measurement test - constexpr size_t MPMD_MEAS_LATENCY_DURATION = 1000; - - using log_buf_t = std::vector<std::map<std::string, std::string>>; - - - /************************************************************************* - * Helper functions - ************************************************************************/ - /*! Return true if we can MPM ping a device via discovery service. - */ - bool is_pingable(const std::string& ip_addr, const std::string& udp_port) - { - auto udp = uhd::transport::udp_simple::make_broadcast( - ip_addr, - udp_port - ); - const std::string send_buf( - uhd::mpmd::mpmd_impl::MPM_ECHO_CMD + " ping" - ); - std::vector<uint8_t> recv_buf; - recv_buf.resize(send_buf.size(), ' '); - udp->send(boost::asio::buffer(send_buf.c_str(), send_buf.size())); - const size_t len = - udp->recv(boost::asio::buffer(recv_buf), MPMD_PING_TIMEOUT); - if (len == 0) { - UHD_LOG_TRACE("MPMD", - "Received no MPM ping, assuming device is unreachable."); - return false; - } - if (len != send_buf.size()) { - UHD_LOG_DEBUG("MPMD", - "Received bad return packet on MPM ping. Assuming endpoint" - " is not a valid MPM device."); - return false; - } - if (std::memcmp( - (void *) &recv_buf[0], - (void *) &send_buf[0], - send_buf.size()) != 0) { - UHD_LOG_DEBUG("MPMD", - "Received invalid return packet on MPM ping. Assuming endpoint" - " is not a valid MPM device."); - return false; - } - return true; +/************************************************************************* + * Local constants + ************************************************************************/ +//! Timeout for pings (seconds). +constexpr double MPMD_PING_TIMEOUT = 0.1; +//! Default session ID (MPM will recognize a session by this name) +const std::string MPMD_DEFAULT_SESSION_ID = "UHD"; +//! Key to initialize a ping/measurement latency test +const std::string MPMD_MEAS_LATENCY_KEY = "measure_rpc_latency"; +//! Duration of a latency measurement test +constexpr size_t MPMD_MEAS_LATENCY_DURATION = 1000; + +using log_buf_t = std::vector<std::map<std::string, std::string>>; + + +/************************************************************************* + * Helper functions + ************************************************************************/ +/*! Return true if we can MPM ping a device via discovery service. + */ +bool is_pingable(const std::string& ip_addr, const std::string& udp_port) +{ + auto udp = uhd::transport::udp_simple::make_broadcast(ip_addr, udp_port); + const std::string send_buf(uhd::mpmd::mpmd_impl::MPM_ECHO_CMD + " ping"); + std::vector<uint8_t> recv_buf; + recv_buf.resize(send_buf.size(), ' '); + udp->send(boost::asio::buffer(send_buf.c_str(), send_buf.size())); + const size_t len = udp->recv(boost::asio::buffer(recv_buf), MPMD_PING_TIMEOUT); + if (len == 0) { + UHD_LOG_TRACE("MPMD", "Received no MPM ping, assuming device is unreachable."); + return false; } - - /*! Call init() on an MPM device. - */ - void init_device( - uhd::rpc_client::sptr rpc, - const uhd::device_addr_t mb_args - ) { - auto init_status = - rpc->request_with_token<std::vector<std::string>>( - MPMD_DEFAULT_INIT_TIMEOUT, "get_init_status"); - if (init_status[0] != "true") { - throw uhd::runtime_error( - std::string("Device is in bad state: ") + init_status[1] - ); - } - - // TODO maybe put this somewhere else? - const std::set<std::string> key_blacklist{ - "serial", "claimed", "type", "rev", "addr" - }; - std::map<std::string, std::string> mpm_device_args; - for (const auto &key : mb_args.keys()) { - if (not key_blacklist.count(key)) { - mpm_device_args[key] = mb_args[key]; - } - } - if (not rpc->request_with_token<bool>(MPMD_DEFAULT_INIT_TIMEOUT, "init", mpm_device_args)) { - throw uhd::runtime_error("Failed to initialize device."); - } + if (len != send_buf.size()) { + UHD_LOG_DEBUG("MPMD", + "Received bad return packet on MPM ping. Assuming endpoint" + " is not a valid MPM device."); + return false; + } + if (std::memcmp((void*)&recv_buf[0], (void*)&send_buf[0], send_buf.size()) != 0) { + UHD_LOG_DEBUG("MPMD", + "Received invalid return packet on MPM ping. Assuming endpoint" + " is not a valid MPM device."); + return false; } + return true; +} - void measure_rpc_latency( - uhd::rpc_client::sptr rpc, - const size_t duration_ms=MPMD_MEAS_LATENCY_DURATION - ) { - const double alpha = 0.99; - const std::string payload = "1234567890"; - auto measure_once = [payload, rpc](){ - const auto start = std::chrono::steady_clock::now(); - rpc->request<std::string>("ping", payload); - return (double) std::chrono::duration_cast<std::chrono::microseconds>( - std::chrono::steady_clock::now() - start - ).count(); - }; +/*! Call init() on an MPM device. + */ +void init_device(uhd::rpc_client::sptr rpc, const uhd::device_addr_t mb_args) +{ + auto init_status = rpc->request_with_token<std::vector<std::string>>( + MPMD_DEFAULT_INIT_TIMEOUT, "get_init_status"); + if (init_status[0] != "true") { + throw uhd::runtime_error( + std::string("Device is in bad state: ") + init_status[1]); + } - double max_latency = measure_once(); - double avg_latency = max_latency; - - auto end_time = std::chrono::steady_clock::now() - + std::chrono::milliseconds(duration_ms); - size_t ctr = 1; - while (std::chrono::steady_clock::now() < end_time) { - const auto duration = measure_once(); - max_latency = std::max(max_latency, duration); - avg_latency = avg_latency * alpha + (1-alpha) * duration; - ctr++; - // Light throttle: - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + // TODO maybe put this somewhere else? + const std::set<std::string> key_blacklist{"serial", "claimed", "type", "rev", "addr"}; + std::map<std::string, std::string> mpm_device_args; + for (const auto& key : mb_args.keys()) { + if (not key_blacklist.count(key)) { + mpm_device_args[key] = mb_args[key]; } - - UHD_LOG_INFO("MPMD", - "RPC latency (coarse estimate): Avg = " << avg_latency << " us, " - "Max = " << max_latency - << ", n = " << ctr); } + if (not rpc->request_with_token<bool>( + MPMD_DEFAULT_INIT_TIMEOUT, "init", mpm_device_args)) { + throw uhd::runtime_error("Failed to initialize device."); + } +} - /*! Forward entries from a list of dictionaries to UHD's native logging - * system. - */ - void forward_logs(log_buf_t&& log_buf) - { - for (const auto &log_record : log_buf) { - if (log_record.count("levelname") == 0 or \ - log_record.count("message") == 0) { - UHD_LOG_ERROR("MPMD", - "Invalid logging structure returned from MPM device!"); - continue; - } - if (log_record.at("levelname") == "TRACE") { - UHD_LOG_TRACE( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "DEBUG") { - UHD_LOG_DEBUG( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "INFO") { - UHD_LOG_INFO( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "WARNING") { - UHD_LOG_WARNING( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "ERROR") { - UHD_LOG_ERROR( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "CRITICAL") { - UHD_LOG_FATAL( - log_record.at("name"), - log_record.at("message") - ); - } else { - UHD_LOG_ERROR("MPMD", - "Invalid log level returned from MPM device: " - "`" << log_record.at("levelname") << "'"); - } - } +void measure_rpc_latency( + uhd::rpc_client::sptr rpc, const size_t duration_ms = MPMD_MEAS_LATENCY_DURATION) +{ + const double alpha = 0.99; + const std::string payload = "1234567890"; + auto measure_once = [payload, rpc]() { + const auto start = std::chrono::steady_clock::now(); + rpc->request<std::string>("ping", payload); + return (double)std::chrono::duration_cast<std::chrono::microseconds>( + std::chrono::steady_clock::now() - start) + .count(); + }; + + double max_latency = measure_once(); + double avg_latency = max_latency; + + auto end_time = + std::chrono::steady_clock::now() + std::chrono::milliseconds(duration_ms); + size_t ctr = 1; + while (std::chrono::steady_clock::now() < end_time) { + const auto duration = measure_once(); + max_latency = std::max(max_latency, duration); + avg_latency = avg_latency * alpha + (1 - alpha) * duration; + ctr++; + // Light throttle: + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - /*! Return a new rpc_client with given addr and mb args - */ - uhd::rpc_client::sptr make_mpm_rpc_client( - const std::string& rpc_server_addr, - const uhd::device_addr_t& mb_args, - const size_t timeout_ms = MPMD_DEFAULT_RPC_TIMEOUT - ){ - return uhd::rpc_client::make( - rpc_server_addr, - mb_args.cast<size_t>( - uhd::mpmd::mpmd_impl::MPM_RPC_PORT_KEY, - uhd::mpmd::mpmd_impl::MPM_RPC_PORT - ), - timeout_ms, - uhd::mpmd::mpmd_impl::MPM_RPC_GET_LAST_ERROR_CMD); + UHD_LOG_INFO("MPMD", + "RPC latency (coarse estimate): Avg = " << avg_latency + << " us, " + "Max = " + << max_latency << ", n = " << ctr); +} + +/*! Forward entries from a list of dictionaries to UHD's native logging + * system. + */ +void forward_logs(log_buf_t&& log_buf) +{ + for (const auto& log_record : log_buf) { + if (log_record.count("levelname") == 0 or log_record.count("message") == 0) { + UHD_LOG_ERROR("MPMD", "Invalid logging structure returned from MPM device!"); + continue; + } + if (log_record.at("levelname") == "TRACE") { + UHD_LOG_TRACE(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "DEBUG") { + UHD_LOG_DEBUG(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "INFO") { + UHD_LOG_INFO(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "WARNING") { + UHD_LOG_WARNING(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "ERROR") { + UHD_LOG_ERROR(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "CRITICAL") { + UHD_LOG_FATAL(log_record.at("name"), log_record.at("message")); + } else { + UHD_LOG_ERROR("MPMD", + "Invalid log level returned from MPM device: " + "`" << log_record.at("levelname") + << "'"); + } } +} +/*! Return a new rpc_client with given addr and mb args + */ +uhd::rpc_client::sptr make_mpm_rpc_client(const std::string& rpc_server_addr, + const uhd::device_addr_t& mb_args, + const size_t timeout_ms = MPMD_DEFAULT_RPC_TIMEOUT) +{ + return uhd::rpc_client::make(rpc_server_addr, + mb_args.cast<size_t>( + uhd::mpmd::mpmd_impl::MPM_RPC_PORT_KEY, uhd::mpmd::mpmd_impl::MPM_RPC_PORT), + timeout_ms, + uhd::mpmd::mpmd_impl::MPM_RPC_GET_LAST_ERROR_CMD); } +} // namespace + using namespace uhd; using namespace uhd::mpmd; @@ -215,22 +172,20 @@ using namespace uhd::mpmd; * Static Helpers *****************************************************************************/ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( - const device_addr_t &device_addr -) { - UHD_LOG_TRACE("MPMD", - "Checking accessibility of device `" << device_addr.to_string() - << "'"); + const device_addr_t& device_addr) +{ + UHD_LOG_TRACE( + "MPMD", "Checking accessibility of device `" << device_addr.to_string() << "'"); UHD_ASSERT_THROW(device_addr.has_key(xport::MGMT_ADDR_KEY)); const std::string rpc_addr = device_addr.get(xport::MGMT_ADDR_KEY); - const size_t rpc_port = device_addr.cast<size_t>( - mpmd_impl::MPM_RPC_PORT_KEY, - mpmd_impl::MPM_RPC_PORT - ); + const size_t rpc_port = + device_addr.cast<size_t>(mpmd_impl::MPM_RPC_PORT_KEY, mpmd_impl::MPM_RPC_PORT); auto rpcc = uhd::rpc_client::make(rpc_addr, rpc_port); // 1) Read back device info dev_info device_info_dict; try { - device_info_dict = rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); + device_info_dict = + rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); } catch (const uhd::runtime_error& e) { UHD_LOG_ERROR("MPMD", e.what()); } catch (...) { @@ -240,8 +195,8 @@ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( return boost::optional<device_addr_t>(); } // 2) Check for local device - if (device_info_dict.count("connection") and - device_info_dict.at("connection") == "local") { + if (device_info_dict.count("connection") + and device_info_dict.at("connection") == "local") { UHD_LOG_TRACE("MPMD", "Device is local, flagging as reachable."); return boost::optional<device_addr_t>(device_addr); } @@ -254,46 +209,43 @@ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( continue; } const std::string chdr_addr = device_info_dict.at(addr_key); - UHD_LOG_TRACE("MPMD", - "Checking reachability via network addr " << chdr_addr); + UHD_LOG_TRACE("MPMD", "Checking reachability via network addr " << chdr_addr); try { // First do an MPM ping -- there is some issue with rpclib that can // lead to indefinite timeouts - const std::string mpm_discovery_port = device_addr.get( - mpmd_impl::MPM_DISCOVERY_PORT_KEY, - std::to_string(mpmd_impl::MPM_DISCOVERY_PORT) - ); + const std::string mpm_discovery_port = + device_addr.get(mpmd_impl::MPM_DISCOVERY_PORT_KEY, + std::to_string(mpmd_impl::MPM_DISCOVERY_PORT)); if (!is_pingable(chdr_addr, mpm_discovery_port)) { - UHD_LOG_TRACE("MPMD", - "Cannot MPM ping, assuming device is unreachable."); + UHD_LOG_TRACE("MPMD", "Cannot MPM ping, assuming device is unreachable."); continue; } - UHD_LOG_TRACE("MPMD", - "Was able to ping device, trying RPC connection."); + UHD_LOG_TRACE("MPMD", "Was able to ping device, trying RPC connection."); auto chdr_rpcc = uhd::rpc_client::make(chdr_addr, rpc_port); - auto dev_info_chdr = chdr_rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); + auto dev_info_chdr = + chdr_rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); if (dev_info_chdr["serial"] != device_info_dict["serial"]) { - UHD_LOG_DEBUG("MPMD", boost::format( - "Connected to CHDR interface, but got wrong device. " - "Tried to reach serial %s, got %s") - % device_info_dict["serial"] % dev_info_chdr["serial"]); + UHD_LOG_DEBUG("MPMD", + boost::format("Connected to CHDR interface, but got wrong device. " + "Tried to reach serial %s, got %s") + % device_info_dict["serial"] % dev_info_chdr["serial"]); return boost::optional<device_addr_t>(); } else { - UHD_LOG_TRACE("MPMD", boost::format( - "Reachable device matches expected device (serial=%s)") - % device_info_dict["serial"] ); + UHD_LOG_TRACE("MPMD", + boost::format("Reachable device matches expected device (serial=%s)") + % device_info_dict["serial"]); } device_addr_t device_addr_copy = device_addr; - device_addr_copy["addr"] = chdr_addr; + device_addr_copy["addr"] = chdr_addr; return boost::optional<device_addr_t>(device_addr_copy); } catch (...) { - UHD_LOG_DEBUG("MPMD", - "Failed to reach device on network addr " << chdr_addr << "."); + UHD_LOG_DEBUG( + "MPMD", "Failed to reach device on network addr " << chdr_addr << "."); } } // If everything fails, we probably can't talk to this chap. - UHD_LOG_TRACE("MPMD", - "All reachability checks failed -- assuming device is not reachable."); + UHD_LOG_TRACE( + "MPMD", "All reachability checks failed -- assuming device is not reachable."); return boost::optional<device_addr_t>(); } @@ -301,9 +253,8 @@ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( * Structors ****************************************************************************/ mpmd_mboard_impl::mpmd_mboard_impl( - const device_addr_t &mb_args_, - const std::string& rpc_server_addr -) : mb_args(mb_args_) + const device_addr_t& mb_args_, const std::string& rpc_server_addr) + : mb_args(mb_args_) , rpc(make_mpm_rpc_client(rpc_server_addr, mb_args_)) , num_xbars(rpc->request<size_t>("get_num_xbars")) , _claim_rpc(make_mpm_rpc_client(rpc_server_addr, mb_args, MPMD_CLAIMER_RPC_TIMEOUT)) @@ -311,12 +262,9 @@ mpmd_mboard_impl::mpmd_mboard_impl( , xbar_local_addrs(num_xbars, 0xFF) , _xport_mgr(xport::mpmd_xport_mgr::make(mb_args)) { - UHD_LOGGER_TRACE("MPMD") - << "Initializing mboard, connecting to RPC server address: " - << rpc_server_addr - << " mboard args: " << mb_args.to_string() - << " number of crossbars: " << num_xbars - ; + UHD_LOGGER_TRACE("MPMD") << "Initializing mboard, connecting to RPC server address: " + << rpc_server_addr << " mboard args: " << mb_args.to_string() + << " number of crossbars: " << num_xbars; _claimer_task = claim_device_and_make_task(); if (mb_args_.has_key(MPMD_MEAS_LATENCY_KEY)) { @@ -325,23 +273,21 @@ mpmd_mboard_impl::mpmd_mboard_impl( /// Get device info const auto device_info_dict = rpc->request<dev_info>("get_device_info"); - for (const auto &info_pair : device_info_dict) { + for (const auto& info_pair : device_info_dict) { device_info[info_pair.first] = info_pair.second; } - UHD_LOGGER_TRACE("MPMD") - << "MPM reports device info: " << device_info.to_string(); + UHD_LOGGER_TRACE("MPMD") << "MPM reports device info: " << device_info.to_string(); /// Get dboard info - const auto dboards_info = - rpc->request<std::vector<dev_info>>("get_dboard_info"); + const auto dboards_info = rpc->request<std::vector<dev_info>>("get_dboard_info"); UHD_ASSERT_THROW(this->dboard_info.size() == 0); - for (const auto &dboard_info_dict : dboards_info) { + for (const auto& dboard_info_dict : dboards_info) { uhd::device_addr_t this_db_info; - for (const auto &info_pair : dboard_info_dict) { + for (const auto& info_pair : dboard_info_dict) { this_db_info[info_pair.first] = info_pair.second; } UHD_LOGGER_TRACE("MPMD") - << "MPM reports dboard info for slot " << this->dboard_info.size() - << ": " << this_db_info.to_string(); + << "MPM reports dboard info for slot " << this->dboard_info.size() << ": " + << this_db_info.to_string(); this->dboard_info.push_back(this_db_info); } } @@ -353,11 +299,9 @@ mpmd_mboard_impl::~mpmd_mboard_impl() } catch (...) { UHD_LOG_WARNING("MPMD", "Could not flush log queue on exit!"); } - UHD_SAFE_CALL( - if (not rpc->request_with_token<bool>("unclaim")) { - UHD_LOG_WARNING("MPMD", "Failure to ack unclaim!"); - } - ); + UHD_SAFE_CALL(if (not rpc->request_with_token<bool>("unclaim")) { + UHD_LOG_WARNING("MPMD", "Failure to ack unclaim!"); + }); } /***************************************************************************** @@ -373,52 +317,42 @@ void mpmd_mboard_impl::init() * API ****************************************************************************/ void mpmd_mboard_impl::set_xbar_local_addr( - const size_t xbar_index, - const size_t local_addr -) { - UHD_ASSERT_THROW(rpc->request_with_token<bool>("set_xbar_local_addr", xbar_index, local_addr)); + const size_t xbar_index, const size_t local_addr) +{ + UHD_ASSERT_THROW( + rpc->request_with_token<bool>("set_xbar_local_addr", xbar_index, local_addr)); UHD_ASSERT_THROW(xbar_index < xbar_local_addrs.size()); xbar_local_addrs.at(xbar_index) = local_addr; } -uhd::both_xports_t mpmd_mboard_impl::make_transport( - const sid_t& sid, - usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args -) { - const std::string xport_type_str = [xport_type](){ +uhd::both_xports_t mpmd_mboard_impl::make_transport(const sid_t& sid, + usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& xport_args) +{ + const std::string xport_type_str = [xport_type]() { switch (xport_type) { - case mpmd_impl::CTRL: - return "CTRL"; - case mpmd_impl::ASYNC_MSG: - return "ASYNC_MSG"; - case mpmd_impl::RX_DATA: - return "RX_DATA"; - case mpmd_impl::TX_DATA: - return "TX_DATA"; - default: - UHD_THROW_INVALID_CODE_PATH(); + case mpmd_impl::CTRL: + return "CTRL"; + case mpmd_impl::ASYNC_MSG: + return "ASYNC_MSG"; + case mpmd_impl::RX_DATA: + return "RX_DATA"; + case mpmd_impl::TX_DATA: + return "TX_DATA"; + default: + UHD_THROW_INVALID_CODE_PATH(); }; }(); - UHD_LOGGER_TRACE("MPMD") - << __func__ << "(): Creating new transport of type: " - << xport_type_str - ; + UHD_LOGGER_TRACE("MPMD") << __func__ + << "(): Creating new transport of type: " << xport_type_str; using namespace uhd::mpmd::xport; const auto xport_info_list = rpc->request_with_token<mpmd_xport_mgr::xport_info_list_t>( - "request_xport", - sid.get_dst(), - sid.get_src(), - xport_type_str - ); - UHD_LOGGER_TRACE("MPMD") - << __func__ - << "(): request_xport() gave us " << xport_info_list.size() - << " option(s)." - ; + "request_xport", sid.get_dst(), sid.get_src(), xport_type_str); + UHD_LOGGER_TRACE("MPMD") << __func__ << "(): request_xport() gave us " + << xport_info_list.size() << " option(s)."; if (xport_info_list.empty()) { UHD_LOG_ERROR("MPMD", "No viable transport path found!"); throw uhd::runtime_error("No viable transport path found!"); @@ -426,15 +360,9 @@ uhd::both_xports_t mpmd_mboard_impl::make_transport( xport::mpmd_xport_mgr::xport_info_t xport_info_out; auto xports = _xport_mgr->make_transport( - xport_info_list, - xport_type, - xport_args, - xport_info_out - ); + xport_info_list, xport_type, xport_args, xport_info_out); - if (not rpc->request_with_token<bool>( - "commit_xport", - xport_info_out)) { + if (not rpc->request_with_token<bool>("commit_xport", xport_info_out)) { UHD_LOG_ERROR("MPMD", "Failed to create UDP transport!"); throw uhd::runtime_error("commit_xport() failed!"); } @@ -474,11 +402,10 @@ bool mpmd_mboard_impl::claim() } } -uhd::task::sptr mpmd_mboard_impl::claim_device_and_make_task( -) { - auto rpc_token = _claim_rpc->request<std::string>("claim", - mb_args.get("session_id", MPMD_DEFAULT_SESSION_ID) - ); +uhd::task::sptr mpmd_mboard_impl::claim_device_and_make_task() +{ + auto rpc_token = _claim_rpc->request<std::string>( + "claim", mb_args.get("session_id", MPMD_DEFAULT_SESSION_ID)); if (rpc_token.empty()) { throw uhd::value_error("mpmd device claiming failed!"); } @@ -493,8 +420,7 @@ uhd::task::sptr mpmd_mboard_impl::claim_device_and_make_task( }; this->dump_logs(); std::this_thread::sleep_until( - now + std::chrono::milliseconds(MPMD_RECLAIM_INTERVAL_MS) - ); + now + std::chrono::milliseconds(MPMD_RECLAIM_INTERVAL_MS)); }); } @@ -514,12 +440,10 @@ void mpmd_mboard_impl::dump_logs(const bool dump_to_null) * Factory ****************************************************************************/ mpmd_mboard_impl::uptr mpmd_mboard_impl::make( - const uhd::device_addr_t &mb_args, - const std::string& addr -) { + const uhd::device_addr_t& mb_args, const std::string& addr) +{ mpmd_mboard_impl::uptr mb = mpmd_mboard_impl::uptr(new mpmd_mboard_impl(mb_args, addr)); // implicit move return mb; } - diff --git a/host/lib/usrp/mpmd/mpmd_prop_tree.cpp b/host/lib/usrp/mpmd/mpmd_prop_tree.cpp index 27893341d..e4ebee5ac 100644 --- a/host/lib/usrp/mpmd/mpmd_prop_tree.cpp +++ b/host/lib/usrp/mpmd/mpmd_prop_tree.cpp @@ -9,91 +9,86 @@ #include "mpmd_impl.hpp" #include <uhd/property_tree.hpp> #include <uhd/types/component_file.hpp> -#include <uhd/types/sensors.hpp> #include <uhd/types/eeprom.hpp> +#include <uhd/types/sensors.hpp> #include <uhd/usrp/mboard_eeprom.hpp> using namespace uhd; using namespace uhd::mpmd; namespace { - //! Timeout value for the update_component RPC call (ms) - constexpr size_t MPMD_UPDATE_COMPONENT_TIMEOUT = 20000; +//! Timeout value for the update_component RPC call (ms) +constexpr size_t MPMD_UPDATE_COMPONENT_TIMEOUT = 20000; - /*! Update a component using all required files. For example, when updating the FPGA image - * (.bit or .bin), users can provide a new overlay image (DTS) to apply in addition. - * - * \param comps Vector of component files to be updated - * \param mb Reference to the actual device - */ - uhd::usrp::component_files_t _update_component( - const uhd::usrp::component_files_t& comps, - mpmd_mboard_impl *mb - ) { - // Construct the arguments to update component - std::vector<std::vector<uint8_t>> all_data; - std::vector<std::map<std::string, std::string>> all_metadata; - // Also construct a copy of just the metadata to store in the property tree - uhd::usrp::component_files_t all_comps_copy; +/*! Update a component using all required files. For example, when updating the FPGA image + * (.bit or .bin), users can provide a new overlay image (DTS) to apply in addition. + * + * \param comps Vector of component files to be updated + * \param mb Reference to the actual device + */ +uhd::usrp::component_files_t _update_component( + const uhd::usrp::component_files_t& comps, mpmd_mboard_impl* mb) +{ + // Construct the arguments to update component + std::vector<std::vector<uint8_t>> all_data; + std::vector<std::map<std::string, std::string>> all_metadata; + // Also construct a copy of just the metadata to store in the property tree + uhd::usrp::component_files_t all_comps_copy; - for (const auto& comp : comps) { - // Make a map for update components args - std::map<std::string, std::string> metadata; - // Make a component copy to add to the property tree - uhd::usrp::component_file_t comp_copy; - // Copy the metadata - for (const auto& key : comp.metadata.keys()) { - metadata[key] = comp.metadata[key]; - comp_copy.metadata[key] = comp.metadata[key]; - } - // Copy to the update component args - all_data.push_back(comp.data); - all_metadata.push_back(metadata); - // Copy to the property tree - all_comps_copy.push_back(comp_copy); + for (const auto& comp : comps) { + // Make a map for update components args + std::map<std::string, std::string> metadata; + // Make a component copy to add to the property tree + uhd::usrp::component_file_t comp_copy; + // Copy the metadata + for (const auto& key : comp.metadata.keys()) { + metadata[key] = comp.metadata[key]; + comp_copy.metadata[key] = comp.metadata[key]; } - - // Now call update component - const size_t update_component_timeout = MPMD_UPDATE_COMPONENT_TIMEOUT * comps.size(); - mb->rpc->notify_with_token(update_component_timeout, - "update_component", all_metadata, all_data); - return all_comps_copy; + // Copy to the update component args + all_data.push_back(comp.data); + all_metadata.push_back(metadata); + // Copy to the property tree + all_comps_copy.push_back(comp_copy); } - /* - * Query the device to get the metadata for desired component - * - * \param comp_name String component name - * \param mb Reference to the actual device - * \return component files containing the component metadata - */ - uhd::usrp::component_files_t _get_component_info( - const std::string &comp_name, - mpmd_mboard_impl *mb - ) { - UHD_LOG_TRACE("MPMD", "Getting component info for " << comp_name); - const auto component_metadata = mb->rpc->request<std::map<std::string, std::string>>( - "get_component_info", comp_name); - // Copy the contents of the component metadata into a object we can return - uhd::usrp::component_file_t return_component; - auto &return_metadata = return_component.metadata; - for (auto item : component_metadata) { - return_metadata[item.first] = item.second; - } - return uhd::usrp::component_files_t {return_component}; + // Now call update component + const size_t update_component_timeout = MPMD_UPDATE_COMPONENT_TIMEOUT * comps.size(); + mb->rpc->notify_with_token( + update_component_timeout, "update_component", all_metadata, all_data); + return all_comps_copy; +} + +/* + * Query the device to get the metadata for desired component + * + * \param comp_name String component name + * \param mb Reference to the actual device + * \return component files containing the component metadata + */ +uhd::usrp::component_files_t _get_component_info( + const std::string& comp_name, mpmd_mboard_impl* mb) +{ + UHD_LOG_TRACE("MPMD", "Getting component info for " << comp_name); + const auto component_metadata = mb->rpc->request<std::map<std::string, std::string>>( + "get_component_info", comp_name); + // Copy the contents of the component metadata into a object we can return + uhd::usrp::component_file_t return_component; + auto& return_metadata = return_component.metadata; + for (auto item : component_metadata) { + return_metadata[item.first] = item.second; } + return uhd::usrp::component_files_t{return_component}; } +} // namespace void mpmd_impl::init_property_tree( - uhd::property_tree::sptr tree, - fs_path mb_path, - mpmd_mboard_impl *mb -) { + uhd::property_tree::sptr tree, fs_path mb_path, mpmd_mboard_impl* mb) +{ /*** Device info ****************************************************/ if (not tree->exists("/name")) { - tree->create<std::string>("/name") - .set(mb->device_info.get("description", "Unknown MPM device")) - ; + tree->create<std::string>("/name").set( + mb->device_info.get("description", "Unknown MPM device")); } tree->create<std::string>(mb_path / "name") .set(mb->device_info.get("name", "UNKNOWN")); @@ -111,143 +106,98 @@ void mpmd_impl::init_property_tree( /*** Clocking *******************************************************/ tree->create<std::string>(mb_path / "clock_source/value") - .add_coerced_subscriber([mb](const std::string &clock_source){ - mb->rpc->notify_with_token(MPMD_DEFAULT_INIT_TIMEOUT, "set_clock_source", clock_source); + .add_coerced_subscriber([mb](const std::string& clock_source) { + mb->rpc->notify_with_token( + MPMD_DEFAULT_INIT_TIMEOUT, "set_clock_source", clock_source); }) - .set_publisher([mb](){ - return mb->rpc->request_with_token<std::string>( - "get_clock_source" - ); - }) - ; - tree->create<std::vector<std::string>>( - mb_path / "clock_source/options") - .set_publisher([mb](){ + .set_publisher([mb]() { + return mb->rpc->request_with_token<std::string>("get_clock_source"); + }); + tree->create<std::vector<std::string>>(mb_path / "clock_source/options") + .set_publisher([mb]() { return mb->rpc->request_with_token<std::vector<std::string>>( - "get_clock_sources" - ); - }) - ; + "get_clock_sources"); + }); tree->create<std::string>(mb_path / "time_source/value") - .add_coerced_subscriber([mb](const std::string &time_source){ - mb->rpc->notify_with_token(MPMD_DEFAULT_INIT_TIMEOUT, "set_time_source", time_source); + .add_coerced_subscriber([mb](const std::string& time_source) { + mb->rpc->notify_with_token( + MPMD_DEFAULT_INIT_TIMEOUT, "set_time_source", time_source); }) - .set_publisher([mb](){ - return mb->rpc->request_with_token<std::string>( - "get_time_source" - ); - }) - ; - tree->create<std::vector<std::string>>( - mb_path / "time_source/options") - .set_publisher([mb](){ + .set_publisher([mb]() { + return mb->rpc->request_with_token<std::string>("get_time_source"); + }); + tree->create<std::vector<std::string>>(mb_path / "time_source/options") + .set_publisher([mb]() { return mb->rpc->request_with_token<std::vector<std::string>>( - "get_time_sources" - ); - }) - ; + "get_time_sources"); + }); /*** Sensors ********************************************************/ auto sensor_list = - mb->rpc->request_with_token<std::vector<std::string>>( - "get_mb_sensors" - ); - UHD_LOG_DEBUG("MPMD", - "Found " << sensor_list.size() << " motherboard sensors." - ); + mb->rpc->request_with_token<std::vector<std::string>>("get_mb_sensors"); + UHD_LOG_DEBUG("MPMD", "Found " << sensor_list.size() << " motherboard sensors."); for (const auto& sensor_name : sensor_list) { - UHD_LOG_TRACE("MPMD", - "Adding motherboard sensor `" << sensor_name << "'" - ); - tree->create<sensor_value_t>( - mb_path / "sensors" / sensor_name) - .set_publisher([mb, sensor_name](){ + UHD_LOG_TRACE("MPMD", "Adding motherboard sensor `" << sensor_name << "'"); + tree->create<sensor_value_t>(mb_path / "sensors" / sensor_name) + .set_publisher([mb, sensor_name]() { auto sensor_val = sensor_value_t( mb->rpc->request_with_token<sensor_value_t::sensor_map_t>( - MPMD_DEFAULT_INIT_TIMEOUT, "get_mb_sensor", sensor_name - ) - ); + MPMD_DEFAULT_INIT_TIMEOUT, "get_mb_sensor", sensor_name)); return sensor_val; }) - .set_coercer([](const sensor_value_t &){ - throw uhd::runtime_error( - "Trying to write read-only sensor value!" - ); + .set_coercer([](const sensor_value_t&) { + throw uhd::runtime_error("Trying to write read-only sensor value!"); return sensor_value_t("", "", ""); - }) - ; + }); } /*** EEPROM *********************************************************/ tree->create<uhd::usrp::mboard_eeprom_t>(mb_path / "eeprom") - .add_coerced_subscriber([mb](const uhd::usrp::mboard_eeprom_t& mb_eeprom){ + .add_coerced_subscriber([mb](const uhd::usrp::mboard_eeprom_t& mb_eeprom) { eeprom_map_t eeprom_map; for (const auto& key : mb_eeprom.keys()) { - eeprom_map[key] = std::vector<uint8_t>( - mb_eeprom[key].cbegin(), - mb_eeprom[key].cend() - ); + eeprom_map[key] = + std::vector<uint8_t>(mb_eeprom[key].cbegin(), mb_eeprom[key].cend()); } - mb->rpc->notify_with_token(MPMD_DEFAULT_INIT_TIMEOUT, "set_mb_eeprom", eeprom_map); + mb->rpc->notify_with_token( + MPMD_DEFAULT_INIT_TIMEOUT, "set_mb_eeprom", eeprom_map); }) - .set_publisher([mb](){ + .set_publisher([mb]() { auto mb_eeprom = mb->rpc->request_with_token<std::map<std::string, std::string>>( - "get_mb_eeprom" - ); + "get_mb_eeprom"); uhd::usrp::mboard_eeprom_t mb_eeprom_dict( - mb_eeprom.cbegin(), mb_eeprom.cend() - ); + mb_eeprom.cbegin(), mb_eeprom.cend()); return mb_eeprom_dict; - }) - ; + }); /*** Updateable Components ******************************************/ std::vector<std::string> updateable_components = - mb->rpc->request<std::vector<std::string>>( - "list_updateable_components" - ); + mb->rpc->request<std::vector<std::string>>("list_updateable_components"); // TODO: Check the 'id' against the registered property UHD_LOG_DEBUG("MPMD", - "Found " << updateable_components.size() << " updateable motherboard components." - ); + "Found " << updateable_components.size() + << " updateable motherboard components."); for (const auto& comp_name : updateable_components) { - UHD_LOG_TRACE("MPMD", - "Adding motherboard component: " << comp_name); + UHD_LOG_TRACE("MPMD", "Adding motherboard component: " << comp_name); tree->create<uhd::usrp::component_files_t>(mb_path / "components" / comp_name) - .set_coercer([mb](const uhd::usrp::component_files_t& comp_files){ - return _update_component( - comp_files, - mb - ); + .set_coercer([mb](const uhd::usrp::component_files_t& comp_files) { + return _update_component(comp_files, mb); }) - .set_publisher([mb, comp_name](){ - return _get_component_info( - comp_name, - mb - ); - }) - ; // Done adding component to property tree + .set_publisher([mb, comp_name]() { + return _get_component_info(comp_name, mb); + }); // Done adding component to property tree } /*** MTUs ***********************************************************/ tree->create<size_t>(mb_path / "mtu/recv") - .add_coerced_subscriber([](const size_t){ - throw uhd::runtime_error( - "Attempting to write read-only value (MTU)!"); - }) - .set_publisher([mb](){ - return mb->get_mtu(uhd::RX_DIRECTION); + .add_coerced_subscriber([](const size_t) { + throw uhd::runtime_error("Attempting to write read-only value (MTU)!"); }) - ; + .set_publisher([mb]() { return mb->get_mtu(uhd::RX_DIRECTION); }); tree->create<size_t>(mb_path / "mtu/send") - .add_coerced_subscriber([](const size_t){ - throw uhd::runtime_error( - "Attempting to write read-only value (MTU)!"); + .add_coerced_subscriber([](const size_t) { + throw uhd::runtime_error("Attempting to write read-only value (MTU)!"); }) - .set_publisher([mb](){ - return mb->get_mtu(uhd::TX_DIRECTION); - }) - ; + .set_publisher([mb]() { return mb->get_mtu(uhd::TX_DIRECTION); }); } - diff --git a/host/lib/usrp/mpmd/mpmd_xport.cpp b/host/lib/usrp/mpmd/mpmd_xport.cpp index e697b6e80..3ef6a074c 100644 --- a/host/lib/usrp/mpmd/mpmd_xport.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport.cpp @@ -26,52 +26,37 @@ uhd::device_addr_t mpmd_impl::get_tx_hints(size_t mb_index) size_t mpmd_impl::identify_mboard_by_xbar_addr(const size_t xbar_addr) const { for (size_t mb_index = 0; mb_index < _mb.size(); mb_index++) { - for (size_t xbar_index = 0; - xbar_index < _mb[mb_index]->num_xbars; - xbar_index++) { + for (size_t xbar_index = 0; xbar_index < _mb[mb_index]->num_xbars; xbar_index++) { if (_mb.at(mb_index)->get_xbar_local_addr(xbar_index) == xbar_addr) { return mb_index; } } } - throw uhd::lookup_error(str( - boost::format("Cannot identify mboard for crossbar address %d") - % xbar_addr - )); + throw uhd::lookup_error( + str(boost::format("Cannot identify mboard for crossbar address %d") % xbar_addr)); } -both_xports_t mpmd_impl::make_transport( - const sid_t& dst_address, - usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& args -) { - const size_t mb_index = - identify_mboard_by_xbar_addr(dst_address.get_dst_addr()); +both_xports_t mpmd_impl::make_transport(const sid_t& dst_address, + usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& args) +{ + const size_t mb_index = identify_mboard_by_xbar_addr(dst_address.get_dst_addr()); - const sid_t sid( - 0, 0, // Not actually an address, more of an 'ignore me' value + const sid_t sid(0, + 0, // Not actually an address, more of an 'ignore me' value dst_address.get_dst_addr(), - dst_address.get_dst_endpoint() - ); - UHD_LOGGER_TRACE("MPMD") - << "Creating new transport to mboard: " << mb_index - << " SID: " << sid.to_pp_string_hex() - << " User-defined xport args: " << args.to_string() - ; - - both_xports_t xports = _mb[mb_index]->make_transport( - sid, - xport_type, - args - ); - UHD_LOGGER_TRACE("MPMD") - << "xport info: send_sid==" << xports.send_sid.to_pp_string_hex() - << " recv_sid==" << xports.recv_sid.to_pp_string_hex() - << " endianness==" - << (xports.endianness == uhd::ENDIANNESS_BIG ? "BE" : "LE") - << " recv_buff_size==" << xports.recv_buff_size - << " send_buff_size==" << xports.send_buff_size - ; + dst_address.get_dst_endpoint()); + UHD_LOGGER_TRACE("MPMD") << "Creating new transport to mboard: " << mb_index + << " SID: " << sid.to_pp_string_hex() + << " User-defined xport args: " << args.to_string(); + + both_xports_t xports = _mb[mb_index]->make_transport(sid, xport_type, args); + UHD_LOGGER_TRACE("MPMD") << "xport info: send_sid==" + << xports.send_sid.to_pp_string_hex() + << " recv_sid==" << xports.recv_sid.to_pp_string_hex() + << " endianness==" + << (xports.endianness == uhd::ENDIANNESS_BIG ? "BE" : "LE") + << " recv_buff_size==" << xports.recv_buff_size + << " send_buff_size==" << xports.send_buff_size; return xports; } - diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp index 78ffeaf1b..a7fff9262 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp @@ -7,8 +7,8 @@ #ifndef INCLUDED_MPMD_XPORT_CTRL_BASE_HPP #define INCLUDED_MPMD_XPORT_CTRL_BASE_HPP -#include "mpmd_xport_mgr.hpp" #include "../device3/device3_impl.hpp" +#include "mpmd_xport_mgr.hpp" #include <uhd/types/device_addr.hpp> #include <memory> @@ -29,20 +29,14 @@ public: * \param xport_type CTRL, ASYNC_MSG, ... (see xport_type_t) * \param xport_args Additional arguments. These can come from the user. */ - virtual both_xports_t make_transport( - mpmd_xport_mgr::xport_info_t& xport_info, + virtual both_xports_t make_transport(mpmd_xport_mgr::xport_info_t& xport_info, const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args - ) = 0; + const uhd::device_addr_t& xport_args) = 0; //! Assert if an xport_info is even valid/feasible/available - virtual bool is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info - ) const = 0; + virtual bool is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const = 0; - virtual size_t get_mtu( - const uhd::direction_t dir - ) const = 0; + virtual size_t get_mtu(const uhd::direction_t dir) const = 0; }; }}} /* namespace uhd::mpmd::xport */ diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp index 13ecea5e9..7efe2bb9a 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp @@ -14,42 +14,41 @@ using namespace uhd::mpmd::xport; namespace { - //! Max frame size of a control packet in bytes - const size_t LIBERIO_CTRL_FRAME_MAX_SIZE = 128; - //! Max frame size of an async message packet in bytes - const size_t LIBERIO_ASYNC_FRAME_MAX_SIZE = 256; - //! Max frame size of a flow control packet in bytes - const size_t LIBERIO_FC_FRAME_MAX_SIZE = 64; - //! The max MTU will be this number times the page size - const size_t LIBERIO_PAGES_PER_BUF = 2; - //! Number of descriptors that liberio allocates (receive) - const size_t LIBERIO_NUM_RECV_FRAMES = 128; - //! Number of descriptors that liberio allocates (send) - const size_t LIBERIO_NUM_SEND_FRAMES = 128; - - uint32_t extract_sid_from_pkt(void* pkt, size_t) { - return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])) - .get_dst(); - } - +//! Max frame size of a control packet in bytes +const size_t LIBERIO_CTRL_FRAME_MAX_SIZE = 128; +//! Max frame size of an async message packet in bytes +const size_t LIBERIO_ASYNC_FRAME_MAX_SIZE = 256; +//! Max frame size of a flow control packet in bytes +const size_t LIBERIO_FC_FRAME_MAX_SIZE = 64; +//! The max MTU will be this number times the page size +const size_t LIBERIO_PAGES_PER_BUF = 2; +//! Number of descriptors that liberio allocates (receive) +const size_t LIBERIO_NUM_RECV_FRAMES = 128; +//! Number of descriptors that liberio allocates (send) +const size_t LIBERIO_NUM_SEND_FRAMES = 128; + +uint32_t extract_sid_from_pkt(void* pkt, size_t) +{ + return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])).get_dst(); } -mpmd_xport_ctrl_liberio::mpmd_xport_ctrl_liberio( - const uhd::device_addr_t& mb_args -) : _mb_args(mb_args) - , _recv_args(filter_args(mb_args, "recv")) - , _send_args(filter_args(mb_args, "send")) +} // namespace + +mpmd_xport_ctrl_liberio::mpmd_xport_ctrl_liberio(const uhd::device_addr_t& mb_args) + : _mb_args(mb_args) + , _recv_args(filter_args(mb_args, "recv")) + , _send_args(filter_args(mb_args, "send")) { // nop } -uhd::both_xports_t -mpmd_xport_ctrl_liberio::make_transport( - mpmd_xport_mgr::xport_info_t &xport_info, - const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& /*xport_args_*/ -) { +uhd::both_xports_t mpmd_xport_ctrl_liberio::make_transport( + mpmd_xport_mgr::xport_info_t& xport_info, + const usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& /*xport_args_*/ +) +{ transport::zero_copy_xport_params default_buff_args; /* default ones for RX / TX, override below */ @@ -75,8 +74,8 @@ mpmd_xport_ctrl_liberio::make_transport( both_xports_t xports; xports.endianness = uhd::ENDIANNESS_LITTLE; - xports.send_sid = sid_t(xport_info["send_sid"]); - xports.recv_sid = xports.send_sid.reversed(); + xports.send_sid = sid_t(xport_info["send_sid"]); + xports.recv_sid = xports.send_sid.reversed(); // this is kinda ghetto: scale buffer for muxed xports since we share the // buffer... @@ -87,7 +86,7 @@ mpmd_xport_ctrl_liberio::make_transport( divisor = 4; - //if (xport_info["muxed"] == "True") { + // if (xport_info["muxed"] == "True") { //// FIXME tbw //} if (xport_type == usrp::device3_impl::CTRL) { @@ -95,8 +94,8 @@ mpmd_xport_ctrl_liberio::make_transport( if (not _ctrl_dma_xport) { default_buff_args.send_frame_size = LIBERIO_CTRL_FRAME_MAX_SIZE; default_buff_args.recv_frame_size = LIBERIO_CTRL_FRAME_MAX_SIZE; - _ctrl_dma_xport = make_muxed_liberio_xport(tx_dev, rx_dev, - default_buff_args, int(divisor)); + _ctrl_dma_xport = + make_muxed_liberio_xport(tx_dev, rx_dev, default_buff_args, int(divisor)); } UHD_LOGGER_TRACE("MPMD") @@ -107,58 +106,52 @@ mpmd_xport_ctrl_liberio::make_transport( if (not _async_msg_dma_xport) { default_buff_args.send_frame_size = LIBERIO_ASYNC_FRAME_MAX_SIZE; default_buff_args.recv_frame_size = LIBERIO_ASYNC_FRAME_MAX_SIZE; - _async_msg_dma_xport = make_muxed_liberio_xport( - tx_dev, rx_dev, default_buff_args, int(divisor)); + _async_msg_dma_xport = + make_muxed_liberio_xport(tx_dev, rx_dev, default_buff_args, int(divisor)); } UHD_LOGGER_TRACE("MPMD") << "making (muxed) stream with num " << xports.recv_sid.get_dst(); - xports.recv = - _async_msg_dma_xport->make_stream(xports.recv_sid.get_dst()); + xports.recv = _async_msg_dma_xport->make_stream(xports.recv_sid.get_dst()); } else { - xports.recv = transport::liberio_zero_copy::make( - tx_dev, rx_dev, default_buff_args); + xports.recv = + transport::liberio_zero_copy::make(tx_dev, rx_dev, default_buff_args); } transport::udp_zero_copy::buff_params buff_params; - buff_params.recv_buff_size = - float(default_buff_args.recv_frame_size) * - float(default_buff_args.num_recv_frames) / divisor; - buff_params.send_buff_size = - float(default_buff_args.send_frame_size) * - float(default_buff_args.num_send_frames) / divisor; + buff_params.recv_buff_size = float(default_buff_args.recv_frame_size) + * float(default_buff_args.num_recv_frames) / divisor; + buff_params.send_buff_size = float(default_buff_args.send_frame_size) + * float(default_buff_args.num_send_frames) / divisor; // Finish both_xports_t object and return: xports.recv_buff_size = buff_params.recv_buff_size; xports.send_buff_size = buff_params.send_buff_size; - xports.send = xports.recv; + xports.send = xports.recv; return xports; } bool mpmd_xport_ctrl_liberio::is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info -) const { + const mpmd_xport_mgr::xport_info_t& xport_info) const +{ return xport_info.at("type") == "liberio"; } -size_t mpmd_xport_ctrl_liberio::get_mtu( - const uhd::direction_t /* dir */ -) const { +size_t mpmd_xport_ctrl_liberio::get_mtu(const uhd::direction_t /* dir */ + ) const +{ return LIBERIO_PAGES_PER_BUF * getpagesize(); } uhd::transport::muxed_zero_copy_if::sptr -mpmd_xport_ctrl_liberio::make_muxed_liberio_xport( - const std::string &tx_dev, - const std::string &rx_dev, - const uhd::transport::zero_copy_xport_params &buff_args, - const size_t max_muxed_ports -) { - auto base_xport = transport::liberio_zero_copy::make( - tx_dev, rx_dev, buff_args); +mpmd_xport_ctrl_liberio::make_muxed_liberio_xport(const std::string& tx_dev, + const std::string& rx_dev, + const uhd::transport::zero_copy_xport_params& buff_args, + const size_t max_muxed_ports) +{ + auto base_xport = transport::liberio_zero_copy::make(tx_dev, rx_dev, buff_args); return uhd::transport::muxed_zero_copy_if::make( - base_xport, extract_sid_from_pkt, max_muxed_ports); + base_xport, extract_sid_from_pkt, max_muxed_ports); } - diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp index 9bea12aa3..5f635e7e7 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp @@ -7,10 +7,10 @@ #ifndef INCLUDED_MPMD_XPORT_ctrl_liberio_HPP #define INCLUDED_MPMD_XPORT_ctrl_liberio_HPP -#include "mpmd_xport_ctrl_base.hpp" -#include <uhd/types/device_addr.hpp> #include "../device3/device3_impl.hpp" +#include "mpmd_xport_ctrl_base.hpp" #include <uhd/transport/muxed_zero_copy_if.hpp> +#include <uhd/types/device_addr.hpp> namespace uhd { namespace mpmd { namespace xport { @@ -19,34 +19,25 @@ namespace uhd { namespace mpmd { namespace xport { class mpmd_xport_ctrl_liberio : public mpmd_xport_ctrl_base { public: - mpmd_xport_ctrl_liberio( - const uhd::device_addr_t& mb_args - ); + mpmd_xport_ctrl_liberio(const uhd::device_addr_t& mb_args); /*! Open DMA interface to kernel (and thus to FPGA DMA engine) */ - both_xports_t make_transport( - mpmd_xport_mgr::xport_info_t& xport_info, + both_xports_t make_transport(mpmd_xport_mgr::xport_info_t& xport_info, const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args - ); + const uhd::device_addr_t& xport_args); - bool is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info - ) const; + bool is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const; - size_t get_mtu( - const uhd::direction_t dir - ) const ; + size_t get_mtu(const uhd::direction_t dir) const; private: /*! Create a muxed liberio transport for control packets */ uhd::transport::muxed_zero_copy_if::sptr make_muxed_liberio_xport( - const std::string &tx_dev, - const std::string &rx_dev, - const uhd::transport::zero_copy_xport_params &buff_args, - const size_t max_muxed_ports - ); + const std::string& tx_dev, + const std::string& rx_dev, + const uhd::transport::zero_copy_xport_params& buff_args, + const size_t max_muxed_ports); const uhd::device_addr_t _mb_args; const uhd::dict<std::string, std::string> _recv_args; diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp index ee48235ee..df02b183f 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp @@ -4,12 +4,12 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include "mpmd_xport_ctrl_udp.hpp" #include "mpmd_impl.hpp" #include "mpmd_xport_mgr.hpp" -#include "mpmd_xport_ctrl_udp.hpp" -#include <uhd/transport/udp_zero_copy.hpp> -#include <uhd/transport/udp_simple.hpp> #include <uhd/transport/udp_constants.hpp> +#include <uhd/transport/udp_simple.hpp> +#include <uhd/transport/udp_zero_copy.hpp> using namespace uhd; @@ -17,244 +17,216 @@ using namespace uhd::mpmd::xport; namespace { - #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) - //! Size of the host-side socket buffer for RX - const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x100000; // 1Mib - #elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) - //! Size of the host-side socket buffer for RX - // For an ~8k frame size any size >32MiB is just wasted buffer space - const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x2000000; // 32 MiB - #endif +#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) +//! Size of the host-side socket buffer for RX +const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x100000; // 1Mib +#elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) +//! Size of the host-side socket buffer for RX +// For an ~8k frame size any size >32MiB is just wasted buffer space +const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x2000000; // 32 MiB +#endif - //! Maximum CHDR packet size in bytes - const size_t MPMD_10GE_DATA_FRAME_MAX_SIZE = 4000; +//! Maximum CHDR packet size in bytes +const size_t MPMD_10GE_DATA_FRAME_MAX_SIZE = 4000; - //! Maximum CHDR packet size in bytes - const size_t MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE = 1472; +//! Maximum CHDR packet size in bytes +const size_t MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE = 1472; - //! Number of send/recv frames - const size_t MPMD_ETH_NUM_FRAMES = 32; +//! Number of send/recv frames +const size_t MPMD_ETH_NUM_FRAMES = 32; - //! - const double MPMD_BUFFER_FILL_RATE = 20.0e-3; // s - //! For MTU discovery, the time we wait for a packet before calling it - // oversized (seconds). - const double MPMD_MTU_DISCOVERY_TIMEOUT = 0.02; +//! +const double MPMD_BUFFER_FILL_RATE = 20.0e-3; // s +//! For MTU discovery, the time we wait for a packet before calling it +// oversized (seconds). +const double MPMD_MTU_DISCOVERY_TIMEOUT = 0.02; - //TODO: move these to appropriate header file for all other devices - const size_t MAX_RATE_1GIGE = 1e9 / 8; // byte/s - const size_t MAX_RATE_10GIGE = 10e9 / 8; // byte/s +// TODO: move these to appropriate header file for all other devices +const size_t MAX_RATE_1GIGE = 1e9 / 8; // byte/s +const size_t MAX_RATE_10GIGE = 10e9 / 8; // byte/s - std::vector<std::string> get_addrs_from_mb_args( - const uhd::device_addr_t& mb_args - ) { - // mb_args must always include addr - if (not mb_args.has_key(FIRST_ADDR_KEY)) { - throw uhd::runtime_error("The " + FIRST_ADDR_KEY + " key must be specified in " - "device args to create an Ethernet transport to an RFNoC block"); - } - std::vector<std::string> addrs{mb_args[FIRST_ADDR_KEY]}; - if (mb_args.has_key(SECOND_ADDR_KEY)){ - addrs.push_back(mb_args[SECOND_ADDR_KEY]); - } - return addrs; +std::vector<std::string> get_addrs_from_mb_args(const uhd::device_addr_t& mb_args) +{ + // mb_args must always include addr + if (not mb_args.has_key(FIRST_ADDR_KEY)) { + throw uhd::runtime_error( + "The " + FIRST_ADDR_KEY + + " key must be specified in " + "device args to create an Ethernet transport to an RFNoC block"); } + std::vector<std::string> addrs{mb_args[FIRST_ADDR_KEY]}; + if (mb_args.has_key(SECOND_ADDR_KEY)) { + addrs.push_back(mb_args[SECOND_ADDR_KEY]); + } + return addrs; +} - /*! Do a binary search to discover MTU - * - * Uses the MPM echo service to figure out MTU. We simply send a bunch of - * packets and see if they come back until we converged on the path MTU. - * The end result must lie between \p min_frame_size and \p max_frame_size. - * - * \param address IP address - * \param port UDP port (yeah it's a string!) - * \param min_frame_size Minimum frame size, initialize algorithm to start - * with this value - * \param max_frame_size Maximum frame size, initialize algorithm to start - * with this value - * \param echo_timeout Timeout value in seconds. For frame sizes that - * exceed the MTU, we don't expect a response, and this - * is the amount of time we'll wait before we assume - * the frame size exceeds the MTU. - */ - size_t discover_mtu( - const std::string &address, - const std::string &port, - size_t min_frame_size, - size_t max_frame_size, - const double echo_timeout = 0.020 - ) { - const size_t echo_prefix_offset = - uhd::mpmd::mpmd_impl::MPM_ECHO_CMD.size(); - const size_t mtu_hdr_len = echo_prefix_offset + 10; - UHD_ASSERT_THROW(min_frame_size < max_frame_size); - UHD_ASSERT_THROW(min_frame_size % 4 == 0); - UHD_ASSERT_THROW(max_frame_size % 4 == 0); - UHD_ASSERT_THROW(min_frame_size >= echo_prefix_offset + mtu_hdr_len); - using namespace uhd::transport; - // The return port will probably differ from the discovery port, so we - // need a "broadcast" UDP connection; using make_connected() would - // drop packets - udp_simple::sptr udp = udp_simple::make_broadcast(address, port); - std::string send_buf(uhd::mpmd::mpmd_impl::MPM_ECHO_CMD); - send_buf.resize(max_frame_size, '#'); - UHD_ASSERT_THROW(send_buf.size() == max_frame_size); - std::vector<uint8_t> recv_buf; - recv_buf.resize(max_frame_size, ' '); - - // Little helper to check returned packets match the sent ones - auto require_bufs_match = [&recv_buf, &send_buf, mtu_hdr_len]( - const size_t len - ){ - if (len < mtu_hdr_len or std::memcmp( - (void *) &recv_buf[0], - (void *) &send_buf[0], - mtu_hdr_len - ) != 0) { - throw uhd::runtime_error("Unexpected content of MTU " - "discovery return packet!"); - } - }; - UHD_LOG_TRACE("MPMD", "Determining UDP MTU... "); - size_t seq_no = 0; - while (min_frame_size < max_frame_size) { - // Only test multiples of 4 bytes! - const size_t test_frame_size = - (max_frame_size/2 + min_frame_size/2 + 3) & ~size_t(3); - // Encode sequence number and current size in the string, makes it - // easy to debug in code or Wireshark. Is also used for identifying - // response packets. - std::sprintf( - &send_buf[echo_prefix_offset], - ";%04lu,%04lu", - seq_no++, - test_frame_size - ); - UHD_LOG_TRACE("MPMD", "Testing frame size " << test_frame_size); - udp->send(boost::asio::buffer(&send_buf[0], test_frame_size)); - - const size_t len = - udp->recv(boost::asio::buffer(recv_buf), echo_timeout); - if (len == 0) { - // Nothing received, so this is probably too big - max_frame_size = test_frame_size - 4; - } else if (len >= test_frame_size) { - // Size went through, so bump the minimum - require_bufs_match(len); - min_frame_size = test_frame_size; - } else if (len < test_frame_size) { - // This is an odd case. Something must have snipped the packet - // on the way back. Still, we'll just back off and try - // something smaller. - UHD_LOG_DEBUG("MPMD", - "Unexpected packet truncation during MTU discovery."); - require_bufs_match(len); - max_frame_size = len; - } +/*! Do a binary search to discover MTU + * + * Uses the MPM echo service to figure out MTU. We simply send a bunch of + * packets and see if they come back until we converged on the path MTU. + * The end result must lie between \p min_frame_size and \p max_frame_size. + * + * \param address IP address + * \param port UDP port (yeah it's a string!) + * \param min_frame_size Minimum frame size, initialize algorithm to start + * with this value + * \param max_frame_size Maximum frame size, initialize algorithm to start + * with this value + * \param echo_timeout Timeout value in seconds. For frame sizes that + * exceed the MTU, we don't expect a response, and this + * is the amount of time we'll wait before we assume + * the frame size exceeds the MTU. + */ +size_t discover_mtu(const std::string& address, + const std::string& port, + size_t min_frame_size, + size_t max_frame_size, + const double echo_timeout = 0.020) +{ + const size_t echo_prefix_offset = uhd::mpmd::mpmd_impl::MPM_ECHO_CMD.size(); + const size_t mtu_hdr_len = echo_prefix_offset + 10; + UHD_ASSERT_THROW(min_frame_size < max_frame_size); + UHD_ASSERT_THROW(min_frame_size % 4 == 0); + UHD_ASSERT_THROW(max_frame_size % 4 == 0); + UHD_ASSERT_THROW(min_frame_size >= echo_prefix_offset + mtu_hdr_len); + using namespace uhd::transport; + // The return port will probably differ from the discovery port, so we + // need a "broadcast" UDP connection; using make_connected() would + // drop packets + udp_simple::sptr udp = udp_simple::make_broadcast(address, port); + std::string send_buf(uhd::mpmd::mpmd_impl::MPM_ECHO_CMD); + send_buf.resize(max_frame_size, '#'); + UHD_ASSERT_THROW(send_buf.size() == max_frame_size); + std::vector<uint8_t> recv_buf; + recv_buf.resize(max_frame_size, ' '); + + // Little helper to check returned packets match the sent ones + auto require_bufs_match = [&recv_buf, &send_buf, mtu_hdr_len](const size_t len) { + if (len < mtu_hdr_len + or std::memcmp((void*)&recv_buf[0], (void*)&send_buf[0], mtu_hdr_len) != 0) { + throw uhd::runtime_error("Unexpected content of MTU " + "discovery return packet!"); + } + }; + UHD_LOG_TRACE("MPMD", "Determining UDP MTU... "); + size_t seq_no = 0; + while (min_frame_size < max_frame_size) { + // Only test multiples of 4 bytes! + const size_t test_frame_size = (max_frame_size / 2 + min_frame_size / 2 + 3) + & ~size_t(3); + // Encode sequence number and current size in the string, makes it + // easy to debug in code or Wireshark. Is also used for identifying + // response packets. + std::sprintf( + &send_buf[echo_prefix_offset], ";%04lu,%04lu", seq_no++, test_frame_size); + UHD_LOG_TRACE("MPMD", "Testing frame size " << test_frame_size); + udp->send(boost::asio::buffer(&send_buf[0], test_frame_size)); + + const size_t len = udp->recv(boost::asio::buffer(recv_buf), echo_timeout); + if (len == 0) { + // Nothing received, so this is probably too big + max_frame_size = test_frame_size - 4; + } else if (len >= test_frame_size) { + // Size went through, so bump the minimum + require_bufs_match(len); + min_frame_size = test_frame_size; + } else if (len < test_frame_size) { + // This is an odd case. Something must have snipped the packet + // on the way back. Still, we'll just back off and try + // something smaller. + UHD_LOG_DEBUG("MPMD", "Unexpected packet truncation during MTU discovery."); + require_bufs_match(len); + max_frame_size = len; } - UHD_LOG_DEBUG("MPMD", - "Path MTU for address " << address << ": " << min_frame_size); - return min_frame_size; } - + UHD_LOG_DEBUG("MPMD", "Path MTU for address " << address << ": " << min_frame_size); + return min_frame_size; } +} // namespace + -mpmd_xport_ctrl_udp::mpmd_xport_ctrl_udp( - const uhd::device_addr_t& mb_args -) : _mb_args(mb_args) - , _recv_args(filter_args(mb_args, "recv")) - , _send_args(filter_args(mb_args, "send")) - , _available_addrs(get_addrs_from_mb_args(mb_args)) - , _mtu(MPMD_10GE_DATA_FRAME_MAX_SIZE) +mpmd_xport_ctrl_udp::mpmd_xport_ctrl_udp(const uhd::device_addr_t& mb_args) + : _mb_args(mb_args) + , _recv_args(filter_args(mb_args, "recv")) + , _send_args(filter_args(mb_args, "send")) + , _available_addrs(get_addrs_from_mb_args(mb_args)) + , _mtu(MPMD_10GE_DATA_FRAME_MAX_SIZE) { const std::string mpm_discovery_port = _mb_args.get( - mpmd_impl::MPM_DISCOVERY_PORT_KEY, - std::to_string(mpmd_impl::MPM_DISCOVERY_PORT) - ); - auto discover_mtu_for_ip = [mpm_discovery_port](const std::string &ip_addr){ - return discover_mtu( - ip_addr, + mpmd_impl::MPM_DISCOVERY_PORT_KEY, std::to_string(mpmd_impl::MPM_DISCOVERY_PORT)); + auto discover_mtu_for_ip = [mpm_discovery_port](const std::string& ip_addr) { + return discover_mtu(ip_addr, mpm_discovery_port, - IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER, + IP_PROTOCOL_MIN_MTU_SIZE - IP_PROTOCOL_UDP_PLUS_IP_HEADER, MPMD_10GE_DATA_FRAME_MAX_SIZE, - MPMD_MTU_DISCOVERY_TIMEOUT - ); + MPMD_MTU_DISCOVERY_TIMEOUT); }; - for (const auto &ip_addr : _available_addrs) { + for (const auto& ip_addr : _available_addrs) { _mtu = std::min(_mtu, discover_mtu_for_ip(ip_addr)); } } -uhd::both_xports_t -mpmd_xport_ctrl_udp::make_transport( - mpmd_xport_mgr::xport_info_t &xport_info, - const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args_ -) { +uhd::both_xports_t mpmd_xport_ctrl_udp::make_transport( + mpmd_xport_mgr::xport_info_t& xport_info, + const usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& xport_args_) +{ auto xport_args = xport_args_; if (xport_type == usrp::device3_impl::RX_DATA - and not xport_args.has_key("recv_buff_size")) { - xport_args["recv_buff_size"] = - std::to_string(MPMD_RX_SW_BUFF_SIZE_ETH); + and not xport_args.has_key("recv_buff_size")) { + xport_args["recv_buff_size"] = std::to_string(MPMD_RX_SW_BUFF_SIZE_ETH); } size_t link_speed = MAX_RATE_1GIGE; - if(xport_info.count("link_speed") == 0) - { + if (xport_info.count("link_speed") == 0) { UHD_LOG_WARNING("MPMD", "Could not determine link speed; using 1GibE max speed of " - << MAX_RATE_1GIGE); - } - else{ - link_speed = xport_info.at("link_speed") == "10000"? - MAX_RATE_10GIGE: - MAX_RATE_1GIGE; + << MAX_RATE_1GIGE); + } else { + link_speed = xport_info.at("link_speed") == "10000" ? MAX_RATE_10GIGE + : MAX_RATE_1GIGE; } transport::zero_copy_xport_params default_buff_args; // Create actual UDP transport default_buff_args.recv_frame_size = get_mtu(uhd::RX_DIRECTION); - default_buff_args.recv_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; - default_buff_args.send_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; + default_buff_args.recv_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; + default_buff_args.send_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; if (xport_type == usrp::device3_impl::ASYNC_MSG) { default_buff_args.send_frame_size = MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE; - }else{ + } else { default_buff_args.send_frame_size = get_mtu(uhd::TX_DIRECTION); } transport::udp_zero_copy::buff_params buff_params; - auto recv = transport::udp_zero_copy::make( - xport_info["ipv4"], + auto recv = transport::udp_zero_copy::make(xport_info["ipv4"], xport_info["port"], default_buff_args, buff_params, - xport_args - ); - const uint16_t port = recv->get_local_port(); + xport_args); + const uint16_t port = recv->get_local_port(); const std::string src_ip_addr = recv->get_local_addr(); - xport_info["src_port"] = std::to_string(port); - xport_info["src_ipv4"] = src_ip_addr; + xport_info["src_port"] = std::to_string(port); + xport_info["src_ipv4"] = src_ip_addr; // Create both_xports_t object and finish: both_xports_t xports; - xports.endianness = uhd::ENDIANNESS_BIG; - xports.send_sid = sid_t(xport_info["send_sid"]); - xports.recv_sid = xports.send_sid.reversed(); + xports.endianness = uhd::ENDIANNESS_BIG; + xports.send_sid = sid_t(xport_info["send_sid"]); + xports.recv_sid = xports.send_sid.reversed(); xports.recv_buff_size = buff_params.recv_buff_size; xports.send_buff_size = buff_params.send_buff_size; - xports.recv = recv; // Note: This is a type cast! - xports.send = recv; // This too + xports.recv = recv; // Note: This is a type cast! + xports.send = recv; // This too return xports; } -bool mpmd_xport_ctrl_udp::is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info -) const { +bool mpmd_xport_ctrl_udp::is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const +{ return std::find( - _available_addrs.cbegin(), - _available_addrs.cend(), - xport_info.at("ipv4") - ) != _available_addrs.cend(); + _available_addrs.cbegin(), _available_addrs.cend(), xport_info.at("ipv4")) + != _available_addrs.cend(); } size_t mpmd_xport_ctrl_udp::get_mtu(const uhd::direction_t /*dir*/) const diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp index ff7e69361..86301bb2a 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp @@ -7,9 +7,9 @@ #ifndef INCLUDED_MPMD_XPORT_ctrl_udp_HPP #define INCLUDED_MPMD_XPORT_ctrl_udp_HPP +#include "../device3/device3_impl.hpp" #include "mpmd_xport_ctrl_base.hpp" #include <uhd/types/device_addr.hpp> -#include "../device3/device3_impl.hpp" namespace uhd { namespace mpmd { namespace xport { @@ -20,23 +20,15 @@ namespace uhd { namespace mpmd { namespace xport { class mpmd_xport_ctrl_udp : public mpmd_xport_ctrl_base { public: - mpmd_xport_ctrl_udp( - const uhd::device_addr_t& mb_args - ); + mpmd_xport_ctrl_udp(const uhd::device_addr_t& mb_args); - both_xports_t make_transport( - mpmd_xport_mgr::xport_info_t& xport_info, + both_xports_t make_transport(mpmd_xport_mgr::xport_info_t& xport_info, const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args - ); + const uhd::device_addr_t& xport_args); - bool is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info - ) const; + bool is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const; - size_t get_mtu( - const uhd::direction_t dir - ) const; + size_t get_mtu(const uhd::direction_t dir) const; private: const uhd::device_addr_t _mb_args; diff --git a/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp b/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp index a4109b51d..c2200c66a 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp @@ -4,18 +4,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "mpmd_impl.hpp" #include "mpmd_xport_mgr.hpp" +#include "mpmd_impl.hpp" #include "mpmd_xport_ctrl_base.hpp" #include "mpmd_xport_ctrl_udp.hpp" #ifdef HAVE_LIBERIO -# include "mpmd_xport_ctrl_liberio.hpp" +# include "mpmd_xport_ctrl_liberio.hpp" #endif uhd::dict<std::string, std::string> uhd::mpmd::xport::filter_args( - const uhd::device_addr_t& args, - const std::string& prefix -) { + const uhd::device_addr_t& args, const std::string& prefix) +{ uhd::dict<std::string, std::string> filtered_args; for (const std::string& key : args.keys()) { if (key.find(prefix) != std::string::npos) { @@ -31,9 +30,7 @@ using namespace uhd::mpmd::xport; class mpmd_xport_mgr_impl : public mpmd_xport_mgr { public: - mpmd_xport_mgr_impl( - const uhd::device_addr_t& mb_args - ) : _mb_args(mb_args) + mpmd_xport_mgr_impl(const uhd::device_addr_t& mb_args) : _mb_args(mb_args) { // nop } @@ -41,36 +38,30 @@ public: /************************************************************************** * API (see mpmd_xport_mgr.hpp) *************************************************************************/ - uhd::both_xports_t make_transport( - const xport_info_list_t &xport_info_list, + uhd::both_xports_t make_transport(const xport_info_list_t& xport_info_list, const uhd::usrp::device3_impl::xport_type_t xport_type, const uhd::device_addr_t& xport_args, - xport_info_t& xport_info_out - ) { - for (const auto &xport_info : xport_info_list) { + xport_info_t& xport_info_out) + { + for (const auto& xport_info : xport_info_list) { require_xport_mgr(xport_info.at("type")); } // Run our incredibly smart selection algorithm - xport_info_out = select_xport_option(xport_info_list); + xport_info_out = select_xport_option(xport_info_list); const std::string xport_medium = xport_info_out.at("type"); - UHD_LOG_TRACE("MPMD", - __func__ << "(): xport medium is " << xport_medium); + UHD_LOG_TRACE("MPMD", __func__ << "(): xport medium is " << xport_medium); UHD_ASSERT_THROW(_xport_ctrls.count(xport_medium) > 0); UHD_ASSERT_THROW(_xport_ctrls.at(xport_medium)); // When we've picked our preferred option, pass it to the transport // implementation for execution: - return _xport_ctrls.at(xport_medium)->make_transport( - xport_info_out, - xport_type, - xport_args - ); + return _xport_ctrls.at(xport_medium) + ->make_transport(xport_info_out, xport_type, xport_args); } - size_t get_mtu( - const uhd::direction_t dir - ) const { + size_t get_mtu(const uhd::direction_t dir) const + { if (_xport_ctrls.empty()) { UHD_LOG_WARNING("MPMD", "Cannot determine MTU, no transport controls have been " @@ -79,7 +70,7 @@ public: } size_t mtu = ~size_t(0); - for (const auto &xport_ctrl_pair : _xport_ctrls) { + for (const auto& xport_ctrl_pair : _xport_ctrls) { mtu = std::min(mtu, xport_ctrl_pair.second->get_mtu(dir)); } @@ -99,21 +90,20 @@ private: * \returns One element of \p xport_info_list based on a selection * algorithm. */ - xport_info_t select_xport_option( - const xport_info_list_t &xport_info_list - ) const { + xport_info_t select_xport_option(const xport_info_list_t& xport_info_list) const + { for (const auto& xport_info : xport_info_list) { const std::string xport_medium = xport_info.at("type"); - if (_xport_ctrls.count(xport_medium) != 0 and - _xport_ctrls.at(xport_medium) and - _xport_ctrls.at(xport_medium)->is_valid(xport_info)) { + if (_xport_ctrls.count(xport_medium) != 0 and _xport_ctrls.at(xport_medium) + and _xport_ctrls.at(xport_medium)->is_valid(xport_info)) { return xport_info; } } - throw uhd::runtime_error("Could not select a transport option! " - "Either a transport hint was not specified or the specified " - "hint does not support communication with RFNoC blocks."); + throw uhd::runtime_error( + "Could not select a transport option! " + "Either a transport hint was not specified or the specified " + "hint does not support communication with RFNoC blocks."); } //! Create an instance of an xport manager implementation @@ -121,22 +111,17 @@ private: // \param xport_medium "UDP" or "liberio" // \param mb_args Device args mpmd_xport_ctrl_base::uptr make_mgr_impl( - const std::string &xport_medium, - const uhd::device_addr_t& mb_args - ) const { + const std::string& xport_medium, const uhd::device_addr_t& mb_args) const + { if (xport_medium == "UDP") { - return mpmd_xport_ctrl_base::uptr( - new mpmd_xport_ctrl_udp(mb_args) - ); + return mpmd_xport_ctrl_base::uptr(new mpmd_xport_ctrl_udp(mb_args)); #ifdef HAVE_LIBERIO } else if (xport_medium == "liberio") { - return mpmd_xport_ctrl_base::uptr( - new mpmd_xport_ctrl_liberio(mb_args) - ); + return mpmd_xport_ctrl_base::uptr(new mpmd_xport_ctrl_liberio(mb_args)); #endif } else { - UHD_LOG_WARNING("MPMD", - "Cannot instantiate transport medium " << xport_medium); + UHD_LOG_WARNING( + "MPMD", "Cannot instantiate transport medium " << xport_medium); return nullptr; } } @@ -150,11 +135,11 @@ private: // \param xport_medium Type of transport, e.g. "UDP", "liberio", ... // // \throws uhd::key_error if \p xport_medium is not known or registered - void require_xport_mgr(const std::string &xport_medium) + void require_xport_mgr(const std::string& xport_medium) { if (_xport_ctrls.count(xport_medium) == 0) { - UHD_LOG_TRACE("MPMD", - "Instantiating transport manager `" << xport_medium << "'"); + UHD_LOG_TRACE( + "MPMD", "Instantiating transport manager `" << xport_medium << "'"); auto mgr_impl = make_mgr_impl(xport_medium, _mb_args); if (mgr_impl) { _xport_ctrls[xport_medium] = std::move(mgr_impl); @@ -174,9 +159,7 @@ private: const uhd::device_addr_t _mb_args; }; -mpmd_xport_mgr::uptr mpmd_xport_mgr::make( - const uhd::device_addr_t& mb_args -) { +mpmd_xport_mgr::uptr mpmd_xport_mgr::make(const uhd::device_addr_t& mb_args) +{ return mpmd_xport_mgr::uptr(new mpmd_xport_mgr_impl(mb_args)); } - diff --git a/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp b/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp index 72700e69a..3d96e5ec6 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp @@ -9,10 +9,10 @@ #include "../device3/device3_impl.hpp" #include <uhd/types/dict.hpp> -#include <memory> #include <map> -#include <vector> +#include <memory> #include <string> +#include <vector> namespace uhd { namespace mpmd { namespace xport { @@ -21,11 +21,11 @@ namespace uhd { namespace mpmd { namespace xport { */ //! Ethernet address for management and RPC communication -const std::string MGMT_ADDR_KEY = "mgmt_addr"; +const std::string MGMT_ADDR_KEY = "mgmt_addr"; //! Primary Ethernet address for streaming and RFNoC communication -const std::string FIRST_ADDR_KEY = "addr"; +const std::string FIRST_ADDR_KEY = "addr"; //! Secondary Ethernet address for streaming and RFNoC communication -const std::string SECOND_ADDR_KEY = "second_addr"; +const std::string SECOND_ADDR_KEY = "second_addr"; /*! Return filtered subset from a device_addr_t * @@ -36,9 +36,7 @@ const std::string SECOND_ADDR_KEY = "second_addr"; * \param prefix Key prefix to match against */ uhd::dict<std::string, std::string> filter_args( - const uhd::device_addr_t& args, - const std::string& prefix -); + const uhd::device_addr_t& args, const std::string& prefix); /*! MPMD Transport Manager * @@ -50,8 +48,8 @@ uhd::dict<std::string, std::string> filter_args( class mpmd_xport_mgr { public: - using uptr = std::unique_ptr<mpmd_xport_mgr>; - using xport_info_t = std::map<std::string, std::string>; + using uptr = std::unique_ptr<mpmd_xport_mgr>; + using xport_info_t = std::map<std::string, std::string>; using xport_info_list_t = std::vector<std::map<std::string, std::string>>; virtual ~mpmd_xport_mgr() {} @@ -65,9 +63,7 @@ public: * \throws uhd::key_error if \p xport_medium is not supported. The ctor of * the underlying class that is requested can also throw. */ - static uptr make( - const uhd::device_addr_t& mb_args - ); + static uptr make(const uhd::device_addr_t& mb_args); /*! Create a transports object * @@ -94,18 +90,14 @@ public: * The latter needs to get sent back to MPM to complete the * transport handshake. */ - virtual both_xports_t make_transport( - const xport_info_list_t &xport_info_list, + virtual both_xports_t make_transport(const xport_info_list_t& xport_info_list, const usrp::device3_impl::xport_type_t xport_type, const uhd::device_addr_t& xport_args, - xport_info_t& xport_info_out - ) = 0; + xport_info_t& xport_info_out) = 0; /*! Return the path MTU for whatever this manager lets us do */ - virtual size_t get_mtu( - const uhd::direction_t dir - ) const = 0; + virtual size_t get_mtu(const uhd::direction_t dir) const = 0; }; }}} /* namespace uhd::mpmd::xport */ |