Exemplo n.º 1
0
//! separate indexed device addresses into a vector of device addresses
device_addrs_t sep_indexed_dev_addrs(const device_addr_t &dev_addr){
    //------------ support old deprecated way and print warning --------
    if (dev_addr.has_key("addr") and not dev_addr["addr"].empty()){
        std::vector<std::string> addrs; boost::split(addrs, dev_addr["addr"], boost::is_any_of(" "));
        if (addrs.size() > 1){
            device_addr_t fixed_dev_addr = dev_addr;
            fixed_dev_addr.pop("addr");
            for (size_t i = 0; i < addrs.size(); i++){
                fixed_dev_addr[str(boost::format("addr%d") % i)] = addrs[i];
            }
            uhd::warning::post(
                "addr = <space separated list of ip addresses> is deprecated.\n"
                "To address a multi-device, use multiple <key><index> = <val>.\n"
                "See the USRP-NXXX application notes. Two device example:\n"
                "    addr0 = 192.168.10.2\n"
                "    addr1 = 192.168.10.3\n"
            );
            return sep_indexed_dev_addrs(fixed_dev_addr);
        }
    }
    //------------------------------------------------------------------
    device_addrs_t dev_addrs;
    BOOST_FOREACH(const std::string &key, dev_addr.keys()){
        boost::cmatch matches;
        if (not boost::regex_match(key.c_str(), matches, boost::regex("^(\\D+)(\\d*)$"))){
            throw std::runtime_error("unknown key format: " + key);
        }
        std::string key_part(matches[1].first, matches[1].second);
        std::string num_part(matches[2].first, matches[2].second);
        size_t num = (num_part.empty())? 0 : boost::lexical_cast<size_t>(num_part);
        dev_addrs.resize(std::max(num+1, dev_addrs.size()));
        dev_addrs[num][key_part] = dev_addr[key];
    }
    return dev_addrs;
}
Exemplo n.º 2
0
    virtual void _parse(const device_addr_t& dev_args) {
        //Extract parameters from dev_args
        if (dev_args.has_key(_master_clock_rate.key()))
            _master_clock_rate.parse(dev_args[_master_clock_rate.key()]);
        if (dev_args.has_key(_send_frame_size.key()))
            _send_frame_size.parse(dev_args[_send_frame_size.key()]);
        if (dev_args.has_key(_recv_frame_size.key()))
            _recv_frame_size.parse(dev_args[_recv_frame_size.key()]);
        if (dev_args.has_key(_num_send_frames.key()))
            _num_send_frames.parse(dev_args[_num_send_frames.key()]);
        if (dev_args.has_key(_num_recv_frames.key()))
            _num_recv_frames.parse(dev_args[_num_recv_frames.key()]);
        if (dev_args.has_key(_send_buff_size.key()))
            _send_buff_size.parse(dev_args[_send_buff_size.key()]);
        if (dev_args.has_key(_recv_buff_size.key()))
            _recv_buff_size.parse(dev_args[_recv_buff_size.key()]);
        if (dev_args.has_key(_safe_mode.key()))
            _safe_mode.parse(dev_args[_safe_mode.key()]);
        if (dev_args.has_key(_loopback_mode.key()))
            _loopback_mode.parse(dev_args[_loopback_mode.key()], false /* assert invalid */);

        //Sanity check params
        _enforce_range(_master_clock_rate, MIN_TICK_RATE, MAX_TICK_RATE);
        _enforce_range(_send_frame_size, MIN_FRAME_SIZE, MAX_FRAME_SIZE);
        _enforce_range(_recv_frame_size, MIN_FRAME_SIZE, MAX_FRAME_SIZE);
        _enforce_range(_num_send_frames, (size_t)2, (size_t)UINT_MAX);
        _enforce_range(_num_recv_frames, (size_t)2, (size_t)UINT_MAX);
    }
