From 652873b664393120b284e3303f82f80c7a1f4f9a Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Fri, 17 Sep 2021 11:24:02 +0200 Subject: examples: Improve txrx_loopback_to_file (late recv, Boost, timing) - Fixes a bug where the RX stream command set set independent of the device time. Now, we read back get_time_now() to calculate the command time. - When using multiple RX USRPs, sync their times. Before, they were left untouched, causing possible timing mismatches. - Increase the initial timeout value. The previous value had only been tested with N2x0. - Replace the boost::thread_group with a std::thread. - Remove some boost::format where it didn't add value. --- host/examples/txrx_loopback_to_file.cpp | 40 ++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/host/examples/txrx_loopback_to_file.cpp b/host/examples/txrx_loopback_to_file.cpp index 0dc489063..e58d5ecc3 100644 --- a/host/examples/txrx_loopback_to_file.cpp +++ b/host/examples/txrx_loopback_to_file.cpp @@ -16,12 +16,12 @@ #include #include #include -#include #include #include #include #include #include +#include namespace po = boost::program_options; @@ -55,7 +55,7 @@ std::string generate_out_filename( /*********************************************************************** * transmit_worker function - * A function to be used as a boost::thread_group thread for transmitting + * A function to be used in a thread for transmitting **********************************************************************/ void transmit_worker(std::vector> buff, wave_table_class wave_table, @@ -127,8 +127,10 @@ void recv_to_file(uhd::usrp::multi_usrp::sptr usrp, UHD_ASSERT_THROW(outfiles.size() == buffs.size()); UHD_ASSERT_THROW(buffs.size() == rx_channel_nums.size()); bool overflow_message = true; - double timeout = - settling_time + 0.1f; // expected settling time + padding for first recv + // We increase the first timeout to cover for the delay between now + the + // command time, plus 500ms of buffer. In the loop, we will then reduce the + // timeout for subsequent receives. + double timeout = settling_time + 0.5f; // setup streaming uhd::stream_cmd_t stream_cmd((num_requested_samples == 0) @@ -136,7 +138,7 @@ void recv_to_file(uhd::usrp::multi_usrp::sptr usrp, : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = num_requested_samples; stream_cmd.stream_now = false; - stream_cmd.time_spec = uhd::time_spec_t(settling_time); + stream_cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(settling_time); rx_stream->issue_stream_cmd(stream_cmd); while (not stop_signal_called @@ -145,7 +147,7 @@ void recv_to_file(uhd::usrp::multi_usrp::sptr usrp, timeout = 0.1f; // small timeout for subsequent recv if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { - std::cout << boost::format("Timeout while streaming") << std::endl; + std::cout << "Timeout while streaming" << std::endl; break; } if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { @@ -163,8 +165,7 @@ void recv_to_file(uhd::usrp::multi_usrp::sptr usrp, continue; } if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { - throw std::runtime_error( - str(boost::format("Receiver error %s") % md.strerror())); + throw std::runtime_error("Receiver error " + md.strerror()); } num_total_samps += num_rx_samps; @@ -243,7 +244,7 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) // print the help message if (vm.count("help")) { - std::cout << boost::format("UHD TXRX Loopback to File %s") % desc << std::endl; + std::cout << "UHD TXRX Loopback to File " << desc << std::endl; return ~0; } @@ -291,10 +292,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) rx_usrp->set_clock_source(ref); } - std::cout << boost::format("Using TX Device: %s") % tx_usrp->get_pp_string() - << std::endl; - std::cout << boost::format("Using RX Device: %s") % rx_usrp->get_pp_string() - << std::endl; + std::cout << "Using TX Device: " << tx_usrp->get_pp_string() << std::endl; + std::cout << "Using RX Device: " << rx_usrp->get_pp_string() << std::endl; // set the transmit sample rate if (not vm.count("tx-rate")) { @@ -423,6 +422,11 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) rx_usrp->set_rx_antenna(rx_ant, channel); } + // Align times in the RX USRP (the TX USRP does not require time-syncing) + if (rx_usrp->get_num_mboards() > 1) { + rx_usrp->set_time_unknown_pps(uhd::time_spec_t(0.0)); + } + // for the const wave, set the wave freq for small samples per period if (wave_freq == 0 and wave_type == "CONST") { wave_freq = tx_usrp->get_tx_rate() / 2; @@ -525,9 +529,9 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) tx_usrp->set_time_now(uhd::time_spec_t(0.0)); // start transmit worker thread - boost::thread_group transmit_thread; - transmit_thread.create_thread(std::bind( - &transmit_worker, buff, wave_table, tx_stream, md, step, index, num_channels)); + std::thread transmit_thread([&]() { + transmit_worker(buff, wave_table, tx_stream, md, step, index, num_channels); + }); // recv to file if (type == "double") @@ -542,13 +546,13 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) else { // clean up transmit worker stop_signal_called = true; - transmit_thread.join_all(); + transmit_thread.join(); throw std::runtime_error("Unknown type " + type); } // clean up transmit worker stop_signal_called = true; - transmit_thread.join_all(); + transmit_thread.join(); // finished std::cout << std::endl << "Done!" << std::endl << std::endl; -- cgit v1.2.3