diff options
Diffstat (limited to 'host')
46 files changed, 533 insertions, 331 deletions
diff --git a/host/AUTHORS.txt b/host/AUTHORS.txt deleted file mode 100644 index 44b7516cd..000000000 --- a/host/AUTHORS.txt +++ /dev/null @@ -1,40 +0,0 @@ -Matt Ettus - matt@ettus.com - USRP1 FPGA code - USRP2/N200 FPGA code - USRP-E100 FPGA code - -Josh Blum - josh@ettus.com - driver framework - USRP2/N200 firmware - USRP2/N200 host code - USRP-E100 host code - Basic/LF host code - XCVR2450 host code - RFX Series host code - -Jason Abele - jason@ettus.com - RFX Series host code - WBX host code - DBSRX host code - DBSRX2 host code - -Eric Blossom - eb@comsec.com - USRP1 firmware - USRP2 firmware - -Tom Tsou - ttsou@vt.edu - UHD-USB framework - LIBUSB host code - USRP1 host code - USRP1 firmware - -Nick Foster - nick@ettus.com - LIBUSB host code - USRP1 host code - TVRX host code - USRP-N200 firmware - USRP-N200 host code - -Philip Balister - philip@opensdr.com - USRP-E100 kernel module - USRP-E100 utilities diff --git a/host/LICENSE.txt b/host/LICENSE index 9aa03b39b..9aa03b39b 100644 --- a/host/LICENSE.txt +++ b/host/LICENSE diff --git a/host/README.txt b/host/README.txt deleted file mode 100644 index 0e8e62ac1..000000000 --- a/host/README.txt +++ /dev/null @@ -1,43 +0,0 @@ -############################################### -# Ettus Research - USRP Hardware Driver -############################################### -The hardware driver for Ettus Research products. - -############################################### -# Supported USRP Motherboards -############################################### -USRP1 -USRP2 -N200 -N210 -E100 -E110 -B100 -B200 - -############################################### -# Supported USRP Daughterboards -############################################### -Basic RX -Basic TX -LF RX -LF TX -RFX Series -XCVR 2450 -WBX + Simple GDB -DBSRX -DBSRX2 -TVRX -TVRX2 -SBX -CBX - -############################################### -# Documentation -############################################### -Online documentation available at: -http://code.ettus.com/redmine/ettus/projects/uhd/wiki - -The build system can generate the html for the manual and Doxygen. -Docutils and Doxygen are required to build the html docs. -See the docs directory for the manual source (reStructuredText). diff --git a/host/apps/omap_debug/README b/host/apps/omap_debug/README deleted file mode 100644 index bbe0c2cc4..000000000 --- a/host/apps/omap_debug/README +++ /dev/null @@ -1 +0,0 @@ -OMAP development tools go here diff --git a/host/cmake/Modules/FindUSB1.cmake b/host/cmake/Modules/FindUSB1.cmake index a494e1350..b2e4d118c 100644 --- a/host/cmake/Modules/FindUSB1.cmake +++ b/host/cmake/Modules/FindUSB1.cmake @@ -8,7 +8,8 @@ PKG_CHECK_MODULES(PC_LIBUSB QUIET libusb-1.0) FIND_PATH(LIBUSB_INCLUDE_DIRS NAMES libusb.h - HINTS $ENV{LIBUSB_DIR}/include ${PC_LIBUSB_INCLUDEDIR} + HINTS $ENV{LIBUSB_DIR}/include $ENV{LIBUSB_DIR}/include/libusb-1.0 + ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDEDIR}/libusb-1.0 PATHS /usr/local/include/libusb-1.0 /usr/local/include /usr/include/libusb-1.0 /usr/include /opt/local/include/libusb-1.0 diff --git a/host/docs/uhd_find_devices.1 b/host/docs/uhd_find_devices.1 index 7dc0dd470..08f9a789c 100644 --- a/host/docs/uhd_find_devices.1 +++ b/host/docs/uhd_find_devices.1 @@ -9,9 +9,6 @@ The UHD package is the universal hardware driver for Ettus Research products. The goal is to provide a host driver and API for current and future Ettus Research products. Users will be able to use the UHD driver standalone or with 3rd party applications. -.LP -Hardware supporting UHD drivers includes the Universal Software Radio -Peripheral, or USRP, available in several models. .SH SYNOPSIS .B uhd_find_devices [OPTIONS] .SH OPTIONS diff --git a/host/docs/uhd_images_downloader.1 b/host/docs/uhd_images_downloader.1 index ece826cb5..28310dd37 100644 --- a/host/docs/uhd_images_downloader.1 +++ b/host/docs/uhd_images_downloader.1 @@ -7,9 +7,6 @@ products. The goal of the UHD is to provide a host driver and API for current and future Ettus Research products. Users will be able to use the UHD driver standalone or with 3rd party applications. .LP -Hardware supporting UHD drivers includes the Universal Software Radio -Peripheral, or USRP, available in several models. -.LP This program installs the firmware and FPGA binaries from Ettus Research matching this UHD driver release onto the host system. If the uhd-images package is installed, there is no need to run this installer. diff --git a/host/docs/uhd_usrp_probe.1 b/host/docs/uhd_usrp_probe.1 index 7e82bf99a..a6c7150ee 100644 --- a/host/docs/uhd_usrp_probe.1 +++ b/host/docs/uhd_usrp_probe.1 @@ -1,6 +1,6 @@ .TH "uhd_usrp_probe" 1 "3.5.1" UHD "User Commands" .SH NAME -uhd_usrp_probe \- Universal Hardware Driver Peripheral Report Utility +uhd_usrp_probe \- USRP Hardware Driver Peripheral Report Utility .SH DESCRIPTION Report detailed information on UHD-supported Software Radio Peripherals attached by USB, network, or embedded configuration. diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp index bb09296b3..fc1ebd91d 100644 --- a/host/examples/network_relay.cpp +++ b/host/examples/network_relay.cpp @@ -33,8 +33,6 @@ typedef boost::shared_ptr<asio::ip::udp::socket> socket_type; static const size_t insane_mtu = 9000; -boost::mutex spawn_mutex; - #if defined(UHD_PLATFORM_MACOS) //limit buffer resize on macos or it will error const size_t rx_dsp_buff_size = size_t(1e6); @@ -100,14 +98,11 @@ public: } std::cout << "spawning relay threads... " << _port << std::endl; + boost::unique_lock<boost::mutex> lock(spawn_mutex); // lock in preparation to wait for threads to spawn _thread_group.create_thread(boost::bind(&udp_relay_type::server_thread, this)); - spawn_mutex.lock(); - spawn_mutex.lock(); - spawn_mutex.unlock(); + wait_for_thread.wait(lock); // wait for thread to spin up _thread_group.create_thread(boost::bind(&udp_relay_type::client_thread, this)); - spawn_mutex.lock(); - spawn_mutex.lock(); - spawn_mutex.unlock(); + wait_for_thread.wait(lock); // wait for thread to spin up std::cout << " done!" << std::endl << std::endl; } @@ -128,7 +123,7 @@ private: void server_thread(void){ uhd::set_thread_priority_safe(); std::cout << " entering server_thread..." << std::endl; - spawn_mutex.unlock(); + wait_for_thread.notify_one(); // notify constructor that this thread has started std::vector<char> buff(insane_mtu); while (not boost::this_thread::interruption_requested()){ if (wait_for_recv_ready(_server_socket->native())){ @@ -154,7 +149,7 @@ private: void client_thread(void){ uhd::set_thread_priority_safe(); std::cout << " entering client_thread..." << std::endl; - spawn_mutex.unlock(); + wait_for_thread.notify_one(); // notify constructor that this thread has started std::vector<char> buff(insane_mtu); while (not boost::this_thread::interruption_requested()){ if (wait_for_recv_ready(_client_socket->native())){ @@ -172,6 +167,8 @@ private: asio::ip::udp::endpoint _endpoint; boost::mutex _endpoint_mutex; socket_type _server_socket, _client_socket; + boost::mutex spawn_mutex; + boost::condition_variable wait_for_thread; }; diff --git a/host/examples/test_dboard_coercion.cpp b/host/examples/test_dboard_coercion.cpp index cfc745147..86c59d9d7 100644 --- a/host/examples/test_dboard_coercion.cpp +++ b/host/examples/test_dboard_coercion.cpp @@ -53,7 +53,7 @@ std::string return_USRP_config_string(uhd::usrp::multi_usrp::sptr usrp, bool tes if(test_tx){ if(tx_info.get("tx_serial") != "") tx_serial = tx_info.get("tx_serial"); - else tx_serial = "no serial"; + else tx_serial = "no serial"; tx_subdev_name = tx_info.get("tx_subdev_name"); tx_subdev_spec = tx_info.get("tx_subdev_spec"); @@ -121,7 +121,7 @@ std::string tx_test(uhd::usrp::multi_usrp::sptr usrp, bool test_gain, bool verbo gains.push_back(current_gain); current_gain++; } - if(gain_end != *gains.end()) gains.push_back(gain_end); + gains.push_back(gain_end); } @@ -182,19 +182,19 @@ std::string tx_test(uhd::usrp::multi_usrp::sptr usrp, bool test_gain, bool verbo } if(test_gain){ - + //Testing for successful gain tune for(std::vector<double>::iterator g = gains.begin(); g != gains.end(); ++g){ usrp->set_tx_gain(*g); boost::this_thread::sleep(boost::posix_time::microseconds(1000)); - + double actual_gain = usrp->get_tx_gain(); if(*g == 0.0){ if(actual_gain == 0.0){ if(verbose) std::cout << boost::format("TX gain successfully set to %5.2f at TX frequency %s.") % *g % return_MHz_string(*f) << std::endl; - } + } else{ if(verbose) std::cout << boost::format("TX gain set to %5.2f instead of %5.2f at TX frequency %s.") % actual_gain % *g % return_MHz_string(*f) << std::endl; std::vector<double> bad_gain_freq; @@ -313,7 +313,7 @@ std::string rx_test(uhd::usrp::multi_usrp::sptr usrp, bool test_gain, bool verbo gains.push_back(current_gain); current_gain++; } - if(gain_end != *gains.end()) gains.push_back(gain_end); + gains.push_back(gain_end); } @@ -518,7 +518,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "REF must equal internal, external, or mimo." << std::endl; return ~0; } - + if(vm.count("tx") + vm.count("rx") == 0){ std::cout << desc << std::endl; std::cout << "Specify --tx to test for TX frequency coercion\n" @@ -557,12 +557,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); std::cout << boost::format("Checking MIMO lock: %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); std::cout << boost::format("Checking REF lock: %s ...") % ref_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); - } + } usrp_config = return_USRP_config_string(usrp, test_tx, test_rx); if(test_tx) tx_results = tx_test(usrp, test_tx_gain, verbose); if(test_rx) rx_results = rx_test(usrp, test_rx_gain, verbose); diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp index e39a8bd30..4240e830b 100644 --- a/host/examples/test_messages.cpp +++ b/host/examples/test_messages.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// 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 @@ -15,6 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // +#include <uhd/config.hpp> #include <uhd/utils/thread_priority.hpp> #include <uhd/utils/safe_main.hpp> #include <uhd/utils/static.hpp> @@ -84,7 +85,7 @@ bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streame * Issue a stream command with num samps and more. * We expect to get an inline broken chain message. */ -bool test_broken_chain_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){ +bool test_broken_chain_message(UHD_UNUSED(uhd::usrp::multi_usrp::sptr usrp), uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){ std::cout << "Test broken chain message... " << std::flush; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE); diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp index 6fd2932cf..619bd0787 100644 --- a/host/include/uhd/config.hpp +++ b/host/include/uhd/config.hpp @@ -55,18 +55,21 @@ typedef ptrdiff_t ssize_t; #define UHD_INLINE __forceinline #define UHD_DEPRECATED __declspec(deprecated) #define UHD_ALIGNED(x) __declspec(align(x)) + #define UHD_UNUSED(x) x #elif defined(__GNUG__) && __GNUG__ >= 4 #define UHD_EXPORT __attribute__((visibility("default"))) #define UHD_IMPORT __attribute__((visibility("default"))) #define UHD_INLINE inline __attribute__((always_inline)) #define UHD_DEPRECATED __attribute__((deprecated)) #define UHD_ALIGNED(x) __attribute__((aligned(x))) + #define UHD_UNUSED(x) x __attribute__((unused)) #else #define UHD_EXPORT #define UHD_IMPORT #define UHD_INLINE inline #define UHD_DEPRECATED #define UHD_ALIGNED(x) + #define UHD_UNUSED(x) x #endif // Define API declaration macro diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp index fe2974d09..40d7b8c59 100644 --- a/host/include/uhd/transport/zero_copy.hpp +++ b/host/include/uhd/transport/zero_copy.hpp @@ -29,7 +29,9 @@ namespace uhd{ namespace transport{ //! Simple managed buffer with release interface class UHD_API managed_buffer{ public: - managed_buffer(void):_ref_count(0){} + managed_buffer(void):_ref_count(0),_buffer(NULL),_length(0){} + + virtual ~managed_buffer(void) {} /*! * Signal to the transport that we are done with the buffer. diff --git a/host/include/uhd/utils/atomic.hpp b/host/include/uhd/utils/atomic.hpp index 8ddee73ca..55769d2fd 100644 --- a/host/include/uhd/utils/atomic.hpp +++ b/host/include/uhd/utils/atomic.hpp @@ -78,6 +78,10 @@ namespace uhd{ class UHD_API reusable_barrier{ public: + reusable_barrier():_size (0) {} + + reusable_barrier(const size_t size):_size(size) {} + //! Resize the barrier for N threads void resize(const size_t size){ _size = size; diff --git a/host/lib/convert/convert_fc32_item32.cpp b/host/lib/convert/convert_fc32_item32.cpp index 29bfefd46..641fc2608 100644 --- a/host/lib/convert/convert_fc32_item32.cpp +++ b/host/lib/convert/convert_fc32_item32.cpp @@ -28,7 +28,7 @@ typedef boost::uint32_t (*to32_type)(boost::uint32_t); template <typename type, to32_type tohost> struct convert_fc32_item32_1_to_star_1 : public converter { - convert_fc32_item32_1_to_star_1(void) + convert_fc32_item32_1_to_star_1(void):_scalar(0.0) { //NOP } @@ -48,9 +48,9 @@ struct convert_fc32_item32_1_to_star_1 : public converter { const item32_t i32 = tohost(input[i++]); const item32_t q32 = tohost(input[i++]); - const float i_f32 = reinterpret_cast<const float &>(i32); - const float q_f32 = reinterpret_cast<const float &>(q32); - output[o] = std::complex<type>(type(i_f32*_scalar), type(q_f32*_scalar)); + const float *i_f32p = reinterpret_cast<const float *>(&i32); + const float *q_f32p = reinterpret_cast<const float *>(&q32); + output[o] = std::complex<type>(type((*i_f32p)*_scalar), type((*q_f32p)*_scalar)); } } @@ -60,7 +60,7 @@ struct convert_fc32_item32_1_to_star_1 : public converter template <typename type, to32_type towire> struct convert_star_1_to_fc32_item32_1 : public converter { - convert_star_1_to_fc32_item32_1(void) + convert_star_1_to_fc32_item32_1(void):_scalar(0.0) { //NOP } @@ -80,9 +80,10 @@ struct convert_star_1_to_fc32_item32_1 : public converter { const float i_f32 = type(input[i].real()*_scalar); const float q_f32 = type(input[i].imag()*_scalar); - const item32_t i32 = towire(reinterpret_cast<const item32_t &>(i_f32)); - const item32_t q32 = towire(reinterpret_cast<const item32_t &>(q_f32)); - output[o++] = i32; output[o++] = q32; + const item32_t *i32p = reinterpret_cast<const item32_t *>(&i_f32); + const item32_t *q32p = reinterpret_cast<const item32_t *>(&q_f32); + output[o++] = towire(*i32p); + output[o++] = towire(*q32p); } } diff --git a/host/lib/convert/convert_pack_sc12.cpp b/host/lib/convert/convert_pack_sc12.cpp index 680814994..92cd5d152 100644 --- a/host/lib/convert/convert_pack_sc12.cpp +++ b/host/lib/convert/convert_pack_sc12.cpp @@ -67,7 +67,7 @@ void convert_star_4_to_sc12_item32_3 template <typename type, towire32_type towire> struct convert_star_1_to_sc12_item32_1 : public converter { - convert_star_1_to_sc12_item32_1(void) + convert_star_1_to_sc12_item32_1(void):_scalar(0.0) { //NOP } diff --git a/host/lib/convert/convert_unpack_sc12.cpp b/host/lib/convert/convert_unpack_sc12.cpp index e98ab73f1..a2aec2ae5 100644 --- a/host/lib/convert/convert_unpack_sc12.cpp +++ b/host/lib/convert/convert_unpack_sc12.cpp @@ -84,7 +84,7 @@ void convert_sc12_item32_3_to_star_4 template <typename type, tohost32_type tohost> struct convert_sc12_item32_1_to_star_1 : public converter { - convert_sc12_item32_1_to_star_1(void) + convert_sc12_item32_1_to_star_1(void):_scalar(0.0) { //NOP } diff --git a/host/lib/convert/sse2_fc32_to_sc16.cpp b/host/lib/convert/sse2_fc32_to_sc16.cpp index 90bf0ed04..a83e9b46c 100644 --- a/host/lib/convert/sse2_fc32_to_sc16.cpp +++ b/host/lib/convert/sse2_fc32_to_sc16.cpp @@ -27,6 +27,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)); + // this macro converts values faster by using SSE intrinsics to convert 4 values at a time #define convert_fc32_1_to_item32_1_nswap_guts(_al_) \ for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ @@ -48,17 +49,25 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){ size_t i = 0; - //dispatch according to alignment + // need to dispatch according to alignment for fastest conversion switch (size_t(input) & 0xf){ - case 0x8: - xx_to_item32_sc16<uhd::htowx>(input, output, 1, scale_factor); i++; case 0x0: + // the data is 16-byte aligned, so do the fast processing of the bulk of the samples + convert_fc32_1_to_item32_1_nswap_guts(_) + break; + case 0x8: + // the first sample is 8-byte aligned - process it to align the remainder of the samples to 16-bytes + xx_to_item32_sc16<uhd::htowx>(input, output, 1, scale_factor); + i++; + // do faster processing of the bulk of the samples now that we are 16-byte aligned convert_fc32_1_to_item32_1_nswap_guts(_) break; - default: convert_fc32_1_to_item32_1_nswap_guts(u_) + default: + // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load + convert_fc32_1_to_item32_1_nswap_guts(u_) } - //convert remainder + // convert any remaining samples xx_to_item32_sc16<uhd::htowx>(input+i, output+i, nsamps-i, scale_factor); } @@ -68,6 +77,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)); + // this macro converts values faster by using SSE intrinsics to convert 4 values at a time #define convert_fc32_1_to_item32_1_bswap_guts(_al_) \ for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ @@ -88,16 +98,24 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){ size_t i = 0; - //dispatch according to alignment + // need to dispatch according to alignment for fastest conversion switch (size_t(input) & 0xf){ - case 0x8: - xx_to_item32_sc16<uhd::htonx>(input, output, 1, scale_factor); i++; case 0x0: + // the data is 16-byte aligned, so do the fast processing of the bulk of the samples + convert_fc32_1_to_item32_1_bswap_guts(_) + case 0x8: + // the first value is 8-byte aligned - process it and prepare the bulk of the data for fast conversion + xx_to_item32_sc16<uhd::htonx>(input, output, 1, scale_factor); + i++; + // do faster processing of the remaining samples now that we are 16-byte aligned convert_fc32_1_to_item32_1_bswap_guts(_) break; - default: convert_fc32_1_to_item32_1_bswap_guts(u_) + break; + default: + // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load + convert_fc32_1_to_item32_1_bswap_guts(u_) } - //convert remainder + // convert any remaining samples xx_to_item32_sc16<uhd::htonx>(input+i, output+i, nsamps-i, scale_factor); } diff --git a/host/lib/convert/sse2_sc16_to_fc32.cpp b/host/lib/convert/sse2_sc16_to_fc32.cpp index c03e41585..0ac7f1798 100644 --- a/host/lib/convert/sse2_sc16_to_fc32.cpp +++ b/host/lib/convert/sse2_sc16_to_fc32.cpp @@ -28,6 +28,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16)); const __m128i zeroi = _mm_setzero_si128(); + // this macro converts values faster by using SSE intrinsics to convert 4 values at a time #define convert_item32_1_to_fc32_1_nswap_guts(_al_) \ for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ @@ -50,17 +51,25 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){ size_t i = 0; - //dispatch according to alignment + // need to dispatch according to alignment for fastest conversion switch (size_t(output) & 0xf){ - case 0x8: - item32_sc16_to_xx<uhd::htowx>(input, output, 1, scale_factor); i++; case 0x0: + // the data is 16-byte aligned, so do the fast processing of the bulk of the samples + convert_item32_1_to_fc32_1_nswap_guts(_) + break; + case 0x8: + // the first sample is 8-byte aligned - process it to align the remainder of the samples to 16-bytes + item32_sc16_to_xx<uhd::htowx>(input, output, 1, scale_factor); + i++; + // do faster processing of the bulk of the samples now that we are 16-byte aligned convert_item32_1_to_fc32_1_nswap_guts(_) break; - default: convert_item32_1_to_fc32_1_nswap_guts(u_) + default: + // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load and store + convert_item32_1_to_fc32_1_nswap_guts(u_) } - //convert remainder + // convert any remaining samples item32_sc16_to_xx<uhd::htowx>(input+i, output+i, nsamps-i, scale_factor); } @@ -71,6 +80,7 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_SIMD){ const __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16)); const __m128i zeroi = _mm_setzero_si128(); + // this macro converts values faster by using SSE intrinsics to convert 4 values at a time #define convert_item32_1_to_fc32_1_bswap_guts(_al_) \ for (; i+3 < nsamps; i+=4){ \ /* load from input */ \ @@ -92,16 +102,24 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_SIMD){ size_t i = 0; - //dispatch according to alignment + // need to dispatch according to alignment for fastest conversion switch (size_t(output) & 0xf){ - case 0x8: - item32_sc16_to_xx<uhd::htonx>(input, output, 1, scale_factor); i++; case 0x0: + // the data is 16-byte aligned, so do the fast processing of the bulk of the samples + convert_item32_1_to_fc32_1_bswap_guts(_) + break; + case 0x8: + // the first sample is 8-byte aligned - process it to align the remainder of the samples to 16-bytes + item32_sc16_to_xx<uhd::htonx>(input, output, 1, scale_factor); + i++; + // do faster processing of the bulk of the samples now that we are 16-byte aligned convert_item32_1_to_fc32_1_bswap_guts(_) break; - default: convert_item32_1_to_fc32_1_bswap_guts(u_) + default: + // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load and store + convert_item32_1_to_fc32_1_bswap_guts(u_) } - //convert remainder + // convert any remaining samples item32_sc16_to_xx<uhd::htonx>(input+i, output+i, nsamps-i, scale_factor); } diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index 688228e49..5080182d6 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -246,7 +246,8 @@ private: struct xport_chan_props_type{ xport_chan_props_type(void): packet_count(0), - handle_overflow(&handle_overflow_nop) + handle_overflow(&handle_overflow_nop), + fc_update_window(0) {} get_buff_type get_buff; issue_stream_cmd_type issue_stream_cmd; diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 41f030ea6..ae483d1f3 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -239,7 +239,7 @@ private: size_t _header_offset_words32; double _tick_rate, _samp_rate; struct xport_chan_props_type{ - xport_chan_props_type(void):has_sid(false){} + xport_chan_props_type(void):has_sid(false),sid(0){} get_buff_type get_buff; bool has_sid; boost::uint32_t sid; diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp index 166177177..7b6a476f5 100644 --- a/host/lib/transport/udp_zero_copy.cpp +++ b/host/lib/transport/udp_zero_copy.cpp @@ -68,7 +68,7 @@ static void check_registry_for_fast_send_threshold(const size_t mtu){ class udp_zero_copy_asio_mrb : public managed_recv_buffer{ public: udp_zero_copy_asio_mrb(void *mem, int sock_fd, const size_t frame_size): - _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) { /*NOP*/ } + _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size), _len(0) { /*NOP*/ } void release(void){ _claimer.release(); @@ -87,6 +87,7 @@ public: if (wait_for_recv_ready(_sock_fd, timeout)){ _len = ::recv(_sock_fd, (char *)_mem, _frame_size, 0); + UHD_ASSERT_THROW(_len > 0); // TODO: Handle case of recv error index++; //advances the caller's buffer return make(this, _mem, size_t(_len)); } diff --git a/host/lib/types/tune.cpp b/host/lib/types/tune.cpp index 154f0990f..7697bd966 100644 --- a/host/lib/types/tune.cpp +++ b/host/lib/types/tune.cpp @@ -24,7 +24,9 @@ using namespace uhd; tune_request_t::tune_request_t(double target_freq): target_freq(target_freq), rf_freq_policy(POLICY_AUTO), - dsp_freq_policy(POLICY_AUTO) + rf_freq(0.0), + dsp_freq_policy(POLICY_AUTO), + dsp_freq(0.0) { /* NOP */ } @@ -33,7 +35,8 @@ tune_request_t::tune_request_t(double target_freq, double lo_off): target_freq(target_freq), rf_freq_policy(POLICY_MANUAL), rf_freq(target_freq + lo_off), - dsp_freq_policy(POLICY_AUTO) + dsp_freq_policy(POLICY_AUTO), + dsp_freq(0.0) { /* NOP */ } diff --git a/host/lib/usrp/README b/host/lib/usrp/README deleted file mode 100644 index 344209179..000000000 --- a/host/lib/usrp/README +++ /dev/null @@ -1,15 +0,0 @@ -######################################################################## -# lib USRP directories: -######################################################################## - -dboard: - Daughterboard implementation code for all USRP daughterboards - -usrp1: - Implementation code for the USB-based USRP Classic motherboard. - -usrp2: - Implementation code for USRP2, USRP-N200, and USRP-N210. - -usrp_e100: - Implementation code for USRP-E100. diff --git a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp index 2096e4ef4..451cdae50 100644 --- a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp +++ b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp @@ -167,6 +167,7 @@ public: usb_zero_copy_wrapper(zero_copy_if::sptr usb_zc, const size_t frame_boundary): _internal_zc(usb_zc), _frame_boundary(frame_boundary), + _last_recv_offset(0), _next_recv_buff_index(0) { for (size_t i = 0; i < this->get_num_recv_frames(); i++){ diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp index bb46fbfce..7a52f1969 100644 --- a/host/lib/usrp/b200/b200_iface.cpp +++ b/host/lib/usrp/b200/b200_iface.cpp @@ -17,6 +17,7 @@ #include "b200_iface.hpp" +#include <uhd/config.hpp> #include <uhd/utils/msg.hpp> #include <uhd/exception.hpp> #include <boost/functional/hash.hpp> @@ -163,6 +164,9 @@ bool parse_record(std::string *record, boost::uint16_t &len, \ std::istringstream(record->substr(3, 4)) >> std::hex >> addr; std::istringstream(record->substr(7, 2)) >> std::hex >> type; + if (len > (2 * (record->length() - 9))) // sanity check to prevent buffer overrun + return false; + for (i = 0; i < len; i++) { std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val; data[i] = (unsigned char) val; @@ -219,13 +223,13 @@ public: } - void write_i2c(boost::uint16_t addr, const byte_vector_t &bytes) + void write_i2c(UHD_UNUSED(boost::uint16_t addr), UHD_UNUSED(const byte_vector_t &bytes)) { throw uhd::not_implemented_error("b200 write i2c"); } - byte_vector_t read_i2c(boost::uint16_t addr, size_t num_bytes) + byte_vector_t read_i2c(UHD_UNUSED(boost::uint16_t addr), UHD_UNUSED(size_t num_bytes)) { throw uhd::not_implemented_error("b200 read i2c"); } @@ -300,7 +304,7 @@ public: } - void load_firmware(const std::string filestring, bool force = false) + void load_firmware(const std::string filestring, UHD_UNUSED(bool force) = false) { const char *filename = filestring.c_str(); @@ -330,6 +334,9 @@ public: std::string record; file >> record; + if (!(record.length() > 0)) + continue; + /* Check for valid Intel HEX record. */ if (!checksum(&record) || !parse_record(&record, len, \ lower_address_bits, type, data)) { @@ -426,7 +433,9 @@ public: UHD_THROW_INVALID_CODE_PATH(); - fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, 4); + // Below is dead code as long as UHD_THROW_INVALID_CODE_PATH(); is declared above. + // It is preserved here in a comment in case it is needed later: + // fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, 4); } boost::uint8_t get_usb_speed(void) { diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index 6111efea9..d68bf6058 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -119,6 +119,9 @@ bool parse_record(std::string *record, unsigned int &len, std::istringstream(record->substr(3, 4)) >> std::hex >> addr; std::istringstream(record->substr(7, 2)) >> std::hex >> type; + if (len > (2 * (record->length() - 9))) // sanity check to prevent buffer overrun + return false; + for (i = 0; i < len; i++) { std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val; data[i] = (unsigned char) val; @@ -181,6 +184,9 @@ public: std::string record; file >> record; + if (!(record.length() > 0)) + continue; + //check for valid record if (not checksum(&record) or not parse_record(&record, len, addr, type, data)) { throw uhd::io_error("usrp_load_firmware: bad record checksum"); diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index ef6b85de9..2fdc220b5 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -59,8 +59,11 @@ public: const size_t dsp_base, const size_t ctrl_base, const boost::uint32_t sid, const bool lingering_packet ): - _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) + _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) { + // previously uninitialized - assuming zero for all + _tick_rate = _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0; + //init to something so update method has reasonable defaults _scaling_adjustment = 1.0; _dsp_extra_scaling = 1.0; diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.cpp b/host/lib/usrp/cores/rx_dsp_core_3000.cpp index 7b3324f74..525916032 100644 --- a/host/lib/usrp/cores/rx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_3000.cpp @@ -50,10 +50,13 @@ public: ): _iface(iface), _dsp_base(dsp_base) { + // previously uninitialized - assuming zero for all + _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0; + //init to something so update method has reasonable defaults _scaling_adjustment = 1.0; _dsp_extra_scaling = 1.0; - this->set_tick_rate(1.0); + _tick_rate = 1.0; } ~rx_dsp_core_3000_impl(void) diff --git a/host/lib/usrp/cores/rx_frontend_core_200.cpp b/host/lib/usrp/cores/rx_frontend_core_200.cpp index 09b36c1a6..864b5cc53 100644 --- a/host/lib/usrp/cores/rx_frontend_core_200.cpp +++ b/host/lib/usrp/cores/rx_frontend_core_200.cpp @@ -38,7 +38,7 @@ static boost::uint32_t fs_to_bits(const double num, const size_t bits){ class rx_frontend_core_200_impl : public rx_frontend_core_200{ public: rx_frontend_core_200_impl(wb_iface::sptr iface, const size_t base): - _iface(iface), _base(base) + _i_dc_off(0), _q_dc_off(0), _iface(iface), _base(base) { //NOP } diff --git a/host/lib/usrp/cores/time64_core_200.cpp b/host/lib/usrp/cores/time64_core_200.cpp index 11b310362..ad5e6477c 100644 --- a/host/lib/usrp/cores/time64_core_200.cpp +++ b/host/lib/usrp/cores/time64_core_200.cpp @@ -48,6 +48,7 @@ public: ): _iface(iface), _base(base), _readback_bases(readback_bases), + _tick_rate(0.0), _mimo_delay_cycles(mimo_delay_cycles) { _sources.push_back("none"); diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 808f13028..f8aa87aa3 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -60,6 +60,9 @@ public: ): _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid) { + // previously uninitialized - assuming zero for all + _tick_rate = _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0; + //init to something so update method has reasonable defaults _scaling_adjustment = 1.0; _dsp_extra_scaling = 1.0; diff --git a/host/lib/usrp/cores/tx_dsp_core_3000.cpp b/host/lib/usrp/cores/tx_dsp_core_3000.cpp index feb749cd9..93c8702bc 100644 --- a/host/lib/usrp/cores/tx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_3000.cpp @@ -45,6 +45,9 @@ public: ): _iface(iface), _dsp_base(dsp_base) { + // previously uninitialized - assuming zero for all + _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0; + //init to something so update method has reasonable defaults _scaling_adjustment = 1.0; _dsp_extra_scaling = 1.0; diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index b1cee4aa7..9d04d8e16 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -179,7 +179,7 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ "DBSRX: incorrect dbid\n" "Expected dbid 0x0002 and R193\n" "found dbid == %d\n" - "Please see the daughterboard app notes" + "Please see the daughterboard app notes" ) % this->get_rx_id().to_pp_string(); //warn user about incorrect DBID on non-USRP1, requires R194 populated @@ -188,7 +188,7 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ "DBSRX: incorrect dbid\n" "Expected dbid 0x000D and R194\n" "found dbid == %d\n" - "Please see the daughterboard app notes" + "Please see the daughterboard app notes" ) % this->get_rx_id().to_pp_string(); //send initial register settings @@ -305,13 +305,13 @@ double dbsrx::set_lo_freq(double target_freq){ goto done_loop; } - } + } done_loop: - //Assert because we failed to find a suitable combination of ref_clock, R and N + //Assert because we failed to find a suitable combination of ref_clock, R and N UHD_ASSERT_THROW(ref_clock <= 27.0e6 and ref_clock >= 0.0); - UHD_ASSERT_THROW(ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6); + UHD_ASSERT_THROW(m and ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6); UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) and (pfd_freq <= dbsrx_pfd_freq_range.stop())); UHD_ASSERT_THROW((N >= 256) and (N <= 32768)); @@ -332,7 +332,7 @@ double dbsrx::set_lo_freq(double target_freq){ _max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t) r; _max2118_write_regs.set_n_divider(N); _max2118_write_regs.ade_vco_ade_read = max2118_write_regs_t::ADE_VCO_ADE_READ_ENABLED; - + //compute prescaler variables int scaler = actual_freq > 1125e6 ? 2 : 4; _max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 : max2118_write_regs_t::DIV2_DIV2; @@ -377,7 +377,7 @@ double dbsrx::set_lo_freq(double target_freq){ if (_max2118_read_regs.adc == 0){ if (_max2118_write_regs.osc_band == 0){ UHD_MSG(warning) << boost::format( - "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" + "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" ) % int(_max2118_write_regs.osc_band); UHD_ASSERT_THROW(_max2118_read_regs.adc != 0); //just to cause a throw } @@ -389,7 +389,7 @@ double dbsrx::set_lo_freq(double target_freq){ if (_max2118_read_regs.adc == 7){ if (_max2118_write_regs.osc_band == 7){ UHD_MSG(warning) << boost::format( - "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" + "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" ) % int(_max2118_write_regs.osc_band); UHD_ASSERT_THROW(_max2118_read_regs.adc != 7); //just to cause a throw } @@ -408,7 +408,7 @@ double dbsrx::set_lo_freq(double target_freq){ //allow for setup time before checking condition again boost::this_thread::sleep(boost::posix_time::milliseconds(10)); } - + UHD_LOGV(often) << boost::format( "DBSRX: final vco %d, vtune adc %d" ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl; @@ -417,7 +417,7 @@ double dbsrx::set_lo_freq(double target_freq){ if (_max2118_read_regs.adc <= 2) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA; else if (_max2118_read_regs.adc >= 5) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA; else _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA; - + //update charge pump bias current setting send_reg(0x2, 0x2); @@ -524,7 +524,7 @@ double dbsrx::set_bandwidth(double bandwidth){ bandwidth = dbsrx_bandwidth_range.clip(bandwidth); double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); - + //NOTE: _max2118_write_regs.m_divider set in set_lo_freq //compute f_dac setting diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index edee46cd5..e9f60f765 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -267,7 +267,7 @@ static std::string get_band(double freq) { * \return a voltage to feed the TVRX analog gain */ -static double gain_interp(double gain, boost::array<double, 17> db_vector, boost::array<double, 17> volts_vector) { +static double gain_interp(double gain, const boost::array<double, 17>& db_vector, const boost::array<double, 17>& volts_vector) { double volts; gain = uhd::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp index 9e984dce7..d1beb160e 100644 --- a/host/lib/usrp/dboard/db_wbx_common.hpp +++ b/host/lib/usrp/dboard/db_wbx_common.hpp @@ -118,7 +118,7 @@ protected: */ class wbx_versionx { public: - wbx_versionx() {} + wbx_versionx():self_base(NULL) {} ~wbx_versionx(void) {} virtual double set_tx_gain(double gain, const std::string &name) = 0; diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index c3af75faa..105a52b30 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -223,7 +223,6 @@ private: boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS)); } throw uhd::value_error(str(boost::format("get_nmea(): no %s message found") % msgtype)); - return std::string(); } //helper function to retrieve a field from an NMEA sentence @@ -322,7 +321,6 @@ private: 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; diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index d384eb13f..e1f17e5a6 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -63,7 +63,7 @@ static const size_t alignment_padding = 512; * Helper struct to associate an offset with a buffer **********************************************************************/ struct offset_send_buffer{ - offset_send_buffer(void){ + offset_send_buffer(void):offset(0){ /* NOP */ } diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp index 9301721aa..6eff9d3ad 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.cpp +++ b/host/lib/usrp/usrp1/usrp1_iface.cpp @@ -91,11 +91,11 @@ public: return uhd::ntohx(value_out); } - + void poke16(boost::uint32_t, boost::uint16_t) { throw uhd::not_implemented_error("Unhandled command poke16()"); } - + boost::uint16_t peek16(boost::uint32_t) { throw uhd::not_implemented_error("Unhandled command peek16()"); return 0; @@ -141,8 +141,10 @@ public: if (readback) { unsigned char buff[4] = { - (bits >> 0) & 0xff, (bits >> 8) & 0xff, - (bits >> 16) & 0xff, (bits >> 24) & 0xff + (unsigned char)(bits & 0xff), + (unsigned char)((bits >> 8) & 0xff), + (unsigned char)((bits >> 16) & 0xff), + (unsigned char)((bits >> 24) & 0xff) }; //conditions where there are two header bytes if (num_bytes >= 3 and buff[num_bytes-1] != 0 and buff[num_bytes-2] != 0 and buff[num_bytes-3] == 0){ @@ -168,7 +170,7 @@ public: (((boost::uint32_t)buff[1]) << 8) | (((boost::uint32_t)buff[2]) << 16) | (((boost::uint32_t)buff[3]) << 24); - return val; + return val; } else { // Byteswap on num_bytes diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp index 8b185eac0..d5e506d8d 100644 --- a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp @@ -22,8 +22,18 @@ class usrp2_clk_regs_t { public: - usrp2_clk_regs_t(void) { ; } + usrp2_clk_regs_t(void): + test(0), + fpga(0), + adc(0), + dac(0), + serdes(0), + exp(0), + tx_db(0), + rx_db(0) {} + usrp2_clk_regs_t(usrp2_iface::rev_type rev) { + fpga = adc = serdes = exp = tx_db = 0; test = 0; fpga = 1; dac = 3; @@ -54,7 +64,7 @@ public: //dont throw, it may be unitialized break; } - + rx_db = 7; } diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 3b230ca69..5f97045e1 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -271,7 +271,7 @@ public: //send and recv usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C); UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); - UHD_ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes); + UHD_ASSERT_THROW(in_data.data.i2c_args.bytes == num_bytes); //copy out the data byte_vector_t result(num_bytes); diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp index 25cade693..3e2bea1c6 100644 --- a/host/lib/utils/paths.cpp +++ b/host/lib/utils/paths.cpp @@ -115,8 +115,8 @@ std::string uhd::get_tmp_path(void){ //try the stdio define if available #ifdef P_tmpdir - if (P_tmpdir != NULL) return P_tmpdir; - #endif + return P_tmpdir; + #else //try unix environment variables tmp_path = std::getenv("TMPDIR"); @@ -124,6 +124,7 @@ std::string uhd::get_tmp_path(void){ //give up and use the unix default return "/tmp"; + #endif } std::string uhd::get_app_path(void){ diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp index 9339a9739..316e24779 100644 --- a/host/tests/sph_recv_test.cpp +++ b/host/tests/sph_recv_test.cpp @@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){ //check the received packets size_t num_accum_samps = 0; - std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS); + std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; std::vector<std::complex<float> *> buffs(NCHANNELS); for (size_t ch = 0; ch < NCHANNELS; ch++){ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; @@ -481,7 +481,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){ //check the received packets size_t num_accum_samps = 0; - std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS); + std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; std::vector<std::complex<float> *> buffs(NCHANNELS); for (size_t ch = 0; ch < NCHANNELS; ch++){ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; @@ -574,7 +574,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){ //check the received packets size_t num_accum_samps = 0; - std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS); + std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; std::vector<std::complex<float> *> buffs(NCHANNELS); for (size_t ch = 0; ch < NCHANNELS; ch++){ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; @@ -659,7 +659,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ //check the received packets size_t num_accum_samps = 0; - std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS); + std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; std::vector<std::complex<float> *> buffs(NCHANNELS); for (size_t ch = 0; ch < NCHANNELS; ch++){ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; diff --git a/host/tests/time_spec_test.cpp b/host/tests/time_spec_test.cpp index 37a039cc5..c9b9652f9 100644 --- a/host/tests/time_spec_test.cpp +++ b/host/tests/time_spec_test.cpp @@ -117,6 +117,7 @@ BOOST_AUTO_TEST_CASE(test_time_error_irrational_rate) const uhd::time_spec_t ts = uhd::time_spec_t::from_ticks(tick_in, rate); const long long tick_out = ts.to_ticks(rate); const long long err = tick_in - tick_out; + std::streamsize precision = std::cout.precision(); std::cout << std::setprecision(18); std::cout << "time ............ " << ts.get_real_secs() << std::endl; @@ -124,6 +125,7 @@ BOOST_AUTO_TEST_CASE(test_time_error_irrational_rate) std::cout << "tick out ........ " << tick_out << std::endl; std::cout << "tick error ...... " << err << std::endl; std::cout << std::endl; + std::cout.precision(precision); BOOST_CHECK_EQUAL(err, (long long)(0)); } diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp index c182548b7..adacff9d0 100644 --- a/host/utils/b2xx_fx3_utils.cpp +++ b/host/utils/b2xx_fx3_utils.cpp @@ -209,7 +209,9 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) { po::notify(vm); if (vm.count("help")){ - std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; + try { + std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; + } catch(...) {} return ~0; } else if (vm.count("reset-usb")) { return reset_usb(); @@ -220,10 +222,15 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) { vid = B200_VENDOR_ID; // Default pid = B200_PRODUCT_ID; // Default - if (vm.count("vid")) - vid = atoh(vid_str); - if (vm.count("pid")) - pid = atoh(pid_str); + try { + if (vm.count("vid")) + vid = atoh(vid_str); + if (vm.count("pid")) + pid = atoh(pid_str); + } catch (std::exception &e) { + std::cerr << "Exception while parsing VID and PID: " << e.what() << std:: endl; + return ~0; + } // open the device handle = open_device(vid, pid); @@ -243,7 +250,11 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) { std::cout << "Overwriting existing firmware" << std::endl; // reset the device - b200->reset_fx3(); + try { + b200->reset_fx3(); + } catch (std::exception &e) { + std::cerr << "Exception while reseting FX3: " << e.what() << std::endl; + } // re-open device b200.reset(); @@ -264,19 +275,24 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) { if (fw_file.empty()) fw_file = uhd::find_image_path(B200_FW_FILE_NAME); - + if(fw_file.empty()) { std::cerr << "Firmware image not found!" << std::endl; return -1; } - + if(!(fs::exists(fw_file))) { std::cerr << "Invalid filepath: " << fw_file << std::endl; return -1; } // load firmware - b200->load_firmware(fw_file); + try { + b200->load_firmware(fw_file); + } catch (std::exception &e) { + std::cerr << "Exception while loading firmware: " << e.what() << std::endl; + return ~0; + } // re-open device b200.reset(); @@ -403,7 +419,7 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) { try { b200->reset_fx3(); } catch (const std::exception &e) { - std::cerr << "Exceptions while resetting device: " << e.what() << std::endl; + std::cerr << "Exception while resetting device: " << e.what() << std::endl; return -1; } @@ -461,7 +477,9 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) { << std::endl; } else { - std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; + try { + std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; + } catch(...) {} return ~0; } diff --git a/host/utils/uhd_images_downloader.py.in b/host/utils/uhd_images_downloader.py.in index bb082190c..697bd4e16 100644 --- a/host/utils/uhd_images_downloader.py.in +++ b/host/utils/uhd_images_downloader.py.in @@ -16,144 +16,341 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -import atexit -import hashlib +import sys, os, string, tempfile, math +import traceback +import shutil, hashlib, urllib2, zipfile + from optparse import OptionParser -import os -import os.path -import shutil -import string -import sys -import tempfile -import urllib2 -import zipfile + +_DEFAULT_BUFFER_SIZE = 8192 +_BASE_DIR_STRUCTURE_PARTS = ["share", "uhd", "images"] +_BASE_DIR_STRUCTURE = os.path.join(_BASE_DIR_STRUCTURE_PARTS) +_DEFAULT_INSTALL_PATH = os.path.join("@CMAKE_INSTALL_PREFIX@", *_BASE_DIR_STRUCTURE) +_AUTOGEN_IMAGES_SOURCE = "@UHD_IMAGES_DOWNLOAD_SRC@" +_AUTOGEN_IMAGES_CHECKSUM = "@UHD_IMAGES_MD5SUM@" +_IMAGES_CHECKSUM_TYPE = "md5" +_CONTACT = "support@ettus.com" def md5Checksum(filePath): - with open(filePath, 'rb') as fh: - m = hashlib.md5() - while True: - data = fh.read(8192) - if not data: - break - m.update(data) - return m.hexdigest() + try: + with open(filePath, 'rb') as fh: + m = hashlib.md5() + while True: + data = fh.read(_DEFAULT_BUFFER_SIZE) + if not data: + break + m.update(data) + return m.hexdigest() + except Exception, e: + print "Failed to calculated MD5 sum of: %s (%s)" % (filePath, e) + raise e -class temp_dir(): +_checksum_fns = { + 'md5': md5Checksum +} +class temporary_directory(): def __enter__(self): - self.name = tempfile.mkdtemp() - return self.name + try: + self.name = tempfile.mkdtemp() + return self.name + except Exception, e: + print "Failed to create a temporary directory (%s)" % (e) + raise e + + # Can return 'True' to suppress incoming exception def __exit__(self, type, value, traceback): try: shutil.rmtree(self.name) - except OSError,e: - #Utility should have already detected this, but this is for safety - print str(e) - raise Exception("Could not install images! Make sure you have write permissions.") - -if __name__ == "__main__": - - print - if os.environ.get("UHD_IMAGES_DIR") != None and os.environ.get("UHD_IMAGES_DIR") != "": - default_images_dir = os.environ.get("UHD_IMAGES_DIR") - print "UHD_IMAGES_DIR environment variable is set. Default install location: %s" % default_images_dir - else: - default_images_dir = "@CMAKE_INSTALL_PREFIX@/share/uhd/images" + except Exception, e: + print "Could not delete temporary directory: %s (%s)" % (self.name, e) - #Command line options - parser = OptionParser() - parser.add_option("--install-location", type="string", default=default_images_dir, help="Set custom install location for images") - parser.add_option("--buffer-size", type="int", default=8192, help="Set download buffer size, [default=%default]",) - (options, args) = parser.parse_args() +class uhd_images_downloader(): + def __init__(self): + pass - #Configuring image download info - images_src = "@UHD_IMAGES_DOWNLOAD_SRC@" - images_zip_md5sum = "@UHD_IMAGES_MD5SUM@" - filename = images_src.split("/")[-1] - - #Use this directory with relative paths - current_directory = os.getcwd() - - with temp_dir() as dirname: - os.chdir(dirname) - - if os.path.isabs(options.install_location): - #Custom absolute path given - images_dir = options.install_location - else: - #Custom relative path given, so construct absolute path - images_dir = os.path.abspath(os.path.join(current_directory, options.install_location)) - - #Before doing anything, check for write permissions in parent directory - parent_directory = os.path.dirname(images_dir) - if os.access(parent_directory, os.W_OK): - print "Downloading images to: %s" % images_dir - else: - print "You do not have write permissions at the install location!" - sys.exit(1) - + def download(self, images_url, filename, buffer_size=_DEFAULT_BUFFER_SIZE, print_progress=False): opener = urllib2.build_opener() opener.add_headers = [('User-Agent', 'UHD Images Downloader')] - u = opener.open(images_src) - f = open(filename, "wb") + u = opener.open(images_url) meta = u.info() filesize = float(meta.getheaders("Content-Length")[0]) - print "Downloading images from: %s" % images_src + filesize_dl = 0 - filesize_dl = 0.0 - - #Downloading file - while True: - buffer = u.read(options.buffer_size) - if not buffer: - break - - filesize_dl -= len(buffer) - f.write(buffer) + with open(filename, "wb") as f: + while True: + buffer = u.read(buffer_size) + if not buffer: + break + + f.write(buffer) - status = r"%2.2f MB/%2.2f MB (%3.2f" % (-filesize_dl/1e6, filesize/1e6, (-filesize_dl*100.)/filesize) + r"%)" - status += chr(8)*(len(status)+1) - print status, + filesize_dl += len(buffer) + + if print_progress: + status = r"%05d kB / %05d kB (%03d%%)" % (int(math.ceil(filesize_dl/1000.)), int(math.ceil(filesize/1000.)), int(math.ceil(filesize_dl*100.)/filesize)) + status += chr(8)*(len(status)+1) + print status, - f.close() - - #Checking md5sum of zip file - downloaded_zip_md5sum = md5Checksum(filename) - if images_zip_md5sum != downloaded_zip_md5sum: - print "\nMD5 checksum does not match!" - print "Expected %s, got %s" % (images_zip_md5sum, downloaded_zip_md5sum) - print "Images did not install. If problem persists, please contact support@ettus.com." - os.remove(filename) - os.chdir("/".join(images_dir.split("/")[:-1])) - sys.exit(1) + if print_progress: + print + + return (filesize, filesize_dl) + + def check_directories(self, dirs, print_progress=False): + if dirs is None or dirs == "": + dirs = "." + dirs = os.path.abspath(dirs) + + def _check_part(head, tail=None): + if print_progress: + print "Checking: %s" % (head) + if tail is not None and tail == "": + return True + if not os.path.exists(head): + if print_progress: + print "Does not exist: %s" % (head) + return _check_part(*os.path.split(head)) + if not os.path.isdir(head): + if print_progress: + print "Is not a directory: %s" % (head) + return (False, head) + if not os.access(head, os.W_OK): + if print_progress: + print "Write permission denied on: %s" % (head) + return (False, head) + if print_progress: + print "Write permission granted on: %s" % (head) + return (True, head) + + return _check_part(dirs) + + def validate_checksum(self, checksum_fn, file_path, expecting, print_progress=False): + if checksum_fn is None: + return (True, "") + + calculated_checksum = checksum_fn(file_path) + + if (expecting is not None) and (expecting != "") and calculated_checksum != expecting: + return (False, calculated_checksum) + + return (True, calculated_checksum) + + def extract_images_archive(self, archive_path, destination=None, print_progress=False): + if not os.path.exists(archive_path): + if print_progress: + print "Path does not exist: %s" % (archive_path) + raise Exception("path does not exist: %s" % (archive_path)) + + if print_progress: + print "Archive path: %s" % (archive_path) + + (head, tail) = os.path.split(archive_path) + + if not os.access(head, os.W_OK): + if print_progress: + print "Write access denied on: %s" % (head) + raise Exception("write access denied on: %s" % (head)) + + (root, ext) = os.path.splitext(tail) + temp_dir = os.path.join(head, root) + + if print_progress: + print "Temporary extraction location: %s" % (temp_dir) + + if os.path.exists(temp_dir): + if print_progress: + print "Deleting existing location: %s" % (temp_dir) + shutil.rmtree(temp_dir) + + if print_progress: + print "Creating directory: %s" % (temp_dir) + os.mkdir(temp_dir) + + if print_progress: + print "Extracting archive %s to %s" % (archive_path, temp_dir) + + images_zip = zipfile.ZipFile(archive_path) + images_zip.extractall(temp_dir) + images_zip.close() + + return temp_dir + + def install_images(self, source, dest, keep=False, print_progress=False): + if not os.path.exists(source): + if print_progress: + print "Source path does not exist: %s" % (source) + return + + if keep: + if print_progress: + print "Not wiping directory tree (existing files will be overwritten): %s" % (dest) + elif os.path.exists(dest): + if print_progress: + print "Deleting directory tree: %s" % (dest) + shutil.rmtree(dest) + + (head, tail) = os.path.split(source) + + if print_progress: + print "Source install path: %s" % (source) + + uhd_source = os.path.join(source, tail, *_BASE_DIR_STRUCTURE_PARTS) + + if print_progress: + print "Copying files from: %s" % (uhd_source) + print "Copying files to: %s" % (dest) + + if keep: + # mgrant @ http://stackoverflow.com/questions/12683834/how-to-copy-directory-recursively-in-python-and-overwrite-all + def _recursive_overwrite(src, dest, ignore=None): + if os.path.isdir(src): + if not os.path.isdir(dest): + os.makedirs(dest) + files = os.listdir(src) + if ignore is not None: + ignored = ignore(src, files) + else: + ignored = set() + for f in files: + if f not in ignored: + _recursive_overwrite(os.path.join(src, f), os.path.join(dest, f), ignore) + else: + shutil.copyfile(src, dest) + + _recursive_overwrite(uhd_source, dest) else: - temp_path = "tempdir" - - #Extracting contents of zip file - if os.path.exists(temp_path): - shutil.rmtree(temp_path) - os.mkdir(temp_path) - - images_zip = zipfile.ZipFile(filename) - images_zip.extractall(temp_path) + shutil.copytree(uhd_source, dest) - #Removing images currently in images_dir - if os.path.exists(images_dir): - try: - shutil.rmtree(images_dir) - except OSError,e: - print str(e) - print "Make sure you have write permissions in the images directory." - sys.exit(1) - - #Copying downloaded images into images_dir - shutil.copytree(os.path.join(temp_path, os.path.splitext(filename)[0], 'share', 'uhd', 'images'), images_dir) - - #Removing tempdir and zip file - shutil.rmtree(temp_path) - images_zip.close() - os.remove(filename) +def main(): + if os.environ.get("UHD_IMAGES_DIR") != None and os.environ.get("UHD_IMAGES_DIR") != "": + default_images_dir = os.environ.get("UHD_IMAGES_DIR") + print "UHD_IMAGES_DIR environment variable is set. Default install location: %s" % default_images_dir + else: + default_images_dir = _DEFAULT_INSTALL_PATH + + parser = OptionParser() + parser.add_option("-i", "--install-location", type="string", default=default_images_dir, + help="Set custom install location for images [default=%default]") + parser.add_option("--buffer-size", type="int", default=_DEFAULT_BUFFER_SIZE, + help="Set download buffer size [default=%default]") + parser.add_option("-u", "--url", type="string", default=_AUTOGEN_IMAGES_SOURCE, + help="Set images download location [default=%default]") + parser.add_option("-c", "--checksum", type="string", default=_AUTOGEN_IMAGES_CHECKSUM, + help="Validate images archive against this checksum (blank to skip) [default=%default]") + parser.add_option("-t", "--checksum-type", type="string", default=_IMAGES_CHECKSUM_TYPE, + help=("Select checksum hash function (options: %s) [default=%%default]" % (",".join(_checksum_fns.keys())))) + parser.add_option("-k", "--keep", action="store_true", default=False, + help="Do not clear images directory before extracting new files [default=%default]") + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="Enable verbose output [default=%default]") + + (options, args) = parser.parse_args() + + if options.buffer_size <= 0: + print "Invalid buffer size: %s" % (options.buffer_size) + return 1 + + checksum_fn = None + if options.checksum != "": + options.checksum_type = options.checksum_type.lower() + if not _checksum_fns.has_key(options.checksum_type): + print "Not a supported checksum function: %s" % (options.checksum_type) + return 1 + checksum_fn = _checksum_fns[options.checksum_type] + + url_parts = options.url.split("/") + if len(url_parts) <= 1 or url_parts[-1] == "": + print "Not a valid URL: %s" % (options.url) + return 1 + images_filename = url_parts[-1] + + images_dir = os.path.abspath(options.install_location) # This will use the current working directory if it's not absolute + + if options.verbose: + print "Requested install location: %s" % (options.install_location) + print "Images source: %s" % (options.url) + print "Images filename: %s" % (images_filename) + print "Images checksum: %s (%s)" % (options.checksum, _IMAGES_CHECKSUM_TYPE) + print "Final install location: %s" % (images_dir) + else: + print "Images destination: %s" % (images_dir) + + downloader = uhd_images_downloader() + + try: + (access, last_path) = downloader.check_directories(images_dir, print_progress=options.verbose) + if access: + with temporary_directory() as temp_dir: + if options.verbose: + print "Using temporary directory: %s" % (temp_dir) + + print "Downloading images from: %s" % options.url + + temp_images_dest = os.path.join(temp_dir, images_filename) + + print "Downloading images to: %s" % (temp_images_dest) + + (reported_size, downloaded_size) = downloader.download(images_url=options.url, filename=temp_images_dest, buffer_size=options.buffer_size, print_progress=True) + + if options.verbose: + print "Downloaded %d of %d bytes" % (downloaded_size, reported_size) + + (checksum_match, calculated_checksum) = downloader.validate_checksum(checksum_fn, temp_images_dest, options.checksum, print_progress=options.verbose) + + if options.verbose: + print "Calculated checksum: %s" % (calculated_checksum) + + if checksum_match: + if options.verbose: + if options.checksum == "": + print "Ignoring checksum" + else: + print "Checksum OK" + + try: + extract_path = downloader.extract_images_archive(temp_images_dest, print_progress=options.verbose) + + if options.verbose: + print "Image archive extracted to: %s" % (extract_path) + + downloader.install_images(extract_path, images_dir, options.keep, print_progress=options.verbose) + + print + print "Images successfully installed to: %s" % (images_dir) + except Exception, e: + print "Failed to install image archive: %s" % (e) + print "This is usually a permissions problem." + print "Please check your file system access rights and try again." + + if options.verbose: + traceback.print_exc() + else: + print "You can run this again with the '--verbose' flag to see more information" + print "If the problem persists, please email the output to: %s" % (_CONTACT) + else: + print "Checksum of downloaded file is not correct (not installing - see options to override)" + print "Expected: %s" % (options.checksum) + print "Calculated: %s" % (calculated_checksum) + print "Please try downloading again." + print "If the problem persists, please email the output to: %s" % (_CONTACT) + else: + print "You do not have sufficient permissions to write to: %s" % (last_path) + print "Are you root?" + except KeyboardInterrupt: + print + print "Cancelled at user request" + except Exception, e: + print "Downloader raised an unhandled exception: %s" % (e) + if options.verbose: + traceback.print_exc() + else: + print "You can run this again with the '--verbose' flag to see more information" + print "If the problem persists, please email the output to: %s" % (_CONTACT) + return 1 + + return 0 - os.chdir(images_dir) - print "\n\nImages successfully installed!" +if __name__ == "__main__": + sys.exit(main()) |