Exemplo n.º 3
0
udp_zero_copy::sptr udp_zero_copy::make(
    const std::string &addr,
    const std::string &port,
    const zero_copy_xport_params &default_buff_args,
    udp_zero_copy::buff_params& buff_params_out,
    const device_addr_t &hints
){
    //Initialize xport_params
    zero_copy_xport_params xport_params = default_buff_args;

    xport_params.recv_frame_size = size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size));
    xport_params.num_recv_frames = size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames));
    xport_params.send_frame_size = size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size));
    xport_params.num_send_frames = size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames));

    //extract buffer size hints from the device addr
    size_t usr_recv_buff_size = size_t(hints.cast<double>("recv_buff_size", 0.0));
    size_t usr_send_buff_size = size_t(hints.cast<double>("send_buff_size", 0.0));

    if (hints.has_key("recv_buff_size")) {
        if (usr_recv_buff_size < xport_params.recv_frame_size * xport_params.num_recv_frames) {
            throw uhd::value_error((boost::format(
                "recv_buff_size must be equal to or greater than (num_recv_frames * recv_frame_size) where num_recv_frames=%d, recv_frame_size=%d")
                % xport_params.num_recv_frames % xport_params.recv_frame_size).str());
        }
    }

    if (hints.has_key("send_buff_size")) {
        if (usr_send_buff_size < xport_params.send_frame_size * xport_params.num_send_frames) {
            throw uhd::value_error((boost::format(
                "send_buff_size must be equal to or greater than (num_send_frames * send_frame_size) where num_send_frames=%d, send_frame_size=%d")
                % xport_params.num_send_frames % xport_params.send_frame_size).str());
        }
    }

    udp_zero_copy_asio_impl::sptr udp_trans(
        new udp_zero_copy_asio_impl(addr, port, xport_params)
    );

    //call the helper to resize send and recv buffers
    buff_params_out.recv_buff_size =
        resize_buff_helper<asio::socket_base::receive_buffer_size>(udp_trans, usr_recv_buff_size, "recv");
    buff_params_out.send_buff_size =
        resize_buff_helper<asio::socket_base::send_buffer_size>   (udp_trans, usr_send_buff_size, "send");

    return udp_trans;
}
Exemplo n.º 4
0
device_addrs_t uhd::separate_device_addr(const device_addr_t &dev_addr){
    //------------ support old deprecated way and print warning --------
    if (dev_addr.has_key("addr") and not dev_addr["addr"].empty()){
        std::vector<std::string> addrs; boost::split(addrs, dev_addr["addr"], boost::is_any_of(" "));
        if (addrs.size() > 1){
            device_addr_t fixed_dev_addr = dev_addr;
            fixed_dev_addr.pop("addr");
            for (size_t i = 0; i < addrs.size(); i++){
                fixed_dev_addr[str(boost::format("addr%d") % i)] = addrs[i];
            }
            UHD_LOGGER_WARNING("UHD") <<
                "addr = <space separated list of ip addresses> is deprecated.\n"
                "To address a multi-device, use multiple <key><index> = <val>.\n"
                "See the USRP-NXXX application notes. Two device example:\n"
                "    addr0 = 192.168.10.2\n"
                "    addr1 = 192.168.10.3\n"
            ;
            return separate_device_addr(fixed_dev_addr);
        }
    }
    //------------------------------------------------------------------
    device_addrs_t dev_addrs(1); //must be at least one (obviously)
    std::vector<std::string> global_keys; //keys that apply to all (no numerical suffix)
    for(const std::string &key:  dev_addr.keys()){
        boost::cmatch matches;
        if (not boost::regex_match(key.c_str(), matches, boost::regex("^(\\D+)(\\d*)$"))){
            throw std::runtime_error("unknown key format: " + key);
        }
        std::string key_part(matches[1].first, matches[1].second);
        std::string num_part(matches[2].first, matches[2].second);
        if (num_part.empty()){ //no number? save it for later
            global_keys.push_back(key);
            continue;
        }
        const size_t num = boost::lexical_cast<size_t>(num_part);
        dev_addrs.resize(std::max(num+1, dev_addrs.size()));
        dev_addrs[num][key_part] = dev_addr[key];
    }

    //copy the global settings across all device addresses
    for(device_addr_t &my_dev_addr:  dev_addrs){
        for(const std::string &global_key:  global_keys){
            my_dev_addr[global_key] = dev_addr[global_key];
        }
    }
    return dev_addrs;
}
Exemplo n.º 5
0
/***********************************************************************
 * Discovery
 **********************************************************************/
