aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils/latency/include/Responder.hpp
diff options
context:
space:
mode:
authorBalint Seeber <balint@ettus.com>2014-10-01 17:20:20 -0700
committerMartin Braun <martin.braun@ettus.com>2014-10-09 10:50:37 +0200
commit15740bcc3b3e1d5adff8c77306d84741a26ebdad (patch)
tree29aba02634aaf58079064084d8bb2cc3fa5c319e /host/utils/latency/include/Responder.hpp
parentea5c8a39e43913e29936acde89745a7cdf5b18a8 (diff)
downloaduhd-15740bcc3b3e1d5adff8c77306d84741a26ebdad.tar.gz
uhd-15740bcc3b3e1d5adff8c77306d84741a26ebdad.tar.bz2
uhd-15740bcc3b3e1d5adff8c77306d84741a26ebdad.zip
utils: Added latency measurement utility
Diffstat (limited to 'host/utils/latency/include/Responder.hpp')
-rw-r--r--host/utils/latency/include/Responder.hpp299
1 files changed, 299 insertions, 0 deletions
diff --git a/host/utils/latency/include/Responder.hpp b/host/utils/latency/include/Responder.hpp
new file mode 100644
index 000000000..a9f616a24
--- /dev/null
+++ b/host/utils/latency/include/Responder.hpp
@@ -0,0 +1,299 @@
+//
+// Copyright 2010-2013 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef RESPONDER_H
+#define RESPONDER_H
+
+#include <curses.h>
+#include <map>
+#include <ctime>
+#include <stdint.h>
+
+#include <uhd/usrp/multi_usrp.hpp>
+#include <uhd/utils/msg.hpp>
+
+using namespace std;
+
+
+class Responder
+{
+ public:
+ enum ReturnCodes
+ {
+ RETCODE_OK = 0,
+ RETCODE_BAD_ARGS = -1,
+ RETCODE_RUNTIME_ERROR = -2,
+ RETCODE_UNKNOWN_EXCEPTION = -3,
+ RETCODE_RECEIVE_TIMEOUT = -4,
+ RETCODE_RECEIVE_FAILED = -5,
+ RETCODE_MANUAL_ABORT = -6,
+ RETCODE_BAD_PACKET = -7,
+ RETCODE_OVERFLOW = -8
+ };
+
+ struct Options
+ {
+ string device_args;
+ double delay;
+ double sample_rate;
+ double trigger_level;
+ float output_scale;
+ double response_duration;
+ double dc_offset_delay;
+ double init_delay;
+ double timeout;
+ size_t samps_per_buff;
+ size_t samps_per_packet;
+ double level_calibration_duration;
+ std::string test_title;
+ std::string stats_filename;
+ std::string stats_filename_prefix;
+ std::string stats_filename_suffix;
+ double delay_min;
+ double delay_max;
+ double delay_step;
+ double pulse_detection_threshold;
+ uint64_t test_iterations;
+ size_t end_test_after_success_count;
+ size_t skip_iterations;
+ double simulate_frequency;
+ double time_mul;
+ size_t flush_count;
+ size_t optimize_padding;
+ double rt_priority;
+ bool ignore_simulation_check;
+ bool test_iterations_is_sample_count;
+ bool skip_eob;
+ bool adjust_simulation_rate;
+ bool optimize_simulation_rate;
+ bool no_stats_file;
+ bool log_file;
+ bool batch_mode;
+ bool skip_if_results_exist;
+ bool skip_send;
+ bool combine_eob;
+ bool pause;
+ bool realtime;
+ bool invert;
+ bool output_value;
+ bool no_delay;
+ bool allow_late_bursts;
+
+ uint64_t level_calibration_count() const
+ {
+ return (uint64_t)(sample_rate * level_calibration_duration);
+ }
+
+ uint64_t response_length() const
+ {
+ return (uint64_t)(sample_rate * response_duration);
+ }
+
+ uint64_t highest_delay_samples(const double delay) const
+ {
+ return (uint64_t)(delay * (double)sample_rate);
+ }
+
+ uint64_t simulate_duration(const double simulate_frequency) const
+ {
+ if(simulate_frequency > 0.0) {
+ return (uint64_t)((double)sample_rate / simulate_frequency);
+ }
+ return 0;
+ }
+ };
+
+ typedef struct Stats
+ {
+ double delay;
+ uint64_t detected;
+ uint64_t missed;
+ uint64_t skipped;
+ } STATS;
+
+ typedef std::map<uint64_t,STATS> StatsMap;
+
+ struct DebugInfo
+ {
+ time_t start_time;
+ time_t end_time;
+ time_t start_time_test;
+ time_t end_time_test;
+ time_t first_send_timeout;
+ };
+ Responder(Options& opt);
+ virtual ~Responder();
+
+ // Main entry point after constructor.
+ int run();
+
+ // Public method to inject UHD messages in the main ncurses window.
+ void print_uhd_late_handler(uhd::msg::type_t type, const std::string& msg);
+
+ int get_return_code(){return _return_code;}
+
+ protected:
+ private:
+ // These 2 variables are used for ncurses output.
+ WINDOW* _window;
+ std::stringstream _ss;
+
+ // struct which holds all arguments as constants settable from outside the class
+ const Options _opt;
+
+ string _stats_filename; // Specify name of statistics file
+ string _stats_log_filename; // Specify name for log file.
+ double _delay; // may be altered in all modes.
+ size_t _samps_per_packet; // This is one of the options of interest. Find out how well it performs.
+ double _delay_step; // may be altered in interactive mode
+ double _simulate_frequency; // updated during automatic test iterations
+
+ // additional attributes
+ bool _allow_late_bursts; // may be altered in interactive mode
+ bool _no_delay; // may be altered in interactive mode
+
+ // dependent variables
+ uint64_t _response_length;
+ int64_t _init_delay_count;
+ int64_t _dc_offset_countdown;
+ int64_t _level_calibration_countdown;
+ uint64_t _simulate_duration;
+ uint64_t _original_simulate_duration;
+
+ // these variables store test conditions
+ uint64_t _num_total_samps; // printed on exit
+ size_t _overruns; // printed on exit
+ StatsMap _mapStats; // store results
+ uint64_t _max_success; // < 0 --> write results to file
+ int _return_code;
+
+ // Hold USRP, streams and commands
+ uhd::usrp::multi_usrp::sptr _usrp;
+ uhd::tx_streamer::sptr _tx_stream;
+ uhd::rx_streamer::sptr _rx_stream;
+ uhd::stream_cmd_t _stream_cmd;
+
+ // Keep track of number of timeouts.
+ uint64_t _timeout_burst_count;
+ uint64_t _timeout_eob_count;
+
+ // Transmit attributes
+ float* _pResponse;
+
+ // Control print parameters.
+ int _y_delay_pos;
+ int _x_delay_pos; // Remember the cursor position of delay line
+ uint64_t _last_overrun_count;
+
+ // Hold debug info during test. Will be included in log file.
+ DebugInfo _dbginfo;
+
+ /*
+ * Here are the class's member methods.
+ */
+ // These methods are used for ncurses output
+ void create_ncurses_window();
+ void FLUSH_SCREEN();
+ void FLUSH_SCREEN_NL();
+
+ // Variable calculation helpers
+ inline uint64_t get_response_length(double sample_rate, double response_duration)
+ {return (uint64_t)(sample_rate * response_duration);}
+ int calculate_dependent_values();
+
+ // make sure existing results are not overwritten accidently
+ bool set_stats_filename(string test_id);
+ bool check_for_existing_results();
+
+ // Functions that may cause Responder to finish
+ void register_stop_signal_handler();
+ bool test_finished(size_t success_count);
+ int test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_test, STATS statsCurrent, size_t success_count);
+
+ // Check if sent burst could be transmitted.
+ bool tx_burst_is_late();
+
+ // Handle receiver errors such as overflows.
+ bool handle_rx_errors(uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps);
+
+ // In interactive mode, handle Responder control and output.
+ bool handle_interactive_control();
+ void print_interactive_msg(std::string msg);
+
+ // calibration important for interactive mode with 2nd USRP connected.
+ float calibrate_usrp_for_test_run();
+
+ // Run actual test
+ void run_test(float threshold = 0.0f );
+
+ // Detect falling edge
+ bool get_new_state(uint64_t total_samps, uint64_t simulate_duration, float val, float threshold);
+ uint64_t detect_respond_pulse_count(STATS &statsCurrent, std::vector<std::complex<float> > &buff, uint64_t trigger_count, size_t num_rx_samps, float threshold, uhd::time_spec_t rx_time);
+
+ // Hold test results till they are printed to a file
+ void add_stats_to_results(STATS statsCurrent, double delay);
+
+ // Control USRP and necessary streamers
+ uhd::usrp::multi_usrp::sptr create_usrp_device();
+ void set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena);
+ void stop_usrp_stream();
+ uhd::tx_streamer::sptr create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp);
+ uhd::rx_streamer::sptr create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp);
+
+ // Send burst and handle results.
+ bool send_tx_burst(uhd::time_spec_t rx_time, size_t n);
+ void handle_tx_timeout(int burst, int eob);
+ float* alloc_response_buffer_with_data(uint64_t response_length);
+ uhd::tx_metadata_t get_tx_metadata(uhd::time_spec_t rx_time, size_t n);
+
+ // Control test parameters
+ void update_and_print_parameters(const STATS& statsPrev, const double delay);
+ double get_simulate_frequency(double delay, uint64_t response_length, uint64_t original_simulate_duration);
+ double get_max_possible_frequency(uint64_t highest_delay_samples, uint64_t response_length);
+
+ // Helper methods to print status during test.
+ void print_init_test_status();
+ void print_test_title();
+ void print_usrp_status();
+ void print_create_usrp_msg();
+ void print_tx_stream_status();
+ void print_rx_stream_status();
+ void print_test_parameters();
+ void print_formatted_delay_line(const uint64_t simulate_duration, const uint64_t old_simulate_duration, const STATS& statsPrev, const double delay, const double simulate_frequency);
+ void print_overrun_msg();
+ void print_error_msg(std::string msg);
+ void print_timeout_msg();
+ void print_final_statistics();
+ void print_msg_and_wait(std::string msg);
+ void print_msg(std::string msg);
+
+ // Safe results of test to file.
+ void write_statistics_to_file(StatsMap mapStats);
+ void safe_write_statistics_to_file(StatsMap mapStats, uint64_t max_success, int return_code);
+ void write_log_file();
+
+ // Write debug info to log file if requested.
+ void write_debug_info(ofstream& logs);
+ std::string get_gmtime_string(time_t time);
+ std::string enum2str(int return_code);
+ std::vector<std::map<std::string,std::string> > read_eth_info();
+ uhd::device_addr_t get_usrp_info();
+ std::map<std::string, std::string> get_hw_info();
+ std::string get_ip_subnet_addr(std::string ip);
+};
+
+#endif // RESPONDER_H