From 4b9f4b5aec74f8b53d8f88d46af23459af9712ec Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 3 Feb 2011 15:48:04 -0800 Subject: sort of working latency tester --- host/examples/latency_test.cpp | 198 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 host/examples/latency_test.cpp (limited to 'host/examples/latency_test.cpp') diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp new file mode 100644 index 000000000..596087d75 --- /dev/null +++ b/host/examples/latency_test.cpp @@ -0,0 +1,198 @@ +// +// Copyright 2010-2011 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 . +// + +#include +#include +#include +#include +#include +#include +#include + +namespace po = boost::program_options; + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args; + double wait_time; + size_t total_num_samps; + size_t samps_per_packet; + double rate, freq; + float ampl; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "single uhd device address args") + ("secs", po::value(&wait_time)->default_value(0.1), "number of seconds in the future to transmit") + ("nsamps", po::value(&total_num_samps)->default_value(100), "total number of samples to transmit") + ("spp", po::value(&samps_per_packet)->default_value(1000), "number of samples per packet") + ("rate", po::value(&rate)->default_value(100e6/4), "rate of outgoing samples") + ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("ampl", po::value(&l)->default_value(float(0.3)), "amplitude of each sample") + ("dilv", "specify to disable inner-loop verbose") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("Latency Test %s") % desc << std::endl; + return ~0; + } + + bool verbose = vm.count("dilv") == 0; + + //create a usrp device + std::cout << std::endl; + //std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); + uhd::device::sptr dev = sdev->get_device(); + //std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + + //set the tx sample rate + sdev->set_tx_rate(rate); + std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl; + + //set the rx sample rate + sdev->set_rx_rate(rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl; + + //allocate data to send + std::vector > txbuff(samps_per_packet, std::complex(ampl, ampl)); + + //allocate receive buffer + std::vector > rxbuff(samps_per_packet, std::complex(ampl, ampl)); + + + int time_error = 0; + int ack = 0; + int underflow = 0; + int other = 0; + // ************************************************** + if(verbose) + std::cout << boost::format("Setting device timestamp to 0...") << std::endl; + sdev->set_time_now(uhd::time_spec_t(0.0)); + + //setup streaming + std::cout << std::endl; + if(verbose) + std::cout << boost::format( + "Begin receiving %u samples, %f seconds in the future..." + ) % total_num_samps % wait_time << std::endl; + + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = total_num_samps; + stream_cmd.stream_now = false; + + double delta_t = 0.0001; + uhd::tx_metadata_t tx_md; + + size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; + + + double cur_time = 0.0; + sdev->set_time_now(uhd::time_spec_t(cur_time)); + + for(int j=0;j<100;j++) { + cur_time += wait_time; + stream_cmd.time_spec = uhd::time_spec_t(cur_time); + sdev->issue_stream_cmd(stream_cmd); + size_t num_acc_samps = 0; + uhd::rx_metadata_t rx_md; + while(num_acc_samps < total_num_samps){ + std::vector > rxbuff(dev->get_max_recv_samps_per_packet()); + size_t num_rx_samps = dev->recv( + &rxbuff.front(), rxbuff.size(), rx_md, + uhd::io_type_t::COMPLEX_FLOAT32, + uhd::device::RECV_MODE_ONE_PACKET + ); + + switch(rx_md.error_code){ + case uhd::rx_metadata_t::ERROR_CODE_NONE: + break; + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (num_acc_samps == 0) continue; + std::cout << boost::format + ("Got timeout before all samples received, possible packet loss, exiting loop...") << std::endl; + goto done_loop; + default: + std::cout << boost::format("Got error code 0x%x, exiting loop...") % rx_md.error_code << std::endl; + goto done_loop; + } + + if(verbose) std::cout << boost::format("Got packet: %u samples, %u full secs, %f frac secs") + % num_rx_samps % rx_md.time_spec.get_full_secs() % rx_md.time_spec.get_frac_secs() << std::endl; + + num_acc_samps += num_rx_samps; + } done_loop: + + if(verbose) std::cout << "Done receiving samps" << std::endl; + + for (size_t i = 0; i < num_packets; i++){ + //setup the metadata flags per fragment + tx_md.start_of_burst = (i == 0); //only first packet has SOB + tx_md.end_of_burst = (i == num_packets-1); //only last packet has EOB + tx_md.has_time_spec = (i == 0); //only first packet has time + + size_t samps_to_send = std::min(total_num_samps - samps_per_packet*i, samps_per_packet); + + //send the entire packet (driver fragments internally) + tx_md.time_spec = uhd::time_spec_t(cur_time+delta_t); + size_t num_tx_samps = dev->send + (&txbuff.front(), samps_to_send, tx_md, + uhd::io_type_t::COMPLEX_FLOAT32, + uhd::device::SEND_MODE_FULL_BUFF, + //send will backup into the host this many seconds before sending: + cur_time + delta_t + 0.1 //timeout (delay before transmit + padding) + ); + if (num_tx_samps < samps_to_send) std::cout << "Send timeout..." << std::endl; + if(verbose) + std::cout << std::endl << boost::format("Sent %d samples") % num_tx_samps << std::endl; + } + + uhd::async_metadata_t async_md; + if (not dev->recv_async_msg(async_md)){ + std::cout << boost::format + ("failed:\n Async message recv timed out.\n") << std::endl; + } else { + switch(async_md.event_code){ + case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR : + time_error++; + break; + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK : + ack++; + break; + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW : + underflow++; + break; + default: + std::cout << boost::format + ("failed:\n Got unexpected event code 0x%x.\n") + % async_md.event_code << std::endl; + other++; + break; + } + } + } + std::cout << boost::format("ACK %d, UNDERFLOW %d, TIME_ERR %d, other %d") % ack + % underflow % time_error % other << std::endl; +} -- cgit v1.2.3 From d74b0322bf3d0f7c89bd6d5224ad73924237aa33 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 3 Feb 2011 16:10:47 -0800 Subject: getting usable data --- host/examples/latency_test.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'host/examples/latency_test.cpp') diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp index 596087d75..b6afdeb34 100644 --- a/host/examples/latency_test.cpp +++ b/host/examples/latency_test.cpp @@ -35,13 +35,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t samps_per_packet; double rate, freq; float ampl; + double delta_t; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("args", po::value(&args)->default_value(""), "single uhd device address args") - ("secs", po::value(&wait_time)->default_value(0.1), "number of seconds in the future to transmit") + ("wait", po::value(&wait_time)->default_value(0.1), "wait time between test cycles") + ("rtt", po::value(&delta_t)->default_value(0.001), "Round-Trip time to test") ("nsamps", po::value(&total_num_samps)->default_value(100), "total number of samples to transmit") ("spp", po::value(&samps_per_packet)->default_value(1000), "number of samples per packet") ("rate", po::value(&rate)->default_value(100e6/4), "rate of outgoing samples") @@ -103,7 +105,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ stream_cmd.num_samps = total_num_samps; stream_cmd.stream_now = false; - double delta_t = 0.0001; uhd::tx_metadata_t tx_md; size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; @@ -113,6 +114,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ sdev->set_time_now(uhd::time_spec_t(cur_time)); for(int j=0;j<100;j++) { + int err = 0; cur_time += wait_time; stream_cmd.time_spec = uhd::time_spec_t(cur_time); sdev->issue_stream_cmd(stream_cmd); @@ -133,9 +135,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ if (num_acc_samps == 0) continue; std::cout << boost::format ("Got timeout before all samples received, possible packet loss, exiting loop...") << std::endl; + err = 1; goto done_loop; default: std::cout << boost::format("Got error code 0x%x, exiting loop...") % rx_md.error_code << std::endl; + err = 1; goto done_loop; } @@ -146,7 +150,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } done_loop: if(verbose) std::cout << "Done receiving samps" << std::endl; - + if(err) + continue; for (size_t i = 0; i < num_packets; i++){ //setup the metadata flags per fragment tx_md.start_of_burst = (i == 0); //only first packet has SOB @@ -162,7 +167,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::SEND_MODE_FULL_BUFF, //send will backup into the host this many seconds before sending: - cur_time + delta_t + 0.1 //timeout (delay before transmit + padding) + 0.1 //timeout (delay before transmit + padding) ); if (num_tx_samps < samps_to_send) std::cout << "Send timeout..." << std::endl; if(verbose) @@ -195,4 +200,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } std::cout << boost::format("ACK %d, UNDERFLOW %d, TIME_ERR %d, other %d") % ack % underflow % time_error % other << std::endl; + return 0; } -- cgit v1.2.3 From d6cab26bf26d61d71ba0792bce8f48a89f7dc2d7 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 3 Feb 2011 16:41:01 -0800 Subject: successful latency test. About 500 us on my laptop. --- host/examples/latency_test.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'host/examples/latency_test.cpp') diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp index b6afdeb34..340e87fb7 100644 --- a/host/examples/latency_test.cpp +++ b/host/examples/latency_test.cpp @@ -36,6 +36,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ double rate, freq; float ampl; double delta_t; + size_t pkts; //setup the program options po::options_description desc("Allowed options"); @@ -46,6 +47,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("rtt", po::value(&delta_t)->default_value(0.001), "Round-Trip time to test") ("nsamps", po::value(&total_num_samps)->default_value(100), "total number of samples to transmit") ("spp", po::value(&samps_per_packet)->default_value(1000), "number of samples per packet") + ("pkts", po::value(&pkts)->default_value(1000), "number of packets") ("rate", po::value(&rate)->default_value(100e6/4), "rate of outgoing samples") ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") ("ampl", po::value(&l)->default_value(float(0.3)), "amplitude of each sample") @@ -110,12 +112,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; - double cur_time = 0.0; + uhd::time_spec_t cur_time; sdev->set_time_now(uhd::time_spec_t(cur_time)); - for(int j=0;j<100;j++) { + for(int j=0;jget_time_now() + uhd::time_spec_t(0.01); stream_cmd.time_spec = uhd::time_spec_t(cur_time); sdev->issue_stream_cmd(stream_cmd); size_t num_acc_samps = 0; @@ -161,7 +164,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t samps_to_send = std::min(total_num_samps - samps_per_packet*i, samps_per_packet); //send the entire packet (driver fragments internally) - tx_md.time_spec = uhd::time_spec_t(cur_time+delta_t); + //tx_md.time_spec = rx_md.time_spec+uhd::time_spec_t(delta_t); + tx_md.time_spec = cur_time + uhd::time_spec_t(delta_t); size_t num_tx_samps = dev->send (&txbuff.front(), samps_to_send, tx_md, uhd::io_type_t::COMPLEX_FLOAT32, -- cgit v1.2.3 From a54c4ab9dedfe283b5dda0e82bab93c35ffe11b9 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 3 Feb 2011 18:50:31 -0800 Subject: uhd: cleanup for latency test --- host/examples/CMakeLists.txt | 2 +- host/examples/latency_test.cpp | 245 +++++++++++++++++------------------------ 2 files changed, 103 insertions(+), 144 deletions(-) (limited to 'host/examples/latency_test.cpp') diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index 47152a88a..434caa328 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2010 Ettus Research LLC +# Copyright 2010-2011 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 diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp index 340e87fb7..be44aad70 100644 --- a/host/examples/latency_test.cpp +++ b/host/examples/latency_test.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2011 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 @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -30,28 +30,21 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //variables to be set by po std::string args; - double wait_time; - size_t total_num_samps; - size_t samps_per_packet; - double rate, freq; - float ampl; - double delta_t; - size_t pkts; + size_t nsamps; + double rate; + double rtt; + size_t nruns; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") - ("args", po::value(&args)->default_value(""), "single uhd device address args") - ("wait", po::value(&wait_time)->default_value(0.1), "wait time between test cycles") - ("rtt", po::value(&delta_t)->default_value(0.001), "Round-Trip time to test") - ("nsamps", po::value(&total_num_samps)->default_value(100), "total number of samples to transmit") - ("spp", po::value(&samps_per_packet)->default_value(1000), "number of samples per packet") - ("pkts", po::value(&pkts)->default_value(1000), "number of packets") - ("rate", po::value(&rate)->default_value(100e6/4), "rate of outgoing samples") - ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") - ("ampl", po::value(&l)->default_value(float(0.3)), "amplitude of each sample") - ("dilv", "specify to disable inner-loop verbose") + ("args", po::value(&args)->default_value(""), "single uhd device address args") + ("nsamps", po::value(&nsamps)->default_value(100), "number of samples per run") + ("nruns", po::value(&nruns)->default_value(1000), "number of tests to perform") + ("rtt", po::value(&rtt)->default_value(0.001), "delay between receive and transmit (seconds)") + ("rate", po::value(&rate)->default_value(100e6/4), "sample rate for receive and transmit (sps)") + ("verbose", "specify to enable inner-loop verbose") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -59,150 +52,116 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //print the help message if (vm.count("help")){ - std::cout << boost::format("Latency Test %s") % desc << std::endl; + std::cout << boost::format("UHD - Latency Test %s") % desc << std::endl; + std::cout << + " Latency test receives a packet at time t,\n" + " and tries to send a packet at time t + rtt,\n" + " where rtt is the round trip time sample time\n" + " from device to host and back to the device.\n" + << std::endl; return ~0; } - bool verbose = vm.count("dilv") == 0; + bool verbose = vm.count("verbose") != 0; //create a usrp device std::cout << std::endl; //std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; - uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); - uhd::device::sptr dev = sdev->get_device(); - //std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); + //std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; + + usrp->set_time_now(uhd::time_spec_t(0.0)); //set the tx sample rate - sdev->set_tx_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl; + usrp->set_tx_rate(rate); + std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl; //set the rx sample rate - sdev->set_rx_rate(rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl; - - //allocate data to send - std::vector > txbuff(samps_per_packet, std::complex(ampl, ampl)); - - //allocate receive buffer - std::vector > rxbuff(samps_per_packet, std::complex(ampl, ampl)); + usrp->set_rx_rate(rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl; + //allocate a buffer to use + std::vector > buffer(nsamps); + //initialize result counts int time_error = 0; int ack = 0; int underflow = 0; int other = 0; - // ************************************************** - if(verbose) - std::cout << boost::format("Setting device timestamp to 0...") << std::endl; - sdev->set_time_now(uhd::time_spec_t(0.0)); - //setup streaming - std::cout << std::endl; - if(verbose) - std::cout << boost::format( - "Begin receiving %u samples, %f seconds in the future..." - ) % total_num_samps % wait_time << std::endl; - - uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = total_num_samps; - stream_cmd.stream_now = false; - - uhd::tx_metadata_t tx_md; - - size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; - - - uhd::time_spec_t cur_time; - sdev->set_time_now(uhd::time_spec_t(cur_time)); - - for(int j=0;jget_time_now() + uhd::time_spec_t(0.01); - stream_cmd.time_spec = uhd::time_spec_t(cur_time); - sdev->issue_stream_cmd(stream_cmd); - size_t num_acc_samps = 0; - uhd::rx_metadata_t rx_md; - while(num_acc_samps < total_num_samps){ - std::vector > rxbuff(dev->get_max_recv_samps_per_packet()); - size_t num_rx_samps = dev->recv( - &rxbuff.front(), rxbuff.size(), rx_md, - uhd::io_type_t::COMPLEX_FLOAT32, - uhd::device::RECV_MODE_ONE_PACKET - ); - - switch(rx_md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_NONE: - break; - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - if (num_acc_samps == 0) continue; - std::cout << boost::format - ("Got timeout before all samples received, possible packet loss, exiting loop...") << std::endl; - err = 1; - goto done_loop; + for(size_t nrun = 0; nrun < nruns; nrun++){ + + /*************************************************************** + * Issue a stream command some time in the near future + **************************************************************/ + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = buffer.size(); + stream_cmd.stream_now = false; + stream_cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.01); + usrp->issue_stream_cmd(stream_cmd); + + /*************************************************************** + * Receive the requested packet + **************************************************************/ + uhd::rx_metadata_t rx_md; + size_t num_rx_samps = usrp->get_device()->recv( + &buffer.front(), buffer.size(), rx_md, + uhd::io_type_t::COMPLEX_FLOAT32, + uhd::device::RECV_MODE_FULL_BUFF + ); + + if(verbose) std::cout << boost::format("Got packet: %u samples, %u full secs, %f frac secs") + % num_rx_samps % rx_md.time_spec.get_full_secs() % rx_md.time_spec.get_frac_secs() << std::endl; + + /*************************************************************** + * Transmit a packet with delta time after received packet + **************************************************************/ + uhd::tx_metadata_t tx_md; + tx_md.start_of_burst = true; + tx_md.end_of_burst = true; + tx_md.has_time_spec = true; + tx_md.time_spec = rx_md.time_spec + uhd::time_spec_t(rtt); + size_t num_tx_samps = usrp->get_device()->send( + &buffer.front(), buffer.size(), tx_md, + uhd::io_type_t::COMPLEX_FLOAT32, + uhd::device::SEND_MODE_FULL_BUFF + ); + if(verbose) std::cout << boost::format("Sent %d samples") % num_tx_samps << std::endl; + + /*************************************************************** + * Check the async messages for result + **************************************************************/ + uhd::async_metadata_t async_md; + if (not usrp->get_device()->recv_async_msg(async_md)){ + std::cout << boost::format("failed:\n Async message recv timed out.\n") << std::endl; + continue; + } + switch(async_md.event_code){ + case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: + time_error++; + break; + + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: + ack++; + break; + + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: + underflow++; + break; + default: - std::cout << boost::format("Got error code 0x%x, exiting loop...") % rx_md.error_code << std::endl; - err = 1; - goto done_loop; + std::cout << boost::format + ("failed:\n Got unexpected event code 0x%x.\n") + % async_md.event_code << std::endl; + other++; + break; } - - if(verbose) std::cout << boost::format("Got packet: %u samples, %u full secs, %f frac secs") - % num_rx_samps % rx_md.time_spec.get_full_secs() % rx_md.time_spec.get_frac_secs() << std::endl; - - num_acc_samps += num_rx_samps; - } done_loop: - - if(verbose) std::cout << "Done receiving samps" << std::endl; - if(err) - continue; - for (size_t i = 0; i < num_packets; i++){ - //setup the metadata flags per fragment - tx_md.start_of_burst = (i == 0); //only first packet has SOB - tx_md.end_of_burst = (i == num_packets-1); //only last packet has EOB - tx_md.has_time_spec = (i == 0); //only first packet has time - - size_t samps_to_send = std::min(total_num_samps - samps_per_packet*i, samps_per_packet); - - //send the entire packet (driver fragments internally) - //tx_md.time_spec = rx_md.time_spec+uhd::time_spec_t(delta_t); - tx_md.time_spec = cur_time + uhd::time_spec_t(delta_t); - size_t num_tx_samps = dev->send - (&txbuff.front(), samps_to_send, tx_md, - uhd::io_type_t::COMPLEX_FLOAT32, - uhd::device::SEND_MODE_FULL_BUFF, - //send will backup into the host this many seconds before sending: - 0.1 //timeout (delay before transmit + padding) - ); - if (num_tx_samps < samps_to_send) std::cout << "Send timeout..." << std::endl; - if(verbose) - std::cout << std::endl << boost::format("Sent %d samples") % num_tx_samps << std::endl; - } - - uhd::async_metadata_t async_md; - if (not dev->recv_async_msg(async_md)){ - std::cout << boost::format - ("failed:\n Async message recv timed out.\n") << std::endl; - } else { - switch(async_md.event_code){ - case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR : - time_error++; - break; - case uhd::async_metadata_t::EVENT_CODE_BURST_ACK : - ack++; - break; - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW : - underflow++; - break; - default: - std::cout << boost::format - ("failed:\n Got unexpected event code 0x%x.\n") - % async_md.event_code << std::endl; - other++; - break; - } - } } - std::cout << boost::format("ACK %d, UNDERFLOW %d, TIME_ERR %d, other %d") % ack - % underflow % time_error % other << std::endl; + + /*************************************************************** + * Print the summary + **************************************************************/ + std::cout << boost::format("\nACK %d, UNDERFLOW %d, TIME_ERR %d, other %d") + % ack % underflow % time_error % other << std::endl; return 0; } -- cgit v1.2.3