static device_addrs_t b200_find(const device_addr_t &hint)
{
    device_addrs_t b200_addrs;

    //return an empty list of addresses when type is set to non-b200
    if (hint.has_key("type") and hint["type"] != "b200") return b200_addrs;

    //Return an empty list of addresses when an address or resource is specified,
    //since an address and resource is intended for a different, non-USB, device.
    if (hint.has_key("addr") || hint.has_key("resource")) return b200_addrs;

    boost::uint16_t vid, pid;

    if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "b200") {
        vid = uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("vid"));
        pid = uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("pid"));
    } else {
        vid = B200_VENDOR_ID;
        pid = B200_PRODUCT_ID;
    }

    // Important note:
    // The get device list calls are nested inside the for loop.
    // This allows the usb guts to decontruct when not in use,
    // so that re-enumeration after fw load can occur successfully.
    // This requirement is a courtesy of libusb1.0 on windows.

    //find the usrps and load firmware
    size_t found = 0;
    BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
        //extract the firmware path for the b200
        std::string b200_fw_image;
        try{
            b200_fw_image = find_image_path(hint.get("fw", B200_FW_FILE_NAME));
        }
        catch(...){
            UHD_MSG(warning) << boost::format(
                "Could not locate B200 firmware.\n"
                "Please install the images package. %s\n"
            ) % print_images_error();
            return b200_addrs;
        }
        UHD_LOG << "the firmware image: " << b200_fw_image << std::endl;

        usb_control::sptr control;
        try{control = usb_control::make(handle, 0);}
        catch(const uhd::exception &){continue;} //ignore claimed

        //check if fw was already loaded
        if (!(handle->firmware_loaded()))
        {
            b200_iface::make(control)->load_firmware(b200_fw_image);
        }

        found++;
    }
Exemplo n.º 6
0
/*****************************************************************************
 * Structors
 ****************************************************************************/
mpmd_mboard_impl::mpmd_mboard_impl(
    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))
    // xbar_local_addrs is not yet valid after this!
    , 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;

    _claimer_task = claim_device_and_make_task();
    if (mb_args_.has_key(MPMD_MEAS_LATENCY_KEY)) {
        measure_rpc_latency(rpc, MPMD_MEAS_LATENCY_DURATION);
    }

    /// Get device info
    const auto device_info_dict = rpc->request<dev_info>("get_device_info");
    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();
    /// 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) {
        uhd::device_addr_t this_db_info;
        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();
        this->dboard_info.push_back(this_db_info);
    }

    for (const std::string& key : mb_args_.keys()) {
        if (key.find("recv") != std::string::npos)
            recv_args[key] = mb_args_[key];
        if (key.find("send") != std::string::npos)
            send_args[key] = mb_args_[key];
    }
}
Exemplo n.º 7
0
/***********************************************************************
 * Discovery
 **********************************************************************/
static device_addrs_t usrp1_find(const device_addr_t &hint)
{
    device_addrs_t usrp1_addrs;

    //return an empty list of addresses when type is set to non-usrp1
    if (hint.has_key("type") and hint["type"] != "usrp1") return usrp1_addrs;

    //Return an empty list of addresses when an address is specified,
    //since an address is intended for a different, non-USB, device.
    if (hint.has_key("addr")) return usrp1_addrs;

    boost::uint16_t vid = hint.has_key("uninit") ? FX2_VENDOR_ID : USRP1_VENDOR_ID;
    boost::uint16_t pid = hint.has_key("uninit") ? FX2_PRODUCT_ID : USRP1_PRODUCT_ID;

    // Important note:
    // The get device list calls are nested inside the for loop.
    // This allows the usb guts to decontruct when not in use,
    // so that re-enumeration after fw load can occur successfully.
    // This requirement is a courtesy of libusb1.0 on windows.

    //find the usrps and load firmware
    BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
        //extract the firmware path for the USRP1
        std::string usrp1_fw_image;
        try {
            usrp1_fw_image = find_image_path(hint.get("fw", "usrp1_fw.ihx"));
        }
        catch(...) {
            UHD_MSG(warning) << boost::format(
                                 "Could not locate USRP1 firmware.\n"
                                 "Please install the images package.\n"
                             );
            return usrp1_addrs;
        }
        UHD_LOG << "USRP1 firmware image: " << usrp1_fw_image << std::endl;

        usb_control::sptr control;
        try {
            control = usb_control::make(handle, 0);
        }
        catch(const uhd::exception &) {
            continue;   //ignore claimed
        }

        fx2_ctrl::make(control)->usrp_load_firmware(usrp1_fw_image);
    }
