diff options
Diffstat (limited to 'host/examples')
| -rw-r--r-- | host/examples/benchmark_rate.cpp | 52 | ||||
| -rw-r--r-- | host/examples/init_usrp/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | host/examples/tx_bursts.cpp | 40 | ||||
| -rw-r--r-- | host/examples/tx_samples_c.c | 21 | ||||
| -rw-r--r-- | host/examples/tx_waveforms.cpp | 30 | 
5 files changed, 115 insertions, 30 deletions
| diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp index 0f01da035..b024c3a20 100644 --- a/host/examples/benchmark_rate.cpp +++ b/host/examples/benchmark_rate.cpp @@ -47,6 +47,8 @@ unsigned long long num_rx_samps = 0;  unsigned long long num_tx_samps = 0;  unsigned long long num_dropped_samps = 0;  unsigned long long num_seq_errors = 0; +unsigned long long num_late_commands = 0; +unsigned long long num_timeouts = 0;  /***********************************************************************   * Benchmark RX Rate @@ -84,10 +86,12 @@ void benchmark_rx_rate(      const float burst_pkt_time = std::max(0.100, (2 * max_samps_per_packet/rate));      float recv_timeout = burst_pkt_time + INIT_DELAY; +    bool stop_called = false;      while (true) { -        //if (burst_timer_elapsed.load(boost::memory_order_relaxed)) { -        if (burst_timer_elapsed) { +        //if (burst_timer_elapsed.load(boost::memory_order_relaxed) and not stop_called) { +        if (burst_timer_elapsed and not stop_called) {              rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); +            stop_called = true;          }          if (random_nsamps) {              cmd.num_samps = rand() % max_samps_per_packet; @@ -110,6 +114,10 @@ void benchmark_rx_rate(                  had_an_overflow = false;                  num_dropped_samps += (md.time_spec - last_time).to_ticks(rate);              } +            if ((burst_timer_elapsed or stop_called) and md.end_of_burst) +            { +                return; +            }              break;          // ERROR_CODE_OVERFLOW can indicate overflow or sequence error @@ -121,12 +129,23 @@ void benchmark_rx_rate(                  num_overflows++;              break; +        case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: +            std::cerr << "Receiver error: " << md.strerror() << ", restart streaming..."<< std::endl; +            num_late_commands++; +            // Radio core will be in the idle state. Issue stream command to restart streaming. +            cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05); +            cmd.stream_now = (buffs.size() == 1); +            rx_stream->issue_stream_cmd(cmd); +            break; +          case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: -            // If we stopped the streamer, then we expect this at some point -            //if (burst_timer_elapsed.load(boost::memory_order_relaxed)) {              if (burst_timer_elapsed) {                  return;              } +            std::cerr << "Receiver error: " << md.strerror() << ", continuing..." << std::endl; +            num_timeouts++; +            break; +              // Otherwise, it's an error          default:              std::cerr << "Receiver error: " << md.strerror() << std::endl; @@ -243,6 +262,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //variables to be set by po      std::string args; +    std::string rx_subdev, tx_subdev;      double duration;      double rx_rate, tx_rate;      std::string rx_otw, tx_otw; @@ -258,6 +278,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          ("help", "help message")          ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")          ("duration", po::value<double>(&duration)->default_value(10.0), "duration for the test in seconds") +        ("rx_subdev", po::value<std::string>(&rx_subdev), "specify the device subdev for RX") +        ("tx_subdev", po::value<std::string>(&tx_subdev), "specify the device subdev for TX")          ("rx_rate", po::value<double>(&rx_rate), "specify to perform a RX rate test (sps)")          ("tx_rate", po::value<double>(&tx_rate), "specify to perform a TX rate test (sps)")          ("rx_otw", po::value<std::string>(&rx_otw)->default_value("sc16"), "specify the over-the-wire sample mode for RX") @@ -310,6 +332,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      }      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;      uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); + +    //always select the subdevice first, the channel mapping affects the other settings +    if (vm.count("rx_subdev")) { +        usrp->set_rx_subdev_spec(rx_subdev); +    } +    if (vm.count("tx_subdev")) { +        usrp->set_tx_subdev_spec(tx_subdev); +    } +      std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl;      int num_mboards = usrp->get_num_mboards(); @@ -406,7 +437,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //sleep for the required duration      const long secs = long(duration);      const long usecs = long((duration - secs)*1e6); -    boost::this_thread::sleep(boost::posix_time::seconds(secs) + boost::posix_time::microseconds(usecs)); +    boost::this_thread::sleep(boost::posix_time::seconds(secs) +            + boost::posix_time::microseconds(usecs) +            + boost::posix_time::milliseconds( (channel_nums.size() == 1) ? 0 : (INIT_DELAY * 1000)) +    );      //interrupt and join the threads      //burst_timer_elapsed.store(true, boost::memory_order_relaxed); @@ -422,7 +456,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          "  Num transmitted samples: %u\n"          "  Num sequence errors:     %u\n"          "  Num underflows detected: %u\n" -    ) % num_rx_samps % num_dropped_samps % num_overflows % num_tx_samps % num_seq_errors % num_underflows << std::endl; +        "  Num late commands:       %u\n" +        "  Num timeouts:            %u\n" +    ) % num_rx_samps % num_dropped_samps +      % num_overflows % num_tx_samps +      % num_seq_errors % num_underflows +      % num_late_commands % num_timeouts +      << std::endl;      //finished      std::cout << std::endl << "Done!" << std::endl << std::endl; diff --git a/host/examples/init_usrp/CMakeLists.txt b/host/examples/init_usrp/CMakeLists.txt index 8705b4a8d..4ce51125f 100644 --- a/host/examples/init_usrp/CMakeLists.txt +++ b/host/examples/init_usrp/CMakeLists.txt @@ -59,7 +59,7 @@ SET(CMAKE_BUILD_TYPE "Release")  MESSAGE(STATUS "******************************************************************************")  MESSAGE(STATUS "* NOTE: When building your own app, you probably need all kinds of different  ")  MESSAGE(STATUS "* compiler flags. This is just an example, so it's unlikely these settings    ") -MESSAGE(STATUS "* exactly matchh what you require. Make sure to double-check compiler and     ") +MESSAGE(STATUS "* exactly match what you require. Make sure to double-check compiler and     ")  MESSAGE(STATUS "* linker flags to make sure your specific requirements are included.          ")  MESSAGE(STATUS "******************************************************************************") diff --git a/host/examples/tx_bursts.cpp b/host/examples/tx_bursts.cpp index bb71d4581..5ee00d5cd 100644 --- a/host/examples/tx_bursts.cpp +++ b/host/examples/tx_bursts.cpp @@ -142,7 +142,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          size_t num_acc_samps = 0; //number of accumulated samples          while(num_acc_samps < total_num_samps){ -            size_t samps_to_send = std::min(total_num_samps - num_acc_samps, spb); +            size_t samps_to_send = total_num_samps - num_acc_samps; +            if (samps_to_send > spb) +            { +                samps_to_send = spb; +            } else { +                md.end_of_burst = true; +            }              //send a single packet              size_t num_tx_samps = tx_stream->send( @@ -152,25 +158,37 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){              md.has_time_spec = false;              md.start_of_burst = false; -            if (num_tx_samps < samps_to_send) std::cerr << "Send timeout..." << std::endl; -            if(verbose) std::cout << boost::format("Sent packet: %u samples") % num_tx_samps << std::endl; +            if (num_tx_samps < samps_to_send) +            { +                std::cerr << "Send timeout..." << std::endl; +                if (stop_signal_called) +                { +                    exit(EXIT_FAILURE); +                } +            } + +            if(verbose) +            { +                std::cout << boost::format("Sent packet: %u samples") % num_tx_samps << std::endl; +            }              num_acc_samps += num_tx_samps;          } -        md.end_of_burst = true; -        tx_stream->send(buffs, 0, md, timeout); -          time_to_send += rep_rate;          std::cout << std::endl << "Waiting for async burst ACK... " << std::flush;          uhd::async_metadata_t async_md; -        bool got_async_burst_ack = false; -        //loop through all messages for the ACK packet (may have underflow messages in queue) -        while (not got_async_burst_ack and tx_stream->recv_async_msg(async_md, seconds_in_future)){ -            got_async_burst_ack = (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK); +        size_t acks = 0; +        //loop through all messages for the ACK packets (may have underflow messages in queue) +        while (acks < channel_nums.size() and tx_stream->recv_async_msg(async_md, seconds_in_future)) +        { +            if (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK) +            { +                acks++; +            }          } -        std::cout << (got_async_burst_ack? "success" : "fail") << std::endl; +        std::cout << (acks == channel_nums.size() ? "success" : "fail") << std::endl;      } while (not stop_signal_called and repeat);      //finished diff --git a/host/examples/tx_samples_c.c b/host/examples/tx_samples_c.c index c052d80ed..3c3fcc8fe 100644 --- a/host/examples/tx_samples_c.c +++ b/host/examples/tx_samples_c.c @@ -21,6 +21,7 @@  #include <math.h>  #include <signal.h> +#include <stdint.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h> @@ -39,6 +40,7 @@ void print_help(void){                      "    -f (frequency in Hz)\n"                      "    -r (sample rate in Hz)\n"                      "    -g (gain)\n" +                    "    -n (number of samples to transmit)\n"                      "    -v (enable verbose prints)\n"                      "    -h (print this help message)\n");  } @@ -57,12 +59,13 @@ int main(int argc, char* argv[]){      double gain = 0;      char* device_args = "";      size_t channel = 0; +    uint64_t total_num_samps = 0;      bool verbose = false;      int return_code = EXIT_SUCCESS;      char error_string[512];      // Process options -    while((option = getopt(argc, argv, "a:f:r:g:vh")) != -1){ +    while((option = getopt(argc, argv, "a:f:r:g:n:vh")) != -1){          switch(option){              case 'a':                  device_args = strdup(optarg); @@ -80,6 +83,10 @@ int main(int argc, char* argv[]){                  gain = atof(optarg);                  break; +            case 'n': +                total_num_samps = atoll(optarg); +                break; +              case 'v':                  verbose = true;                  break; @@ -198,11 +205,19 @@ int main(int argc, char* argv[]){      fprintf(stderr, "Press Ctrl+C to stop streaming...\n");      // Actual streaming -    size_t num_samps_sent = 0; -    while(!stop_signal_called){ +    uint64_t num_acc_samps = 0; +    uint64_t num_samps_sent = 0; + +    while(1) { +        if (stop_signal_called) break; +        if (total_num_samps > 0 && num_acc_samps >= total_num_samps) break; +          EXECUTE_OR_GOTO(free_tx_streamer,              uhd_tx_streamer_send(tx_streamer, buffs_ptr, samps_per_buff, &md, 0.1, &num_samps_sent)          ) + +        num_acc_samps += num_samps_sent; +          if(verbose){              fprintf(stderr, "Sent %zu samples\n", num_samps_sent);          } diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp index af8f92607..b2a8f944c 100644 --- a/host/examples/tx_waveforms.cpp +++ b/host/examples/tx_waveforms.cpp @@ -28,6 +28,7 @@  #include <boost/thread.hpp>  #include <boost/lexical_cast.hpp>  #include <boost/algorithm/string.hpp> +#include <stdint.h>  #include <iostream>  #include <csignal> @@ -47,7 +48,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //variables to be set by po      std::string args, wave_type, ant, subdev, ref, pps, otw, channel_list; -    size_t spb; +    uint64_t total_num_samps, spb;      double rate, freq, gain, wave_freq, bw;      float ampl; @@ -56,7 +57,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      desc.add_options()          ("help", "help message")          ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args") -        ("spb", po::value<size_t>(&spb)->default_value(0), "samples per buffer, 0 for default") +        ("spb", po::value<uint64_t>(&spb)->default_value(0), "samples per buffer, 0 for default") +        ("nsamps", po::value<uint64_t>(&total_num_samps)->default_value(0), "total number of samples to transmit")          ("rate", po::value<double>(&rate), "rate of outgoing samples")          ("freq", po::value<double>(&freq), "RF center frequency in Hz")          ("ampl", po::value<float>(&l)->default_value(float(0.3)), "amplitude of the waveform [0 to 0.7]") @@ -211,20 +213,22 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //Check Ref and LO Lock detect      std::vector<std::string> sensor_names; -    sensor_names = usrp->get_tx_sensor_names(0); +    const size_t tx_sensor_chan = channel_list.empty() ? 0 : boost::lexical_cast<size_t>(channel_list[0]); +    sensor_names = usrp->get_tx_sensor_names(tx_sensor_chan);      if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { -        uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked",0); +        uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked", tx_sensor_chan);          std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl;          UHD_ASSERT_THROW(lo_locked.to_bool());      } -    sensor_names = usrp->get_mboard_sensor_names(0); +    const size_t mboard_sensor_idx = 0; +    sensor_names = usrp->get_mboard_sensor_names(mboard_sensor_idx);      if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { -        uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); +        uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked", mboard_sensor_idx);          std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() << std::endl;          UHD_ASSERT_THROW(mimo_locked.to_bool());      }      if ((ref == "external") and (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())) { -        uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0); +        uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked", mboard_sensor_idx);          std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() << std::endl;          UHD_ASSERT_THROW(ref_locked.to_bool());      } @@ -241,14 +245,22 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      md.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.1);      //send data until the signal handler gets called -    while(not stop_signal_called){ +    //or if we accumulate the number of samples specified (unless it's 0) +    uint64_t num_acc_samps = 0; +    while(true){ + +        if (stop_signal_called) break; +        if (total_num_samps > 0 and num_acc_samps >= total_num_samps) break; +          //fill the buffer with the waveform          for (size_t n = 0; n < buff.size(); n++){              buff[n] = wave_table(index += step);          }          //send the entire contents of the buffer -        tx_stream->send(buffs, buff.size(), md); +        num_acc_samps += tx_stream->send( +            buffs, buff.size(), md +        );          md.start_of_burst = false;          md.has_time_spec = false; | 
