[USRP-users] USRP x310 with multi_usrp and RFNoC

Armin Schmidt schmiar at gmail.com
Tue Feb 19 12:07:20 EST 2019


Thanks for your replay! Hm, yes I've thought also about to use
STREAM_MODE_STOP_CONTINUOUS, but I would like to be able to restart my app
also after a crash. Ok, it should never happen, but one can never guarantee
that case. Do you have an idea, how to deal with such cases? I think it's a
bug in UHD, because in the version 3.9 was that never a problem.



Am Di., 19. Feb. 2019 um 14:47 Uhr schrieb Brian Padalino <
bpadalino at gmail.com>:

> On Tue, Feb 19, 2019 at 5:42 AM Armin Schmidt via USRP-users <
> usrp-users at lists.ettus.com> wrote:
>
>> 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
>>
>
> What is your shutdown procedure?  Do you ever issue
> STREAM_MODE_STOP_CONTINUOUS?  I've noticed that if I don't do that, then
> the USRP is not happy in subsequent runs.  I also tend to keep receiving
> until I have multiple consecutive timeouts to ensure everything has run its
> course.
>
> If you do this already, then it is probably something somewhere else, and
> I am not sure what it might be.
>
> Brian
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/attachments/20190219/7f1ec8ac/attachment.html>


More information about the USRP-users mailing list