Exemplo n.º 8
0
/***********************************************************************
 * Discovery
 **********************************************************************/
static device_addrs_t e100_find(const device_addr_t &hint){
    device_addrs_t e100_addrs;

    //return an empty list of addresses when type is set to non-usrp-e
    if (hint.has_key("type") and hint["type"] != "e100") return e100_addrs;

    //Return an empty list of addresses when a resource is specified,
    //since a resource is intended for a different, non-USB, device.
    if (hint.has_key("resource")) return e100_addrs;

    //device node not provided, assume its 0
    if (not hint.has_key("node")){
        device_addr_t new_addr = hint;
        new_addr["node"] = "/dev/usrp_e0";
        return e100_find(new_addr);
    }

    //use the given device node name
    if (fs::exists(hint["node"])){
        device_addr_t new_addr;
        new_addr["type"] = "e100";
        new_addr["node"] = fs::system_complete(fs::path(hint["node"])).string();
        try{
            i2c_iface::sptr i2c_iface = e100_ctrl::make_dev_i2c_iface(E100_I2C_DEV_NODE);
            const mboard_eeprom_t mb_eeprom(*i2c_iface, E100_EEPROM_MAP_KEY);
            new_addr["name"] = mb_eeprom["name"];
            new_addr["serial"] = mb_eeprom["serial"];
        }
        catch(const std::exception &e){
            new_addr["name"] = "";
            new_addr["serial"] = "";
        }
        if (
            (not hint.has_key("name")   or hint["name"]   == new_addr["name"]) and
            (not hint.has_key("serial") or hint["serial"] == new_addr["serial"])
        ){
            e100_addrs.push_back(new_addr);
        }
    }

    return e100_addrs;
}
Exemplo n.º 9
0
/***********************************************************************
 * Discovery
 **********************************************************************/
static device_addrs_t usrp1_find(const device_addr_t &hint)
{
    device_addrs_t usrp1_addrs;

    //return an empty list of addresses when type is set to non-usrp1
    if (hint.has_key("type") and hint["type"] != "usrp1") return usrp1_addrs;

    //Return an empty list of addresses when an address or resource is specified,
    //since an address and resource is intended for a different, non-USB, device.
    if (hint.has_key("addr") || hint.has_key("resource")) return usrp1_addrs;

    boost::uint16_t vid, pid;

    if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "usrp1") {
        vid = uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("vid"));
        pid = uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("pid"));
    } else {
        vid = USRP1_VENDOR_ID;
        pid = USRP1_PRODUCT_ID;
    }

    // Important note:
    // The get device list calls are nested inside the for loop.
    // This allows the usb guts to decontruct when not in use,
    // so that re-enumeration after fw load can occur successfully.
    // This requirement is a courtesy of libusb1.0 on windows.

    //find the usrps and load firmware
    size_t found = 0;
    BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
        //extract the firmware path for the USRP1
        std::string usrp1_fw_image;
        try{
            usrp1_fw_image = find_image_path(hint.get("fw", "usrp1_fw.ihx"));
        }
        catch(...){
            UHD_MSG(warning) << boost::format("Could not locate USRP1 firmware. %s") % print_utility_error("uhd_images_downloader.py");
        }
        UHD_LOG << "USRP1 firmware image: " << usrp1_fw_image << std::endl;

        usb_control::sptr control;
        try{control = usb_control::make(handle, 0);}
        catch(const uhd::exception &){continue;} //ignore claimed

        fx2_ctrl::make(control)->usrp_load_firmware(usrp1_fw_image);
        found++;
    }
