From 1488781b091484d52e7c9b96115b0ab5a9b3e957 Mon Sep 17 00:00:00 2001 From: michael-west Date: Thu, 15 Apr 2021 23:51:25 -0700 Subject: utils: Improve cal TX threads Increase thread priority on TX thread and remove memory copy to reduce underruns. Signed-off-by: michael-west --- host/utils/uhd_cal_rx_iq_balance.cpp | 43 +++-------------- host/utils/uhd_cal_tx_dc_offset.cpp | 51 +++---------------- host/utils/uhd_cal_tx_iq_balance.cpp | 50 +++---------------- host/utils/usrp_cal_utils.hpp | 94 ++++++++++++++++++++++++++---------- 4 files changed, 86 insertions(+), 152 deletions(-) (limited to 'host/utils') diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp index ff074acef..8b9ada1a4 100644 --- a/host/utils/uhd_cal_rx_iq_balance.cpp +++ b/host/utils/uhd_cal_rx_iq_balance.cpp @@ -10,11 +10,8 @@ #include #include #include -#include #include -#include #include -#include #include #include #include @@ -22,37 +19,9 @@ #include #include #include -#include namespace po = boost::program_options; -/*********************************************************************** - * Transmit thread - **********************************************************************/ -static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, - uhd::tx_streamer::sptr tx_stream, - const double tx_wave_ampl) -{ - // set max TX gain - usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); - - // setup variables and allocate buffer - uhd::tx_metadata_t md; - md.has_time_spec = false; - std::vector buff(tx_stream->get_max_num_samps() * 10); - - // fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) { - for (size_t i = 0; i < buff.size(); i++) - buff[i] = float(tx_wave_ampl); - tx_stream->send(&buff.front(), buff.size(), md); - } - - // send a mini EOB packet - md.end_of_burst = true; - tx_stream->send("", 0, md); -} - /*********************************************************************** * Tune RX and TX routine **********************************************************************/ @@ -142,8 +111,10 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); // create a transmitter thread - boost::thread_group threads; - threads.create_thread(std::bind(&tx_thread, usrp, tx_stream, tx_wave_ampl)); + std::atomic_flag transmit = ATOMIC_FLAG_INIT; + transmit.test_and_set(); + auto transmitter = + std::thread(std::bind(&tx_thread, &transmit, usrp, tx_stream, 0.0, tx_wave_ampl)); // re-usable buffer for samples std::vector buff; @@ -292,10 +263,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) std::cout << std::endl; // stop the transmitter - threads.interrupt_all(); - std::this_thread::sleep_for( - std::chrono::milliseconds(500)); // wait for threads to finish - threads.join_all(); + transmit.clear(); + transmitter.join(); store_results(results, "RX", "rx", "iq", serial); diff --git a/host/utils/uhd_cal_tx_dc_offset.cpp b/host/utils/uhd_cal_tx_dc_offset.cpp index 9a0a3bb77..cb97fca29 100644 --- a/host/utils/uhd_cal_tx_dc_offset.cpp +++ b/host/utils/uhd_cal_tx_dc_offset.cpp @@ -10,54 +10,16 @@ #include #include #include -#include #include -#include #include -#include #include #include #include #include #include -#include namespace po = boost::program_options; -/*********************************************************************** - * Transmit thread - **********************************************************************/ -static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, - uhd::tx_streamer::sptr tx_stream, - const double tx_wave_freq, - const double tx_wave_ampl) -{ - // set max TX gain - usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); - - // setup variables and allocate buffer - uhd::tx_metadata_t md; - md.has_time_spec = false; - std::vector buff(tx_stream->get_max_num_samps() * 10); - - // values for the wave table lookup - size_t index = 0; - const double tx_rate = usrp->get_tx_rate(); - const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); - wave_table table(tx_wave_ampl); - - // fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) { - for (size_t i = 0; i < buff.size(); i++) - buff[i] = table(index += step); - tx_stream->send(&buff.front(), buff.size(), md); - } - - // send a mini EOB packet - md.end_of_burst = true; - tx_stream->send("", 0, md); -} - /*********************************************************************** * Tune RX and TX routine **********************************************************************/ @@ -148,9 +110,10 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); // create a transmitter thread - boost::thread_group threads; - threads.create_thread( - std::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); + std::atomic_flag transmit = ATOMIC_FLAG_INIT; + transmit.test_and_set(); + auto transmitter = std::thread( + std::bind(&tx_thread, &transmit, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); // re-usable buffer for samples std::vector buff; @@ -290,10 +253,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) std::cout << std::endl; // stop the transmitter - threads.interrupt_all(); - std::this_thread::sleep_for( - std::chrono::milliseconds(500)); // wait for threads to finish - threads.join_all(); + transmit.clear(); + transmitter.join(); store_results(results, "TX", "tx", "dc", serial); diff --git a/host/utils/uhd_cal_tx_iq_balance.cpp b/host/utils/uhd_cal_tx_iq_balance.cpp index 5f2695784..5c9f981c9 100644 --- a/host/utils/uhd_cal_tx_iq_balance.cpp +++ b/host/utils/uhd_cal_tx_iq_balance.cpp @@ -7,54 +7,17 @@ #include "usrp_cal_utils.hpp" #include -#include #include #include -#include #include #include #include #include #include #include -#include namespace po = boost::program_options; -/*********************************************************************** - * Transmit thread - **********************************************************************/ -static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, - uhd::tx_streamer::sptr tx_stream, - const double tx_wave_freq, - const double tx_wave_ampl) -{ - // set max TX gain - usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); - - // setup variables and allocate buffer - uhd::tx_metadata_t md; - md.has_time_spec = false; - std::vector buff(tx_stream->get_max_num_samps() * 10); - - // values for the wave table lookup - size_t index = 0; - const double tx_rate = usrp->get_tx_rate(); - const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); - wave_table table(tx_wave_ampl); - - // fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) { - for (size_t i = 0; i < buff.size(); i++) - buff[i] = table(index += step); - tx_stream->send(&buff.front(), buff.size(), md); - } - - // send a mini EOB packet - md.end_of_burst = true; - tx_stream->send("", 0, md); -} - /*********************************************************************** * Tune RX and TX routine **********************************************************************/ @@ -145,9 +108,10 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); // create a transmitter thread - boost::thread_group threads; - threads.create_thread( - std::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); + std::atomic_flag transmit = ATOMIC_FLAG_INIT; + transmit.test_and_set(); + auto transmitter = std::thread( + std::bind(&tx_thread, &transmit, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); // re-usable buffer for samples std::vector buff; @@ -292,10 +256,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) std::cout << std::endl; // stop the transmitter - threads.interrupt_all(); - std::this_thread::sleep_for( - std::chrono::milliseconds(500)); // wait for threads to finish - threads.join_all(); + transmit.clear(); + transmitter.join(); store_results(results, "TX", "tx", "iq", serial); diff --git a/host/utils/usrp_cal_utils.hpp b/host/utils/usrp_cal_utils.hpp index c0b9b115e..1b9df9d03 100644 --- a/host/utils/usrp_cal_utils.hpp +++ b/host/utils/usrp_cal_utils.hpp @@ -11,9 +11,11 @@ #include #include #include +#include #include +#include +#include #include -#include #include #include #include @@ -31,8 +33,7 @@ typedef std::complex samp_type; /*********************************************************************** * Constants **********************************************************************/ -static const double tau = 6.28318531; -static const size_t wave_table_len = 65536; +static const double tau = 2 * uhd::math::PI; static const size_t num_search_steps = 5; static const double default_precision = 0.0001; static const double default_freq_step = 7.3e6; @@ -125,28 +126,6 @@ void check_for_empty_serial(uhd::usrp::multi_usrp::sptr usrp) } } -/*********************************************************************** - * Sinusoid wave table - **********************************************************************/ -class wave_table -{ -public: - wave_table(const double ampl) - { - _table.resize(wave_table_len); - for (size_t i = 0; i < wave_table_len; i++) - _table[i] = samp_type(std::polar(ampl, (tau * i) / wave_table_len)); - } - - inline samp_type operator()(const size_t index) const - { - return _table[index % wave_table_len]; - } - -private: - std::vector _table; -}; - /*********************************************************************** * Compute power of a tone **********************************************************************/ @@ -173,7 +152,6 @@ static inline void write_samples_to_file( outfile.close(); } - /*********************************************************************** * Store data to file **********************************************************************/ @@ -347,6 +325,70 @@ UHD_INLINE void set_optimal_rx_gain(uhd::usrp::multi_usrp::sptr usrp, usrp->set_rx_gain(rx_gain); } +/*********************************************************************** + * Transmit thread + **********************************************************************/ +static void tx_thread(std::atomic_flag* transmit, + uhd::usrp::multi_usrp::sptr usrp, + uhd::tx_streamer::sptr tx_stream, + const double tx_wave_freq, + const double tx_wave_ampl) +{ + // increase thread priority for TX to prevent underruns + uhd::set_thread_priority(); + + // set max TX gain + usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); + + // setup variables + uhd::tx_metadata_t md; + md.has_time_spec = false; + const double tx_rate = usrp->get_tx_rate(); + const size_t frame_size = tx_stream->get_max_num_samps(); + + // set up buffer + // make buffer size of 1 second aligned to a complete wave + // to provide accuracy down to 1 Hz with no discontinuity + const size_t buff_size = + tx_wave_freq == 0.0 + ? frame_size + : static_cast(tx_rate) + - static_cast((tx_wave_freq - static_cast(tx_wave_freq)) + * tx_rate / tx_wave_freq); + // Since send calls are aligned to the frame size, make the buffer 1 frame + // larger to prevent an overrun when it reaches the end and wraps around. + std::vector buff(buff_size + frame_size); + + // fill buffer + for (size_t i = 0; i < buff.size(); i++) { + if (tx_wave_freq == 0.0) { + // fill with constant value + buff[i] = samp_type(static_cast(tx_wave_ampl), 0.0); + } else { + // fill with sine waves + buff[i] = + samp_type(std::polar(tx_wave_ampl, (tau * i * tx_wave_freq / tx_rate))); + } + } + + // send until stopped + size_t index = 0; + while (transmit->test_and_set()) { + // send calls are aligned to the frame size for optimal performance + tx_stream->send(&buff[index], frame_size, md); + + // increment index + index += frame_size; + + // wrap around at end of buffer + // (actual buffer size is 1 frame larger to prevent overrun) + index %= buff_size; + } + + // send a mini EOB packet + md.end_of_burst = true; + tx_stream->send("", 0, md); +} /*! Returns true if any error on the TX stream has occurred */ -- cgit v1.2.3