[USRP-users] USRP x310 with multi_usrp and RFNoC

Armin Schmidt schmiar at gmail.com
Tue Feb 19 05:40:43 EST 2019


Hallo,
We're about to migrate from multi-usrp-application with UHD 3.9 and custome
FPGA to UHD 3.14 with RFNoC. We are using the USRP x310 with daughterboards
ubx-160. Everything seems to work fine except that when we stop our
application in the terminal with ctrl-c, a new startup is only possible
after a powercycle of all USRP's.
The problem is, that we can connect our RFNoC-blocks and start streaming,
but without a powercycle the recv() function starts after several
successfully received packets to produce continuously the following error
and hangs in this state:
[ERROR] [STREAMER] The receive packet handler failed to time-align packets.
1002 received packets were processed by the handler.
However, a timestamp match could not be determined.

For me it is not clear, where to search for the problem. We set sudo sysctl
net.core.rmem_max=33554432.

Following our code for initializing the USRPS and RFNoC:

//=======================
    //Setup a RX usrp device:
    //=======================
    multiUSRP =
uhd::usrp::multi_usrp::make(parser.value("args").toStdString());
//create multi-USRP

    QThread::sleep(1);  //allow for some setup-time

    if(parser.value("args") == "")  //show default values
    {
        uhd::device_addr_t hint("");
        std::vector<uhd::device_addr_t> addresses =
((multiUSRP->get_device())->find(hint));
        QString address =
QString::fromUtf8((addresses[0].to_string()).c_str());
        QStringList addressList = address.split(",");
        QString args = addressList[0] + ",";

        for(int i = 0; i < addresses.size(); i++)
        {
            address = QString::fromUtf8((addresses[i].to_string()).c_str());
            addressList = address.split(",");
            args += "addr" + QString::number(i) + "=" +
(addressList[1].split("="))[1] + ",";
        }

        args += "master_clock_rate=" +
QString::number(multiUSRP->get_master_clock_rate());

        qInfo() << endl << "Creating the RX usrp device with: " << args;
    }

    else
    {
        qInfo() << endl << "Creating the RX usrp device with: " <<
parser.value("args");
    }

    usrpDevice = multiUSRP->get_device3();
    usrpDevice->clear();    //reset device streaming state (resets blocks
after a stream)

    //======================
    //Create block controls:
    //======================
    std::vector<std::string> blocks;
    std::string agc0_id, ddc0_id, psd0_id, agc1_id, ddc1_id, psd1_id,