Exemplo n.º 10
0
/***********************************************************************
 * Discovery
 **********************************************************************/
static device_addrs_t b100_find(const device_addr_t &hint)
{
    device_addrs_t b100_addrs;

    //return an empty list of addresses when type is set to non-b100
    if (hint.has_key("type") and hint["type"] != "b100") return b100_addrs;

    //Return an empty list of addresses when an address is specified,
    //since an address is intended for a different, non-USB, device.
    if (hint.has_key("addr")) return b100_addrs;

    unsigned int vid, pid;

    if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "b100") {
        sscanf(hint.get("vid").c_str(), "%x", &vid);
        sscanf(hint.get("pid").c_str(), "%x", &pid);
    } else {
        vid = B100_VENDOR_ID;
        pid = B100_PRODUCT_ID;
    }

    // Important note:
    // The get device list calls are nested inside the for loop.
    // This allows the usb guts to decontruct when not in use,
    // so that re-enumeration after fw load can occur successfully.
    // This requirement is a courtesy of libusb1.0 on windows.

    //find the usrps and load firmware
    size_t found = 0;
    BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
        //extract the firmware path for the b100
        std::string b100_fw_image;
        try{
            b100_fw_image = find_image_path(hint.get("fw", B100_FW_FILE_NAME));
        }
        catch(...){
            UHD_MSG(warning) << boost::format("Could not locate B100 firmware. %s\n") % print_images_error();
            return b100_addrs;
        }
        UHD_LOG << "the firmware image: " << b100_fw_image << std::endl;

        usb_control::sptr control;
        try{control = usb_control::make(handle, 0);}
        catch(const uhd::exception &){continue;} //ignore claimed

        fx2_ctrl::make(control)->usrp_load_firmware(b100_fw_image);
        found++;
    }
Exemplo n.º 11
0
udp_zero_copy::sptr udp_zero_copy::make(const std::string& addr,
    const std::string& port,
    const zero_copy_xport_params& default_buff_args,
    udp_zero_copy::buff_params& buff_params_out,
    const device_addr_t& hints)
{
    // Initialize xport_params
    zero_copy_xport_params xport_params = default_buff_args;

    xport_params.recv_frame_size =
        size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size));
    xport_params.num_recv_frames =
        size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames));
    xport_params.send_frame_size =
        size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size));
    xport_params.num_send_frames =
        size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames));
    xport_params.recv_buff_size =
        size_t(hints.cast<double>("recv_buff_size", default_buff_args.recv_buff_size));
    xport_params.send_buff_size =
        size_t(hints.cast<double>("send_buff_size", default_buff_args.send_buff_size));

    if (xport_params.num_recv_frames == 0) {
        UHD_LOG_TRACE("UDP",
            "Default value for num_recv_frames: " << UDP_ZERO_COPY_DEFAULT_NUM_FRAMES);
        xport_params.num_recv_frames = UDP_ZERO_COPY_DEFAULT_NUM_FRAMES;
    }
    if (xport_params.num_send_frames == 0) {
        UHD_LOG_TRACE("UDP",
            "Default value for no num_send_frames: " << UDP_ZERO_COPY_DEFAULT_NUM_FRAMES);
        xport_params.num_send_frames = UDP_ZERO_COPY_DEFAULT_NUM_FRAMES;
    }
    if (xport_params.recv_frame_size == 0) {
        UHD_LOG_TRACE("UDP",
            "Using default value for  recv_frame_size: "
                << UDP_ZERO_COPY_DEFAULT_FRAME_SIZE);
        xport_params.recv_frame_size = UDP_ZERO_COPY_DEFAULT_FRAME_SIZE;
    }
    if (xport_params.send_frame_size == 0) {
        UHD_LOG_TRACE("UDP",
            "Using default value for send_frame_size, "
                << UDP_ZERO_COPY_DEFAULT_FRAME_SIZE);
        xport_params.send_frame_size = UDP_ZERO_COPY_DEFAULT_FRAME_SIZE;
    }

    if (xport_params.recv_buff_size == 0) {
        UHD_LOG_TRACE("UDP", "Using default value for recv_buff_size");
        xport_params.recv_buff_size = std::max(UDP_ZERO_COPY_DEFAULT_BUFF_SIZE,
            xport_params.num_recv_frames * MAX_ETHERNET_MTU);
        UHD_LOG_TRACE("UDP",
            "Using default value for recv_buff_size" << xport_params.recv_buff_size);
    }
    if (xport_params.send_buff_size == 0) {
        UHD_LOG_TRACE("UDP", "default_buff_args has no send_buff_size");
        xport_params.send_buff_size = std::max(UDP_ZERO_COPY_DEFAULT_BUFF_SIZE,
            xport_params.num_send_frames * MAX_ETHERNET_MTU);
    }

