diff options
30 files changed, 281 insertions, 76 deletions
diff --git a/host/cmake/Modules/UHDPackage.cmake b/host/cmake/Modules/UHDPackage.cmake index d2f5d78f2..330a9ecc2 100644 --- a/host/cmake/Modules/UHDPackage.cmake +++ b/host/cmake/Modules/UHDPackage.cmake @@ -109,7 +109,6 @@ SET(CPACK_COMPONENT_LIBRARIES_GROUP "Development") SET(CPACK_COMPONENT_HEADERS_GROUP "Development") SET(CPACK_COMPONENT_UTILITIES_GROUP "Runtime") SET(CPACK_COMPONENT_EXAMPLES_GROUP "Runtime") -SET(CPACK_COMPONENT_TESTS_GROUP "Runtime") SET(CPACK_COMPONENT_MANUAL_GROUP "Documentation") SET(CPACK_COMPONENT_DOXYGEN_GROUP "Documentation") SET(CPACK_COMPONENT_README_GROUP "Documentation") @@ -118,7 +117,6 @@ SET(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries") SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers") SET(CPACK_COMPONENT_UTILITIES_DISPLAY_NAME "Utilities") SET(CPACK_COMPONENT_EXAMPLES_DISPLAY_NAME "Examples") -SET(CPACK_COMPONENT_TESTS_DISPLAY_NAME "Unit Tests") SET(CPACK_COMPONENT_MANUAL_DISPLAY_NAME "Manual") SET(CPACK_COMPONENT_DOXYGEN_DISPLAY_NAME "Doxygen") SET(CPACK_COMPONENT_README_DISPLAY_NAME "Readme") @@ -128,7 +126,6 @@ SET(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "Dynamic link library") SET(CPACK_COMPONENT_HEADERS_DESCRIPTION "C++ development headers") SET(CPACK_COMPONENT_UTILITIES_DESCRIPTION "Utility executables and python scripts") SET(CPACK_COMPONENT_EXAMPLES_DESCRIPTION "Example executables") -SET(CPACK_COMPONENT_TESTS_DESCRIPTION "Unit test executables") SET(CPACK_COMPONENT_MANUAL_DESCRIPTION "Manual/application notes (rst and html)") SET(CPACK_COMPONENT_DOXYGEN_DESCRIPTION "API documentation (html)") SET(CPACK_COMPONENT_README_DESCRIPTION "Readme files (txt)") @@ -140,7 +137,7 @@ SET(CPACK_COMPONENT_UTILITIES_DEPENDS libraries) SET(CPACK_COMPONENT_EXAMPLES_DEPENDS libraries) SET(CPACK_COMPONENT_TESTS_DEPENDS libraries) -SET(CPACK_COMPONENTS_ALL libraries headers utilities examples tests manual doxygen readme images) +SET(CPACK_COMPONENTS_ALL libraries headers utilities examples manual doxygen readme images) ######################################################################## # Setup CPack Debian diff --git a/host/cmake/Modules/UHDUnitTest.cmake b/host/cmake/Modules/UHDUnitTest.cmake new file mode 100644 index 000000000..47cddc521 --- /dev/null +++ b/host/cmake/Modules/UHDUnitTest.cmake @@ -0,0 +1,110 @@ +# +# Copyright 2010-2012 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/>. +# + +######################################################################## +# Add a unit test and setup the environment for a unit test. +# Takes the same arguments as the ADD_TEST function. +# +# Before calling set the following variables: +# UHD_TEST_TARGET_DEPS - built targets for the library path +# UHD_TEST_LIBRARY_DIRS - directories for the library path +######################################################################## +function(UHD_ADD_TEST test_name) + + #Ensure that the build exe also appears in the PATH. + list(APPEND UHD_TEST_TARGET_DEPS ${ARGN}) + + #In the land of windows, all libraries must be in the PATH. + #Since the dependent libraries are not yet installed, + #we must manually set them in the PATH to run tests. + #The following appends the path of a target dependency. + foreach(target ${UHD_TEST_TARGET_DEPS}) + get_target_property(location ${target} LOCATION) + if(location) + get_filename_component(path ${location} PATH) + string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path}) + list(APPEND UHD_TEST_LIBRARY_DIRS ${path}) + endif(location) + endforeach(target) + + file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir) + file(TO_NATIVE_PATH "${UHD_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list? + + #http://www.cmake.org/pipermail/cmake/2009-May/029464.html + #Replaced this add test + set environs code with the shell script generation. + #Its nicer to be able to manually run the shell script to diagnose problems. + #ADD_TEST(${ARGV}) + #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}") + + if(UNIX) + set(LD_PATH_VAR "LD_LIBRARY_PATH") + if(APPLE) + set(LD_PATH_VAR "DYLD_LIBRARY_PATH") + endif() + + set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH") + list(APPEND libpath "$${LD_PATH_VAR}") + + #replace list separator with the path separator + string(REPLACE ";" ":" libpath "${libpath}") + list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}") + + #generate a bat file that sets the environment and runs the test + find_program(SHELL sh) + set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh) + file(WRITE ${sh_file} "#!${SHELL}\n") + #each line sets an environment variable + foreach(environ ${environs}) + file(APPEND ${sh_file} "export ${environ}\n") + endforeach(environ) + #load the command to run with its arguments + foreach(arg ${ARGN}) + file(APPEND ${sh_file} "${arg} ") + endforeach(arg) + file(APPEND ${sh_file} "\n") + + #make the shell file executable + execute_process(COMMAND chmod +x ${sh_file}) + + add_test(${test_name} ${SHELL} ${sh_file}) + + endif(UNIX) + + if(WIN32) + list(APPEND libpath ${DLL_PATHS} "%PATH%") + + #replace list separator with the path separator (escaped) + string(REPLACE ";" "\\;" libpath "${libpath}") + list(APPEND environs "PATH=${libpath}") + + #generate a bat file that sets the environment and runs the test + set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat) + file(WRITE ${bat_file} "@echo off\n") + #each line sets an environment variable + foreach(environ ${environs}) + file(APPEND ${bat_file} "SET ${environ}\n") + endforeach(environ) + #load the command to run with its arguments + foreach(arg ${ARGN}) + file(APPEND ${bat_file} "${arg} ") + endforeach(arg) + file(APPEND ${bat_file} "\n") + + add_test(${test_name} ${bat_file}) + endif(WIN32) + +endfunction(UHD_ADD_TEST) diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp index 8a000f6c3..ed3a8580a 100644 --- a/host/examples/benchmark_rate.cpp +++ b/host/examples/benchmark_rate.cpp @@ -25,6 +25,7 @@ #include <boost/math/special_functions/round.hpp> #include <iostream> #include <complex> +#include <cstdlib> namespace po = boost::program_options; @@ -264,5 +265,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp index 518d2383a..461ac9bf8 100644 --- a/host/examples/latency_test.cpp +++ b/host/examples/latency_test.cpp @@ -164,5 +164,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ **************************************************************/ std::cout << boost::format("\nACK %d, UNDERFLOW %d, TIME_ERR %d, other %d") % ack % underflow % time_error % other << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp index e8f9e667f..bb09296b3 100644 --- a/host/examples/network_relay.cpp +++ b/host/examples/network_relay.cpp @@ -24,6 +24,7 @@ #include <iostream> #include <csignal> #include <vector> +#include <cstdlib> namespace po = boost::program_options; namespace asio = boost::asio; @@ -202,7 +203,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ << "Runs a network relay between UHD on one computer and a USRP on the network.\n" << "This example is basically for test purposes. Use at your own convenience.\n" << std::endl; - return ~0; + return EXIT_FAILURE; } { @@ -223,5 +224,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/rx_ascii_art_dft.cpp b/host/examples/rx_ascii_art_dft.cpp index fe8fb0347..1aede51a4 100644 --- a/host/examples/rx_ascii_art_dft.cpp +++ b/host/examples/rx_ascii_art_dft.cpp @@ -25,6 +25,7 @@ #include <curses.h> #include <iostream> #include <complex> +#include <cstdlib> namespace po = boost::program_options; @@ -63,7 +64,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //print the help message if (vm.count("help") or not vm.count("rate")){ std::cout << boost::format("UHD RX ASCII Art DFT %s") % desc << std::endl; - return ~0; + return EXIT_FAILURE; } //create a usrp device @@ -82,7 +83,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //set the sample rate if (not vm.count("rate")){ std::cerr << "Please specify the sample rate with --rate" << std::endl; - return ~0; + return EXIT_FAILURE; } std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; usrp->set_rx_rate(rate); @@ -91,7 +92,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //set the center frequency if (not vm.count("freq")){ std::cerr << "Please specify the center frequency with --freq" << std::endl; - return ~0; + return EXIT_FAILURE; } std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; usrp->set_rx_freq(freq); @@ -194,5 +195,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/rx_multi_samples.cpp b/host/examples/rx_multi_samples.cpp index 42ef33d70..83d648eb5 100644 --- a/host/examples/rx_multi_samples.cpp +++ b/host/examples/rx_multi_samples.cpp @@ -174,5 +174,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp index 5197bfe69..d0a02a6c1 100644 --- a/host/examples/rx_samples_to_file.cpp +++ b/host/examples/rx_samples_to_file.cpp @@ -214,5 +214,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp index 2acaa5d8b..f637f9313 100644 --- a/host/examples/rx_samples_to_udp.cpp +++ b/host/examples/rx_samples_to_udp.cpp @@ -168,5 +168,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 143bceb03..f0d49b4bd 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -124,5 +124,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/test_dboard_coercion.cpp b/host/examples/test_dboard_coercion.cpp index 5b1e9f0e2..cfc745147 100644 --- a/host/examples/test_dboard_coercion.cpp +++ b/host/examples/test_dboard_coercion.cpp @@ -573,5 +573,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ if(test_tx and test_rx) std::cout << std::endl; if(test_rx) std::cout << rx_results << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp index afb092092..6f2ddfe28 100644 --- a/host/examples/test_messages.cpp +++ b/host/examples/test_messages.cpp @@ -350,5 +350,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/test_pps_input.cpp b/host/examples/test_pps_input.cpp index 994b7ca87..c07f2fffd 100644 --- a/host/examples/test_pps_input.cpp +++ b/host/examples/test_pps_input.cpp @@ -58,5 +58,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << std::endl << "Attempt to detect the PPS and set the time..." << std::endl << std::endl; usrp->set_time_unknown_pps(uhd::time_spec_t(0.0)); std::cout << std::endl << "Success!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/test_timed_commands.cpp b/host/examples/test_timed_commands.cpp index 34c83dfd6..cecf1607c 100644 --- a/host/examples/test_timed_commands.cpp +++ b/host/examples/test_timed_commands.cpp @@ -125,5 +125,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/transport_hammer.cpp b/host/examples/transport_hammer.cpp index e32912eaa..ff35ceb21 100644 --- a/host/examples/transport_hammer.cpp +++ b/host/examples/transport_hammer.cpp @@ -272,5 +272,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/tx_bursts.cpp b/host/examples/tx_bursts.cpp index 4cf5f2fd1..8dd4a002c 100644 --- a/host/examples/tx_bursts.cpp +++ b/host/examples/tx_bursts.cpp @@ -156,5 +156,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/tx_samples_from_file.cpp b/host/examples/tx_samples_from_file.cpp index 04a6a63d4..f9447c25d 100644 --- a/host/examples/tx_samples_from_file.cpp +++ b/host/examples/tx_samples_from_file.cpp @@ -192,5 +192,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index 3b8cc75d4..4cc31a7c0 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -124,5 +124,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp index 3c5eecd65..40326ae93 100644 --- a/host/examples/tx_waveforms.cpp +++ b/host/examples/tx_waveforms.cpp @@ -260,5 +260,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/examples/txrx_loopback_to_file.cpp b/host/examples/txrx_loopback_to_file.cpp index 495c9f7e4..9dc348da8 100644 --- a/host/examples/txrx_loopback_to_file.cpp +++ b/host/examples/txrx_loopback_to_file.cpp @@ -443,5 +443,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index f3bdded60..917f115f3 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -26,6 +26,10 @@ #include <boost/thread/thread.hpp> #include <boost/tokenizer.hpp> #include <boost/format.hpp> +#include <boost/regex.hpp> + +#include "boost/tuple/tuple.hpp" +#include "boost/foreach.hpp" using namespace uhd; using namespace boost::gregorian; @@ -38,14 +42,69 @@ using namespace boost::this_thread; */ class gps_ctrl_impl : public gps_ctrl{ +private: + std::map<std::string, boost::tuple<std::string, boost::system_time, bool> > sensors; + + std::string get_cached_sensor(const std::string sensor, const int freshness, const bool once, const bool touch=true) { + boost::system_time time = boost::get_system_time(); + try { + // this is nasty ... + //std::cout << boost::format("Requested %s - seen? ") % sensor << sensors[sensor].get<2>() << " once? " << once << std::endl; + if(time - sensors[sensor].get<1>() < milliseconds(freshness) && (!once or !sensors[sensor].get<2>())) { + sensors[sensor] = boost::make_tuple(sensors[sensor].get<0>(), sensors[sensor].get<1>(), touch); + return sensors[sensor].get<0>(); + } else { + return update_cached_sensors(sensor); + } + } catch(std::exception &e) { + UHD_MSG(warning) << "get_cached_sensor: " << e.what(); + } + return std::string(); + } + + std::string update_cached_sensors(const std::string sensor) { + if(not gps_detected() || (gps_type != GPS_TYPE_JACKSON_LABS)) { + UHD_MSG(error) << "get_stat(): unsupported GPS or no GPS detected"; + return std::string(); + } + + std::string msg = _recv(); + static const boost::regex status_regex("\\d\\d-\\d\\d-\\d\\d"); + boost::system_time time = boost::get_system_time(); + if(msg.size() < 6) + return std::string(); + + std::string nmea = msg.substr(1,5); + const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC"); + BOOST_FOREACH(std::string key, list) { + // beginning matches one of the NMEA keys + if(!nmea.compare(key)) { + sensors[key] = boost::make_tuple(msg, time, !sensor.compare(key)); + // if this was what we're looking for return it + return (!sensor.compare(key))? msg : std::string(); + } + } + + //We're still here so it's not one of the NMEA strings from above + if(boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous)) { + trim(msg); + sensors["SERVO"] = boost::make_tuple(msg, time, false); + if(!sensor.compare("SERVO")) + return msg; + else + return std::string(); + } + return std::string(); + } public: gps_ctrl_impl(uart_iface::sptr uart){ _uart = uart; + std::string reply; bool i_heard_some_nmea = false, i_heard_something_weird = false; gps_type = GPS_TYPE_NONE; - + //first we look for a Jackson Labs Firefly (since that's what we provide...) _flush(); //get whatever junk is in the rx buffer right now, and throw it away _send("HAAAY GUYYYYS\n"); //to elicit a response from the Firefly @@ -60,7 +119,7 @@ public: if(reply.find("Command Error") != std::string::npos) { gps_type = GPS_TYPE_JACKSON_LABS; break; - } + } else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate sleep(milliseconds(GPS_TIMEOUT_DELAY_MS)); @@ -99,7 +158,8 @@ public: ("gps_gpgga") ("gps_gprmc") ("gps_time") - ("gps_locked"); + ("gps_locked") + ("gps_servo"); return ret; } @@ -108,7 +168,7 @@ public: or key == "gps_gprmc") { return sensor_value_t( boost::to_upper_copy(key), - get_nmea(boost::to_upper_copy(key.substr(4,8))), + get_cached_sensor(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, false, false), ""); } else if(key == "gps_time") { @@ -117,6 +177,9 @@ public: else if(key == "gps_locked") { return sensor_value_t("GPS lock status", locked(), "locked", "unlocked"); } + else if(key == "gps_servo") { + return sensor_value_t("GPS servo status", get_servo(), ""); + } else { throw uhd::value_error("gps ctrl get_sensor unknown key: " + key); } @@ -138,24 +201,25 @@ private: sleep(milliseconds(FIREFLY_STUPID_DELAY_MS)); _send("GPS:GPRMC 1\n"); sleep(milliseconds(FIREFLY_STUPID_DELAY_MS)); + _send("SERV:TRAC 1\n"); // enable servo trace message + sleep(milliseconds(FIREFLY_STUPID_DELAY_MS)); } - + //retrieve a raw NMEA sentence std::string get_nmea(std::string msgtype) { - msgtype.insert(0, "$"); std::string reply; - if(not gps_detected()) { - UHD_MSG(error) << "get_nmea(): unsupported GPS or no GPS detected"; - return std::string(); - } - - _flush(); //flush all input before waiting for a message const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS); while(boost::get_system_time() < comm_timeout) { - reply = _recv(); - if(reply.substr(0, 6) == msgtype) - return reply; + if(!msgtype.compare("GPRMC")) { + reply = get_cached_sensor(msgtype, GPS_NMEA_FRESHNESS, true); + } + else { + reply = get_cached_sensor(msgtype, GPS_NMEA_LOW_FRESHNESS, false); + } + if(reply.size()) { + if(reply.substr(1, 5) == msgtype) return reply; + } boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS)); } throw uhd::value_error(str(boost::format("get_nmea(): no %s message found") % msgtype)); @@ -178,7 +242,7 @@ private: ptime get_time(void) { int error_cnt = 0; ptime gps_time; - while(error_cnt < 3) { + while(error_cnt < 2) { try { std::string reply = get_nmea("GPRMC"); @@ -188,29 +252,30 @@ private: if(datestr.size() == 0 or timestr.size() == 0) { throw uhd::value_error(str(boost::format("Invalid response \"%s\"") % reply)); } - + //just trust me on this one - gps_time = ptime( date( + gps_time = ptime( date( greg_year(boost::lexical_cast<int>(datestr.substr(4, 2)) + 2000), - greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))), - greg_day(boost::lexical_cast<int>(datestr.substr(0, 2))) + greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))), + greg_day(boost::lexical_cast<int>(datestr.substr(0, 2))) ), hours( boost::lexical_cast<int>(timestr.substr(0, 2))) + minutes(boost::lexical_cast<int>(timestr.substr(2, 2))) + seconds(boost::lexical_cast<int>(timestr.substr(4, 2))) ); return gps_time; - + } catch(std::exception &e) { UHD_MSG(warning) << "get_time: " << e.what(); + _flush(); error_cnt++; } } throw uhd::value_error("Timeout after no valid message found"); - + return gps_time; //keep gcc from complaining } - + time_t get_epoch_time(void) { return (get_time() - from_time_t(0)).total_seconds(); } @@ -223,7 +288,7 @@ private: int error_cnt = 0; while(error_cnt < 3) { try { - std::string reply = get_nmea("GPGGA"); + std::string reply = get_cached_sensor("GPGGA", GPS_LOCK_FRESHNESS, false, false); if(reply.size() <= 1) return false; return (get_token(reply, 6) != "0"); @@ -236,6 +301,20 @@ private: return false; } + std::string get_servo(void) { + std::string reply; + + const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS); + while(boost::get_system_time() < comm_timeout) { + reply = get_cached_sensor("SERVO", GPS_SERVO_FRESHNESS, false); + if(reply.size()) + return reply; + boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS)); + } + throw uhd::value_error("get_stat(): no servo message found"); + return std::string(); + } + uart_iface::sptr _uart; void _flush(void){ @@ -258,7 +337,12 @@ private: GPS_TYPE_NONE } gps_type; - static const int GPS_COMM_TIMEOUT_MS = 1500; + static const int GPS_COMM_TIMEOUT_MS = 1300; + static const int GPS_NMEA_FRESHNESS = 10; + static const int GPS_NMEA_LOW_FRESHNESS = 2500; + static const int GPS_NMEA_NORMAL_FRESHNESS = 1000; + static const int GPS_SERVO_FRESHNESS = 2500; + static const int GPS_LOCK_FRESHNESS = 2500; static const int GPS_TIMEOUT_DELAY_MS = 200; static const int FIREFLY_STUPID_DELAY_MS = 200; }; diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt index 67e99941b..f5cead184 100644 --- a/host/tests/CMakeLists.txt +++ b/host/tests/CMakeLists.txt @@ -16,6 +16,11 @@ # ######################################################################## +# unit test support +######################################################################## +include(UHDUnitTest) + +######################################################################## # unit test suite ######################################################################## SET(test_sources @@ -39,13 +44,15 @@ SET(test_sources #turn each test cpp file into an executable with an int main() function ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN) -#for each source: build an executable, register it as a test, and install +SET(UHD_TEST_TARGET_DEPS uhd) +SET(UHD_TEST_LIBRARY_DIRS ${Boost_LIBRARY_DIRS}) + +#for each source: build an executable, register it as a test FOREACH(test_source ${test_sources}) GET_FILENAME_COMPONENT(test_name ${test_source} NAME_WE) ADD_EXECUTABLE(${test_name} ${test_source}) TARGET_LINK_LIBRARIES(${test_name} uhd) - ADD_TEST(${test_name} ${test_name}) - INSTALL(TARGETS ${test_name} RUNTIME DESTINATION ${PKG_LIB_DIR}/tests COMPONENT tests) + UHD_ADD_TEST(${test_name} ${test_name}) ENDFOREACH(test_source) ######################################################################## diff --git a/host/utils/fx2_init_eeprom.cpp b/host/utils/fx2_init_eeprom.cpp index c210ae575..701092a5d 100644 --- a/host/utils/fx2_init_eeprom.cpp +++ b/host/utils/fx2_init_eeprom.cpp @@ -41,12 +41,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); + po::notify(vm); //print the help message if (vm.count("help")){ std::cout << boost::format("USRP EEPROM initialization %s") % desc << std::endl; - return ~0; + return EXIT_FAILURE; } //cant find a uninitialized usrp with this mystery module in the way... @@ -76,7 +76,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ if (found_addrs.size() == 0){ std::cerr << "No USRP devices found" << std::endl; - return ~0; + return EXIT_FAILURE; } for (size_t i = 0; i < found_addrs.size(); i++){ @@ -89,5 +89,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp index 68d0443da..5fb494114 100644 --- a/host/utils/uhd_cal_rx_iq_balance.cpp +++ b/host/utils/uhd_cal_rx_iq_balance.cpp @@ -29,6 +29,7 @@ #include <complex> #include <cmath> #include <ctime> +#include <cstdlib> namespace po = boost::program_options; @@ -120,7 +121,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n" << std::endl; - return ~0; + return EXIT_FAILURE; } //create a usrp device @@ -239,5 +240,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ store_results(usrp, results, "RX", "rx", "iq"); - return 0; + return EXIT_SUCCESS; } diff --git a/host/utils/uhd_cal_tx_dc_offset.cpp b/host/utils/uhd_cal_tx_dc_offset.cpp index 8f69b3ce1..c9cf757f4 100644 --- a/host/utils/uhd_cal_tx_dc_offset.cpp +++ b/host/utils/uhd_cal_tx_dc_offset.cpp @@ -123,7 +123,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n" << std::endl; - return ~0; + return EXIT_FAILURE; } //create a usrp device @@ -237,5 +237,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ store_results(usrp, results, "TX", "tx", "dc"); - return 0; + return EXIT_SUCCESS; } diff --git a/host/utils/uhd_cal_tx_iq_balance.cpp b/host/utils/uhd_cal_tx_iq_balance.cpp index 5478b07e3..20d018edf 100644 --- a/host/utils/uhd_cal_tx_iq_balance.cpp +++ b/host/utils/uhd_cal_tx_iq_balance.cpp @@ -28,6 +28,7 @@ #include <iostream> #include <complex> #include <ctime> +#include <cstdlib> namespace po = boost::program_options; @@ -123,7 +124,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n" << std::endl; - return ~0; + return EXIT_FAILURE; } //create a usrp device @@ -242,5 +243,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ store_results(usrp, results, "TX", "tx", "iq"); - return 0; + return EXIT_SUCCESS; } diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp index b778eeb68..c258c580e 100644 --- a/host/utils/uhd_find_devices.cpp +++ b/host/utils/uhd_find_devices.cpp @@ -20,6 +20,7 @@ #include <boost/program_options.hpp> #include <boost/format.hpp> #include <iostream> +#include <cstdlib> namespace po = boost::program_options; @@ -37,7 +38,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //print the help message if (vm.count("help")){ std::cout << boost::format("UHD Find Devices %s") % desc << std::endl; - return ~0; + return EXIT_FAILURE; } //discover the usrps and print the results @@ -45,7 +46,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ if (device_addrs.size() == 0){ std::cerr << "No UHD Devices Found" << std::endl; - return ~0; + return EXIT_FAILURE; } for (size_t i = 0; i < device_addrs.size(); i++){ @@ -56,5 +57,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //uhd::device::make(device_addrs[i]); //test make } - return 0; + return EXIT_SUCCESS; } diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 5b3702fb4..736490f19 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -30,6 +30,7 @@ #include <iostream> #include <sstream> #include <vector> +#include <cstdlib> namespace po = boost::program_options; using namespace uhd; @@ -197,12 +198,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //print the help message if (vm.count("help")){ std::cout << boost::format("UHD USRP Probe %s") % desc << std::endl; - return ~0; + return EXIT_FAILURE; } if (vm.count("version")){ std::cout << uhd::get_version_string() << std::endl; - return 0; + return EXIT_SUCCESS; } device::sptr dev = device::make(vm["args"].as<std::string>()); @@ -210,11 +211,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ if (vm.count("string")){ std::cout << tree->access<std::string>(vm["string"].as<std::string>()).get() << std::endl; - return 0; + return EXIT_SUCCESS; } if (vm.count("tree") != 0) print_tree("/", tree); else std::cout << make_border(get_device_pp_string(tree)) << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp index b6b2dc4d6..3ca953115 100644 --- a/host/utils/usrp_burn_db_eeprom.cpp +++ b/host/utils/usrp_burn_db_eeprom.cpp @@ -58,7 +58,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ "Omit the ID argument to perform readback,\n" "Or specify a new ID to burn into the EEPROM.\n" ) << std::endl; - return ~0; + return EXIT_FAILURE; } //make the device and extract the dboard w/ property @@ -96,5 +96,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << boost::format(" Current revision: \"%s\"") % db_eeprom.revision << std::endl; std::cout << " Done" << std::endl << std::endl; - return 0; + return EXIT_SUCCESS; } diff --git a/host/utils/usrp_burn_mb_eeprom.cpp b/host/utils/usrp_burn_mb_eeprom.cpp index ca9a6c8ba..1b13fb615 100644 --- a/host/utils/usrp_burn_mb_eeprom.cpp +++ b/host/utils/usrp_burn_mb_eeprom.cpp @@ -47,7 +47,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ "Omit the value argument to perform a readback,\n" "Or specify a new value to burn into the EEPROM.\n" ) << std::endl; - return ~0; + return EXIT_FAILURE; } std::cout << "Creating USRP device from address: " + args << std::endl; @@ -60,7 +60,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::usrp::mboard_eeprom_t mb_eeprom = tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").get(); if (not mb_eeprom.has_key(key)){ std::cerr << boost::format("Cannot find value for EEPROM[%s]") % key << std::endl; - return ~0; + return EXIT_FAILURE; } std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % key % mb_eeprom[key] << std::endl; std::cout << std::endl; @@ -74,5 +74,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } std::cout << "Done" << std::endl; - return 0; + return EXIT_SUCCESS; } |