From 2b864696b729783a0248c800e0a5b18bd881509c Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Tue, 30 May 2017 14:33:15 -0700 Subject: mpmd: Added preliminary support for passing RPC client to blocks --- host/lib/rfnoc/rpc_block_ctrl.hpp | 51 +++++++++++++++++++++++++++++++++++++++ host/lib/usrp/mpmd/mpmd_impl.cpp | 49 ++++++++++++++++++++++++++----------- host/lib/usrp/mpmd/mpmd_impl.hpp | 18 +++++++++++++- host/lib/utils/rpc.hpp | 4 +++ 4 files changed, 107 insertions(+), 15 deletions(-) create mode 100644 host/lib/rfnoc/rpc_block_ctrl.hpp (limited to 'host/lib') diff --git a/host/lib/rfnoc/rpc_block_ctrl.hpp b/host/lib/rfnoc/rpc_block_ctrl.hpp new file mode 100644 index 000000000..99c0c8ce1 --- /dev/null +++ b/host/lib/rfnoc/rpc_block_ctrl.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2017 Ettus Research (National Instruments) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP +#define INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP + +#include "../utils/rpc.hpp" + +namespace uhd { + namespace rfnoc { + +/*! Abstraction for RPC client + * + * Purpose of this class is to wrap the underlying RPC implementation. + * This class holds a connection to an RPC server (the connection is severed on + * destruction). + */ +class rpc_block_ctrl +{ +public: + virtual ~rpc_block_ctrl() {} + + /*! Pass in an RPC client for the block to use + * + * \param rpcc Reference to the RPC client + * \param block_args Additional block arguments + */ + virtual void set_rpc_client( + uhd::rpc_client::sptr rpcc, + const uhd::device_addr_t &block_args + ) = 0; + +}; + +}} + +#endif /* INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp index 747bd87a6..2d93c16ff 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_impl.cpp @@ -16,6 +16,7 @@ // #include "mpmd_impl.hpp" +#include "rpc_block_ctrl.hpp" #include <../device3/device3_impl.hpp> #include #include @@ -36,15 +37,15 @@ using namespace uhd; mpmd_mboard_impl::mpmd_mboard_impl(const std::string& addr) - : rpc(addr, MPM_RPC_PORT) + : rpc(uhd::rpc_client::make(addr, MPM_RPC_PORT)) { UHD_LOG_TRACE("MPMD", "Initializing mboard, IP address: " << addr); std::map _dev_info = - rpc.call("get_device_info"); + rpc->call("get_device_info"); device_info = dict(_dev_info.begin(), _dev_info.end()); // Get initial claim on mboard - _rpc_token = rpc.call("claim", "UHD - Session 01"); // make this configurable with device_addr? + _rpc_token = rpc->call("claim", "UHD - Session 01"); // TODO make this configurable with device_addr, and provide better defaults if (_rpc_token.empty()){ throw uhd::value_error("mpmd device claiming failed!"); } @@ -77,7 +78,7 @@ uhd::sid_t mpmd_mboard_impl::allocate_sid(const uint16_t port, const uhd::sid_t address, const uint32_t xbar_src_addr, const uint32_t xbar_src_port){ - const uint32_t sid = rpc.call("allocate_sid", _rpc_token, port, + const uint32_t sid = rpc->call("allocate_sid", _rpc_token, port, address.get(), xbar_src_addr, xbar_src_port); return sid; } @@ -91,36 +92,56 @@ mpmd_mboard_impl::uptr mpmd_mboard_impl::make(const std::string& addr) return mb; } -bool mpmd_mboard_impl::claim() { return rpc.call("reclaim", _rpc_token); } +bool mpmd_mboard_impl::claim() +{ + return rpc->call("reclaim", _rpc_token); +} mpmd_impl::mpmd_impl(const device_addr_t& device_addr) : usrp::device3_impl() , _device_addr(device_addr) , _sid_framer(0) { - UHD_LOGGER_INFO("MPMD") << "MPMD initialization sequence. Device args: " << device_addr.to_string(); - _tree->create("/name").set("MPMD - Series device"); + UHD_LOGGER_INFO("MPMD") + << "MPMD initialization sequence. Device args: " + << device_addr.to_string(); const device_addrs_t device_args = separate_device_addr(device_addr); _mb.reserve(device_args.size()); for (size_t mb_i = 0; mb_i < device_args.size(); ++mb_i) { _mb.push_back(setup_mb(mb_i, device_args[mb_i])); } + + // TODO read this from the device info + _tree->create("/name").set("MPMD - Series device"); + try { enumerate_rfnoc_blocks( 0, - 3, /* num blocks */ - 3, /* base port */ - uhd::sid_t(0x0200), + 3, /* num blocks */ // TODO don't hardcode + 3, /* base port */ // TODO don't hardcode + uhd::sid_t(0x0200), // TODO don't hardcode device_addr ); } catch (const std::exception &ex) { - UHD_HERE(); - std::cout << ex.what() << std::endl; + UHD_LOGGER_ERROR("MPMD") + << "Failure during device initialization: " + << ex.what(); + throw uhd::runtime_error("Failed to run enumerate_rfnoc_blocks()"); } - - // FIXME pass in a reference to the rpc client for all childs of rpc_block_ctrl + for (const auto &block_ctrl: _rfnoc_block_ctrl) { + auto rpc_block_id = block_ctrl->get_block_id(); + if (has_block(block_ctrl->get_block_id())) { + const size_t mboard_idx = rpc_block_id.get_device_no(); + UHD_LOGGER_DEBUG("MPMD") + << "Adding RPC access to block: " << rpc_block_id + << " Extra device args: " << device_args[mboard_idx].to_string() + ; + get_block_ctrl(rpc_block_id) + ->set_rpc_client(_mb[mboard_idx]->rpc, device_args[mboard_idx]); + } + } } mpmd_impl::~mpmd_impl() {} diff --git a/host/lib/usrp/mpmd/mpmd_impl.hpp b/host/lib/usrp/mpmd/mpmd_impl.hpp index 3b6a4b213..9a8b25ba0 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.hpp +++ b/host/lib/usrp/mpmd/mpmd_impl.hpp @@ -40,6 +40,9 @@ struct frame_size_t size_t send_frame_size; }; + +/*! Stores all attributes specific to a single MPM device + */ class mpmd_mboard_impl { public: @@ -56,7 +59,13 @@ class mpmd_mboard_impl std::map data_interfaces; std::string loaded_fpga_image; std::string xport_path; - uhd::rpc_client rpc; + + /*! Reference the RPC client for this motherboard + * + * We store a shared ptr, because we might share it with some of the RFNoC + * blocks. + */ + uhd::rpc_client::sptr rpc; uhd::sid_t allocate_sid(const uint16_t port, const uhd::sid_t address, const uint32_t xbar_src_addr, @@ -69,6 +78,13 @@ class mpmd_mboard_impl uhd::task::sptr _claimer_task; }; + +/*! Parent class of an MPM device + * + * An MPM device is a USRP running MPM. Because most of the hardware controls + * are taken care of by MPM itself, it is not necessary to write a specific + * derived class for every single type of MPM device. + */ class mpmd_impl : public uhd::usrp::device3_impl { public: diff --git a/host/lib/utils/rpc.hpp b/host/lib/utils/rpc.hpp index 39acffa04..bae8f7fe1 100644 --- a/host/lib/utils/rpc.hpp +++ b/host/lib/utils/rpc.hpp @@ -33,6 +33,10 @@ class rpc_client public: using sptr = std::shared_ptr; + static sptr make(std::string const& addr, uint16_t port) { + return std::make_shared(addr, port); + } + /*! * \param addr An IP address to connect to * \param port Port to connect to -- cgit v1.2.3