#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD)
    // limit default buffer size on macos to avoid the warning issued by
    // resize_buff_helper
    if (not hints.has_key("recv_buff_size")
        and xport_params.recv_buff_size > MAX_BUFF_SIZE_ETH_MACOS) {
        xport_params.recv_buff_size = MAX_BUFF_SIZE_ETH_MACOS;
    }
    if (not hints.has_key("send_buff_size")
        and xport_params.send_buff_size > MAX_BUFF_SIZE_ETH_MACOS) {
        xport_params.send_buff_size = MAX_BUFF_SIZE_ETH_MACOS;
    }
#endif

    udp_zero_copy_asio_impl::sptr udp_trans(
        new udp_zero_copy_asio_impl(addr, port, xport_params));

    // call the helper to resize send and recv buffers
    buff_params_out.recv_buff_size =
        resize_buff_helper<asio::socket_base::receive_buffer_size>(
            udp_trans, xport_params.recv_buff_size, "recv");
    buff_params_out.send_buff_size =
        resize_buff_helper<asio::socket_base::send_buffer_size>(
            udp_trans, xport_params.send_buff_size, "send");

    if (buff_params_out.recv_buff_size
        < xport_params.num_recv_frames * MAX_ETHERNET_MTU) {
        UHD_LOG_WARNING("UDP",
            "The current recv_buff_size of "
                << xport_params.recv_buff_size
                << " is less than the minimum recommended size of "
                << xport_params.num_recv_frames * MAX_ETHERNET_MTU
                << " and may result in dropped packets on some NICs");
    }
    if (buff_params_out.send_buff_size
        < xport_params.num_send_frames * MAX_ETHERNET_MTU) {
        UHD_LOG_WARNING("UDP",
            "The current send_buff_size of "
                << xport_params.send_buff_size
                << " is less than the minimum recommended size of "
                << xport_params.num_send_frames * MAX_ETHERNET_MTU
                << " and may result in dropped packets on some NICs");
    }

    return udp_trans;
}
Exemplo n.º 12
0
static void x300_setup_session(x300_session_t& session,
    const device_addr_t& args,
    const std::string& filepath,
    const std::string& outpath)
{
    device_addrs_t devs = x300_find(args);
    if (devs.size() == 0) {
        session.found = false;
        return;
    } else if (devs.size() > 1) {
        std::string err_msg =
            "Could not resolve given args to a single X-Series device.\n"
            "Applicable devices:\n";

        for (const uhd::device_addr_t& dev : devs) {
            std::string identifier = dev.has_key("addr") ? "addr" : "resource";

            err_msg += str(boost::format(" * %s (%s=%s)\n") % dev.get("product", "X3XX")
                           % identifier % dev.get(identifier));
        }

        err_msg += "\nSpecify one of these devices with the given args to load an image "
                   "onto it.";

        throw uhd::runtime_error(err_msg);
    }

    session.found    = true;
    session.dev_addr = devs[0];
    session.ethernet = session.dev_addr.has_key("addr");
    if (session.ethernet) {
        session.ip_addr     = session.dev_addr["addr"];
        session.configure   = args.has_key("configure");
        session.write_xport = udp_simple::make_connected(
            session.ip_addr, BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT));
        session.read_xport = udp_simple::make_connected(
            session.ip_addr, BOOST_STRINGIZE(X300_FPGA_READ_UDP_PORT));
        session.verify   = args.has_key("verify");
        session.download = args.has_key("download");
    } else {
        session.resource = session.dev_addr["resource"];
        session.rpc_port = args.get("rpc-port", "5444");
    }

    /*
     * The user can specify an FPGA type (1G, HGS, XGS), 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.
     */
    session.fpga_type = args.get("fpga", session.dev_addr.get("fpga", ""));
    if (filepath == "") {
        if (!session.dev_addr.has_key("product") or session.fpga_type == "") {
            throw uhd::runtime_error(
                "Found a device but could not auto-generate an image filename.");
        } else {
            std::string fpga_file_type = to_lower_copy(session.dev_addr["product"]);
            if (fpga_file_type == "ni-2974") {
                fpga_file_type = "x310";
            }
            session.filepath = find_image_path(
                str(boost::format("usrp_%s_fpga_%s.bit")
                    % fpga_file_type % session.fpga_type));
        }
    } else
        session.filepath = filepath;

    /*
     * The user can specify an output image path, or UHD will use the
     * system temporary path by default
     */
    if (outpath == "") {
        if (!session.dev_addr.has_key("product") or session.fpga_type == "") {
            throw uhd::runtime_error(
                "Found a device but could not auto-generate an image filename.");
        }
        std::string filename =
            str(boost::format("usrp_%s_fpga_%s")
                % (to_lower_copy(session.dev_addr["product"])) % session.fpga_type);

        session.outpath = get_tmp_path() + "/" + filename;
    } else {
        session.outpath = outpath;
    }

    // Validate image
    x300_validate_image(session);
}
Exemplo n.º 13
0
/******************************************************************************
 * 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() << "'");
    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);
    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");
    } catch (const uhd::runtime_error& e) {
        UHD_LOG_ERROR("MPMD", e.what());
    } catch (...) {
        UHD_LOG_DEBUG("MPMD",
            "Unexpected exception when trying to query device info. Flagging "
            "device as unreachable.");
        return boost::optional<device_addr_t>();
    }
    // 2) Check for local device
    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);
    }
    // 3) Check for network-reachable device
    // Note: This makes the assumption that devices will always allow RPC
    // connections on their CHDR addresses.
    const std::vector<std::string> addr_keys = {"second_addr", "addr"};
    for (const auto& addr_key : addr_keys) {
        if (not device_info_dict.count(addr_key)) {
            continue;
        }
        const std::string chdr_addr = device_info_dict.at(addr_key);
        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));
            if (!is_pingable(chdr_addr, mpm_discovery_port)) {
                UHD_LOG_TRACE("MPMD", "Cannot MPM ping, assuming device is unreachable.");
                continue;
            }
            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");
            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"]);
                return boost::optional<device_addr_t>();
            } else {
                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;
            return boost::optional<device_addr_t>(device_addr_copy);
        } catch (...) {
            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.");
    return boost::optional<device_addr_t>();
}
Exemplo n.º 14
0
/***********************************************************************
 * Multi USRP Clock factory function
 **********************************************************************/
