On Tue, Feb 19, 2019 at 5:42 AM Armin Schmidt via USRP-users <
[email protected]> 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
_______________________________________________
USRP-users mailing list
[email protected]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com