radio_args, agc_args, ddc_args, streamargs;
    ddc0_id = "DDC_0";

    //Initialize Radio-blocks:
    //========================
    QStringList rx_channel_strings = (parser.value("channels")).split(",");
    numChannels = rx_channel_strings.size();
    QVector<uhd::rfnoc::radio_ctrl::sptr> radio_ctrls;

    qInfo() << endl;

    //initializes all m radio controls:
    for(int i = 0; i < numChannels; i++)
    {
        uhd::rfnoc::block_id_t radio_ctrl_id(qFloor(i/2), "Radio", (i %
2)); //create on USRP x the radio object for channel 0 or 1

radio_ctrls.append(usrpDevice->get_block_ctrl<uhd::rfnoc::radio_ctrl>(radio_ctrl_id));
//this line will faile, if radio is not available

        qInfo() << "Using USRP: " << qFloor(i/2) << ", channel: " << (i %
2) << endl;
    }

    //radio_ctrl->set_args(radio_args);

    //Set clock-source:
    /*for(int i = 0; i < numChannels; i++)
    {
        radio_ctrls[i]->set_time_source("external");
        radio_ctrls[i]->set_clock_source("external");
    }*/
    //radio_ctrls[0]->set_time_next_pps()

    multiUSRP->set_time_source("external");
    multiUSRP->set_clock_source("external");
    multiUSRP->set_time_unknown_pps(uhd::time_spec_t(0.0));
    QThread::sleep(1); //wait for pps sync pulse

    //check time synchronization across all motherboards
    if (multiUSRP->get_time_synchronized())
    {
        qInfo() << endl << "Time Synchronization across all Motherboards
done";
    }

    else
    {
        qInfo() << endl << "Time Synchronization across all Motherboards
failed";
        throw "Time Synchronization across all Motherboards failed";
    }

    //set the RX-antenna:
    for(int i = 0; i < numChannels; i++)
    {
        radio_ctrls[i]->set_rx_antenna("RX2", 0);
    }

    QThread::sleep(1);  //allow for some setup-time

    //this->set_rx_gain((parser.value("gain")).toDouble());
    //this->set_rx_freq((parser.value("freq")).toDouble());


    //=================
    //Set-up streaming:
    //=================
    uhd::device_addr_t streamer_args(streamargs);
    std::vector<size_t> rx_channel_nums;

    rx_graph = usrpDevice->create_graph("rx_graph");

    for(int i = 0; i < numChannels; i++)
    {
        /*
        //Check if agc0-block is available:
        if(!usrpDevice->has_block(agc0_id))
        {
            qInfo() << endl << "AGC-block does not exist on current
device!" << endl;
        }

        uhd::rfnoc::source_block_ctrl_base::sptr agc0_block_ctrl =
usrpDevice->get_block_ctrl<uhd::rfnoc::source_block_ctrl_base>(agc0_id);
        agc0_block_ctrl->set_args(uhd::device_addr_t(agc_args)); //set
arguments of agc
        rx_graph->connect(radio_ctrl_id, channel_Nr,
agc0_block_ctrl->get_block_id(), 0);   //connect channel0 from radio with
agc0
        */


        //Radio -> DDC:
        //=============

        //Check if ddc-block is available on current device:

if(!usrpDevice->has_block(uhd::rfnoc::block_id_t(std::to_string(qFloor(i/2))
+ "/DDC_" + std::to_string(i % 2))))
        {
            qInfo() << endl << "DDC-block " + QString::number(i % 2) + "
does not exist on device " + QString::number(qFloor(i/2)) + "!" << endl;
            throw "DDC-block " + QString::number(i % 2) + " does not exist
on device " + QString::number(qFloor(i/2)) + "!";
        }

        uhd::rfnoc::source_block_ctrl_base::sptr ddc_block_ctrl =
usrpDevice->get_block_ctrl<uhd::rfnoc::source_block_ctrl_base>(uhd::rfnoc::block_id_t(std::to_string(qFloor(i/2))
+ "/DDC_" + std::to_string(i % 2)));


ddc_block_ctrl->set_args(uhd::device_addr_t("freq=0,input_rate=184320000,output_rate=46080000"));
//set arguments of ddc
        rx_graph->connect(radio_ctrls[i]->get_block_id(), 0,
ddc_block_ctrl->get_block_id(), 0, 1);   //connect radio with ddc


        //DDC -> PSD:
        //===========

        //Check if psd-block is available:

if(!usrpDevice->has_block(uhd::rfnoc::block_id_t(std::to_string(qFloor(i/2))
+ "/PSD_" + std::to_string(i % 2))))
        {
            qInfo() << endl << "PSD-block " + QString::number(i % 2) + "
does not exist on device " + QString::number(qFloor(i/2)) + "!" << endl;
            throw "PSD-block " + QString::number(i % 2) + " does not exist
on device " + QString::number(qFloor(i/2)) + "!";
        }

        uhd::rfnoc::source_block_ctrl_base::sptr psd_block_ctrl =
usrpDevice->get_block_ctrl<uhd::rfnoc::source_block_ctrl_base>(std::to_string(qFloor(i/2))
+ "/PSD_" + std::to_string(i % 2));
        rx_graph->connect(ddc_block_ctrl->get_block_id(), 0,
psd_block_ctrl->get_block_id(), 0, 1);   //connect ddc with psd

        streamer_args["block_id" + std::to_string(i)] =
psd_block_ctrl->get_block_id().to_string();    //connects psd to stream
        streamer_args["block_port" + std::to_string(i)] = "0";
        rx_channel_nums.push_back(i);
    }

    samps_per_buff = 256;
    this->createNewBuffers();   //prepare buffer for streamed data

    //Create a receive streamer:
    uhd::stream_args_t stream_args("sc16", "sc16");
    stream_args.channels = rx_channel_nums;
    stream_args.args = streamer_args;
    stream_args.args["spp"] = boost::lexical_cast<std::string>(256);
    rx_stream = usrpDevice->get_rx_stream(stream_args);

    qInfo() << endl << "Begin continuous streaming in " <<
parser.value("secs") << " seconds...";

    stream_cmd = QSharedPointer<uhd::stream_cmd_t>(new
uhd::stream_cmd_t(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS));

    stream_cmd->stream_now = false; //controls, when the stream begins.
When false, the device will begin streaming at a time specified by time_spec
    stream_cmd->time_spec =
uhd::time_spec_t(((parser.value("secs")).toDouble()) *
multiUSRP->get_num_mboards());
    rx_stream->issue_stream_cmd(*stream_cmd); //tells all channels to stream
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/attachments/20190219/cbade734/attachment.html>


More information about the USRP-users mailing list