multi_usrp_clock::sptr multi_usrp_clock::make(const device_addr_t &dev_addr){
    UHD_LOG << "multi_usrp_clock::make with args " << dev_addr.to_pp_string() << std::endl;
    return sptr(new multi_usrp_clock_impl(dev_addr));
}
Exemplo n.º 15
0
/***********************************************************************
 * Structors
 **********************************************************************/
usrp2_mboard_impl::usrp2_mboard_impl(
    size_t index,
    transport::udp_simple::sptr ctrl_transport,
    transport::zero_copy_if::sptr data_transport,
    transport::zero_copy_if::sptr err0_transport,
    const device_addr_t &device_args,
    size_t recv_samps_per_packet
):
    _index(index),
    _iface(usrp2_iface::make(ctrl_transport))
{
    //Send a small data packet so the usrp2 knows the udp source port.
    //This setup must happen before further initialization occurs
    //or the async update packets will cause ICMP destination unreachable.
    transport::managed_send_buffer::sptr send_buff;
    static const boost::uint32_t data[2] = {
        uhd::htonx(boost::uint32_t(0 /* don't care seq num */)),
        uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER))
    };
    send_buff = data_transport->get_send_buff();
    std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
    send_buff->commit(sizeof(data));
    send_buff = err0_transport->get_send_buff();
    std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
    send_buff->commit(sizeof(data));

    //contruct the interfaces to mboard perifs
    _clock_ctrl = usrp2_clock_ctrl::make(_iface);
    _codec_ctrl = usrp2_codec_ctrl::make(_iface);
//    _gps_ctrl = gps_ctrl::make(
//        _iface->get_gps_write_fn(),
//        _iface->get_gps_read_fn());

    //if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl;

    //TODO move to dsp impl...
    //load the allowed decim/interp rates
    //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
    _allowed_decim_and_interp_rates.clear();
    for (size_t i = 4; i <= 128; i+=1){
        _allowed_decim_and_interp_rates.push_back(i);
    }
    for (size_t i = 130; i <= 256; i+=2){
        _allowed_decim_and_interp_rates.push_back(i);
    }
    for (size_t i = 260; i <= 512; i+=4){
        _allowed_decim_and_interp_rates.push_back(i);
    }

    //setup the vrt rx registers
    _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //reset
    _iface->poke32(_iface->regs.rx_ctrl_nsamps_per_pkt, recv_samps_per_packet);
    _iface->poke32(_iface->regs.rx_ctrl_nchannels, 1);
    _iface->poke32(_iface->regs.rx_ctrl_vrt_header, 0
        | (0x1 << 28) //if data with stream id
        | (0x1 << 26) //has trailer
        | (0x3 << 22) //integer time other
        | (0x1 << 20) //fractional time sample count
    );
    _iface->poke32(_iface->regs.rx_ctrl_vrt_stream_id, usrp2_impl::RECV_SID);
    _iface->poke32(_iface->regs.rx_ctrl_vrt_trailer, 0);
    _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq()));

    //init the tx control registers
    _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset
    _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0);    //1 channel
    _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID);
    _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET);

    //setting the cycles per update (disabled by default)
    const double ups_per_sec = device_args.cast<double>("ups_per_sec", 0.0);
    if (ups_per_sec > 0.0){
        const size_t cycles_per_up = size_t(_clock_ctrl->get_master_clock_rate()/ups_per_sec);
        _iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, U2_FLAG_TX_CTRL_UP_ENB | cycles_per_up);
    }

    //setting the packets per update (enabled by default)
    const double ups_per_fifo = device_args.cast<double>("ups_per_fifo", 8.0);
    if (ups_per_fifo > 0.0){
        const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/data_transport->get_send_frame_size());
        _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up);
    }

    //init the ddc
    init_ddc_config();

    //init the duc
    init_duc_config();

    //initialize the clock configuration
    if (device_args.has_key("mimo_mode")){
        if (device_args["mimo_mode"] == "master"){
            _mimo_clocking_mode_is_master = true;
        }
        else if (device_args["mimo_mode"] == "slave"){
            _mimo_clocking_mode_is_master = false;
        }
        else throw std::runtime_error(
            "mimo_mode must be set to master or slave"
        );
    }
    else {
        _mimo_clocking_mode_is_master = (_iface->peek32(_iface->regs.status) & (1 << 8)) != 0;
    }
    std::cout << boost::format("mboard%d MIMO %s") % _index %
        (_mimo_clocking_mode_is_master?"master":"slave") << std::endl;

    //init the clock config
    _clock_config = clock_config_t::internal();
    update_clock_config();

    //init the codec before the dboard
    codec_init();

    //init the tx and rx dboards (do last)
    dboard_init();

    //set default subdev specs
    (*this)[MBOARD_PROP_RX_SUBDEV_SPEC] = subdev_spec_t();
    (*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t();

    //This is a hack/fix for the lingering packet problem.
    stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    stream_cmd.num_samps = 1;
    this->issue_ddc_stream_cmd(stream_cmd);
    data_transport->get_recv_buff().get(); //recv with timeout for lingering
    data_transport->get_recv_buff().get(); //recv with timeout for expected
    _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //resets sequence
}