summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-10-05 10:30:28 -0700
committerJosh Blum <josh@joshknows.com>2010-10-05 10:30:28 -0700
commit0cd5375b5c8a928f112a963d9c9c2556bafed108 (patch)
treef3a10162878cab2f576dc58cc1d6ae7be22eb715
parent50ff7e4d3bf4e196b4c054821f67f8d1bff5203b (diff)
downloaduhd-0cd5375b5c8a928f112a963d9c9c2556bafed108.tar.gz
uhd-0cd5375b5c8a928f112a963d9c9c2556bafed108.tar.bz2
uhd-0cd5375b5c8a928f112a963d9c9c2556bafed108.zip
uhd: replaced frame params for the zero copy interfaces with a device address
the device address gives a key, value pair of infinite optional capabilities added a cast option to the device address to cast string to type T added call to the zero_copy_if to get send and recv frame sizes changed the usrp2 impl to calculate recv/send spp from the data transport
-rw-r--r--host/include/uhd/transport/udp_zero_copy.hpp7
-rw-r--r--host/include/uhd/transport/usb_control.hpp2
-rw-r--r--host/include/uhd/transport/usb_zero_copy.hpp17
-rw-r--r--host/include/uhd/transport/zero_copy.hpp26
-rw-r--r--host/include/uhd/types/device_addr.hpp20
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp67
-rw-r--r--host/lib/transport/udp_zero_copy_asio.cpp35
-rw-r--r--host/lib/transport/usb_dummy_impl.cpp4
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp48
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp4
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp40
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp75
13 files changed, 162 insertions, 191 deletions
diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp
index 818709973..bbba97b21 100644
--- a/host/include/uhd/transport/udp_zero_copy.hpp
+++ b/host/include/uhd/transport/udp_zero_copy.hpp
@@ -20,6 +20,7 @@
#include <uhd/config.hpp>
#include <uhd/transport/zero_copy.hpp>
+#include <uhd/types/device_addr.hpp>
#include <boost/shared_ptr.hpp>
namespace uhd{ namespace transport{
@@ -50,14 +51,12 @@ public:
*
* \param addr a string representing the destination address
* \param port a string representing the destination port
- * \param recv_buff_size size in bytes for the recv buffer, 0 for automatic
- * \param send_buff_size size in bytes for the send buffer, 0 for automatic
+ * \param hints optional parameters to pass to the underlying transport
*/
static sptr make(
const std::string &addr,
const std::string &port,
- size_t recv_buff_size = 0,
- size_t send_buff_size = 0
+ const device_addr_t &hints = device_addr_t()
);
};
diff --git a/host/include/uhd/transport/usb_control.hpp b/host/include/uhd/transport/usb_control.hpp
index f9829c3ec..e6c32f78e 100644
--- a/host/include/uhd/transport/usb_control.hpp
+++ b/host/include/uhd/transport/usb_control.hpp
@@ -18,7 +18,7 @@
#ifndef INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP
#define INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP
-#include "usb_device_handle.hpp"
+#include <uhd/transport/usb_device_handle.hpp>
namespace uhd { namespace transport {
diff --git a/host/include/uhd/transport/usb_zero_copy.hpp b/host/include/uhd/transport/usb_zero_copy.hpp
index 61bf380ba..b39171fba 100644
--- a/host/include/uhd/transport/usb_zero_copy.hpp
+++ b/host/include/uhd/transport/usb_zero_copy.hpp
@@ -18,8 +18,9 @@
#ifndef INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP
#define INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP
-#include "usb_device_handle.hpp"
+#include <uhd/transport/usb_device_handle.hpp>
#include <uhd/transport/zero_copy.hpp>
+#include <uhd/types/device_addr.hpp>
namespace uhd { namespace transport {
@@ -47,19 +48,13 @@ public:
* \param handle a device handle that uniquely identifying the device
* \param recv_endpoint an integer specifiying an IN endpoint number
* \param send_endpoint an integer specifiying an OUT endpoint number
- * \param recv_xfer_size the number of bytes for each receive transfer
- * \param recv_num_xfers the number of simultaneous receive transfers
- * \param send_xfer_size the number of bytes for each send transfer
- * \param send_num_xfers the number of simultaneous send transfers
+ * \param hints optional parameters to pass to the underlying transport
*/
static sptr make(
usb_device_handle::sptr handle,
- unsigned int recv_endpoint,
- unsigned int send_endpoint,
- size_t recv_xfer_size = 0,
- size_t recv_num_xfers = 0,
- size_t send_xfer_size = 0,
- size_t send_num_xfers = 0
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints = device_addr_t()
);
};
diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp
index 9dd16280c..7d8fb4b83 100644
--- a/host/include/uhd/transport/zero_copy.hpp
+++ b/host/include/uhd/transport/zero_copy.hpp
@@ -155,15 +155,20 @@ namespace uhd{ namespace transport{
virtual managed_recv_buffer::sptr get_recv_buff(double timeout = 0.1) = 0;
/*!
- * Get the maximum number of receive frames:
- * The maximum number of valid managed recv buffers,
- * or the maximum number of frames in the ring buffer,
- * depending upon the underlying implementation.
+ * Get the number of receive frames:
+ * The number of simultaneous receive buffers in use.
* \return number of frames
*/
virtual size_t get_num_recv_frames(void) const = 0;
/*!
+ * Get the size of a receive frame:
+ * The maximum capacity of a single receive buffer.
+ * \return frame size in bytes
+ */
+ virtual size_t get_recv_frame_size(void) const = 0;
+
+ /*!
* Get a new send buffer from this transport object.
* \param timeout the timeout to get the buffer in seconds
* \return a managed buffer, or null sptr on timeout/error
@@ -171,14 +176,19 @@ namespace uhd{ namespace transport{
virtual managed_send_buffer::sptr get_send_buff(double timeout = 0.1) = 0;
/*!
- * Get the maximum number of send frames:
- * The maximum number of valid managed send buffers,
- * or the maximum number of frames in the ring buffer,
- * depending upon the underlying implementation.
+ * Get the number of send frames:
+ * The number of simultaneous send buffers in use.
* \return number of frames
*/
virtual size_t get_num_send_frames(void) const = 0;
+ /*!
+ * Get the size of a send frame:
+ * The maximum capacity of a single send buffer.
+ * \return frame size in bytes
+ */
+ virtual size_t get_send_frame_size(void) const = 0;
+
};
}} //namespace
diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp
index e359d9467..eb3394230 100644
--- a/host/include/uhd/types/device_addr.hpp
+++ b/host/include/uhd/types/device_addr.hpp
@@ -20,6 +20,8 @@
#include <uhd/config.hpp>
#include <uhd/types/dict.hpp>
+#include <boost/lexical_cast.hpp>
+#include <stdexcept>
#include <vector>
#include <string>
@@ -62,6 +64,24 @@ namespace uhd{
* \return a string with delimiter markup
*/
std::string to_string(void) const;
+
+ /*!
+ * Lexically cast a parameter to the specified type,
+ * or use the default value if the key is not found.
+ * \param key the key as one of the address parameters
+ * \param def the value to use when key is not present
+ * \return the casted value as type T or the default
+ * \throw error when the parameter cannot be casted
+ */
+ template <typename T> T cast(const std::string &key, const T &def) const{
+ if (not this->has_key(key)) return def;
+ try{
+ return boost::lexical_cast<T>((*this)[key]);
+ }
+ catch(const boost::bad_lexical_cast &){
+ throw std::runtime_error("cannot cast " + key + " = " + (*this)[key]);
+ }
+ }
};
//handy typedef for a vector of device addresses
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 819874483..df6db1eb9 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -26,6 +26,7 @@
#include <vector>
#include <iostream>
+using namespace uhd;
using namespace uhd::transport;
static const double CLEANUP_TIMEOUT = 0.2; //seconds
@@ -284,16 +285,19 @@ public:
libusb_zero_copy_impl(
libusb::device_handle::sptr handle,
- unsigned int recv_endpoint, unsigned int send_endpoint,
- size_t recv_xfer_size, size_t recv_num_xfers,
- size_t send_xfer_size, size_t send_num_xfers
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints
);
managed_recv_buffer::sptr get_recv_buff(double);
managed_send_buffer::sptr get_send_buff(double);
- size_t get_num_recv_frames(void) const { return _recv_num_frames; }
- size_t get_num_send_frames(void) const { return _send_num_frames; }
+ size_t get_num_recv_frames(void) const { return _num_recv_frames; }
+ size_t get_num_send_frames(void) const { return _num_send_frames; }
+
+ size_t get_recv_frame_size(void) const { return _recv_frame_size; }
+ size_t get_send_frame_size(void) const { return _send_frame_size; }
private:
void release(libusb_transfer *lut){
@@ -311,8 +315,8 @@ private:
}
libusb::device_handle::sptr _handle;
- size_t _recv_xfer_size, _send_xfer_size;
- size_t _recv_num_frames, _send_num_frames;
+ const size_t _recv_frame_size, _num_recv_frames;
+ const size_t _send_frame_size, _num_send_frames;
usb_endpoint::sptr _recv_ep, _send_ep;
};
@@ -323,24 +327,16 @@ private:
*/
libusb_zero_copy_impl::libusb_zero_copy_impl(
libusb::device_handle::sptr handle,
- unsigned int recv_endpoint, unsigned int send_endpoint,
- size_t recv_xfer_size, size_t recv_num_xfers,
- size_t send_xfer_size, size_t send_num_xfers
-){
- _handle = handle;
-
- //if the sizes are left at 0 (automatic) -> use the defaults
- if (recv_xfer_size == 0) recv_xfer_size = DEFAULT_XFER_SIZE;
- if (recv_num_xfers == 0) recv_num_xfers = DEFAULT_NUM_XFERS;
- if (send_xfer_size == 0) send_xfer_size = DEFAULT_XFER_SIZE;
- if (send_num_xfers == 0) send_num_xfers = DEFAULT_NUM_XFERS;
-
- //store the num xfers for the num frames count
- _recv_xfer_size = recv_xfer_size;
- _recv_num_frames = recv_num_xfers;
- _send_xfer_size = send_xfer_size;
- _send_num_frames = send_num_xfers;
-
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints
+):
+ _handle(handle),
+ _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", DEFAULT_XFER_SIZE))),
+ _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_XFERS))),
+ _send_frame_size(size_t(hints.cast<double>("send_frame_size", DEFAULT_XFER_SIZE))),
+ _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_XFERS)))
+{
_handle->claim_interface(2 /*in interface*/);
_handle->claim_interface(1 /*out interface*/);
@@ -348,16 +344,16 @@ libusb_zero_copy_impl::libusb_zero_copy_impl(
_handle, // libusb device_handle
recv_endpoint, // USB endpoint number
true, // IN endpoint
- recv_xfer_size, // buffer size per transfer
- recv_num_xfers // number of libusb transfers
+ this->get_recv_frame_size(), // buffer size per transfer
+ this->get_num_recv_frames() // number of libusb transfers
));
_send_ep = usb_endpoint::sptr(new usb_endpoint(
_handle, // libusb device_handle
send_endpoint, // USB endpoint number
false, // OUT endpoint
- send_xfer_size, // buffer size per transfer
- send_num_xfers // number of libusb transfers
+ this->get_send_frame_size(), // buffer size per transfer
+ this->get_num_send_frames() // number of libusb transfers
));
}
@@ -394,7 +390,7 @@ managed_send_buffer::sptr libusb_zero_copy_impl::get_send_buff(double timeout){
}
else {
return managed_send_buffer::make_safe(
- boost::asio::mutable_buffer(lut->buffer, _send_xfer_size),
+ boost::asio::mutable_buffer(lut->buffer, this->get_send_frame_size()),
boost::bind(&libusb_zero_copy_impl::commit, shared_from_this(), lut, _1)
);
}
@@ -405,17 +401,14 @@ managed_send_buffer::sptr libusb_zero_copy_impl::get_send_buff(double timeout){
**********************************************************************/
usb_zero_copy::sptr usb_zero_copy::make(
usb_device_handle::sptr handle,
- unsigned int recv_endpoint, unsigned int send_endpoint,
- size_t recv_xfer_size, size_t recv_num_xfers,
- size_t send_xfer_size, size_t send_num_xfers
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints
){
libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle(
boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()
));
return sptr(new libusb_zero_copy_impl(
- dev_handle,
- recv_endpoint, send_endpoint,
- recv_xfer_size, recv_num_xfers,
- send_xfer_size, send_num_xfers
+ dev_handle, recv_endpoint, send_endpoint, hints
));
}
diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp
index e9d91fe45..ada282e07 100644
--- a/host/lib/transport/udp_zero_copy_asio.cpp
+++ b/host/lib/transport/udp_zero_copy_asio.cpp
@@ -44,7 +44,7 @@ static const size_t MIN_RECV_SOCK_BUFF_SIZE = size_t(4 * 25e6 * 0.5);
static const size_t MIN_SEND_SOCK_BUFF_SIZE = size_t(10e3);
//the number of async frames to allocate for each send and recv
-static const size_t DEFAULT_NUM_ASYNC_FRAMES = 32;
+static const size_t DEFAULT_NUM_FRAMES = 32;
//a single concurrent thread for io_service seems to be the fastest
static const size_t CONCURRENCY_HINT = 1;
@@ -61,14 +61,15 @@ public:
typedef boost::shared_ptr<udp_zero_copy_asio_impl> sptr;
udp_zero_copy_asio_impl(
- const std::string &addr, const std::string &port,
- size_t recv_frame_size, size_t num_recv_frames,
- size_t send_frame_size, size_t num_send_frames
+ const std::string &addr,
+ const std::string &port,
+ const device_addr_t &hints
):
- _io_service(CONCURRENCY_HINT),
- _work(new asio::io_service::work(_io_service)),
- _recv_frame_size(recv_frame_size), _num_recv_frames(num_recv_frames),
- _send_frame_size(send_frame_size), _num_send_frames(num_send_frames)
+ _io_service(hints.cast<size_t>("concurrency_hint", CONCURRENCY_HINT)),
+ _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", udp_simple::mtu))),
+ _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_FRAMES))),
+ _send_frame_size(size_t(hints.cast<double>("send_frame_size", udp_simple::mtu))),
+ _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_FRAMES)))
{
//std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl;
@@ -99,6 +100,7 @@ public:
}
//spawn the service threads that will run the io service
+ _work = new asio::io_service::work(_io_service); //new work to delete later
for (size_t i = 0; i < CONCURRENCY_HINT; i++) _thread_group.create_thread(
boost::bind(&udp_zero_copy_asio_impl::service, this)
);
@@ -141,6 +143,7 @@ public:
}
size_t get_num_recv_frames(void) const {return _num_recv_frames;}
+ size_t get_recv_frame_size(void) const {return _recv_frame_size;}
//! pop an empty send buffer off of the fifo and bind with the commit callback
managed_send_buffer::sptr get_send_buff(double timeout){
@@ -159,6 +162,7 @@ public:
}
size_t get_num_send_frames(void) const {return _num_send_frames;}
+ size_t get_send_frame_size(void) const {return _send_frame_size;}
private:
void service(void){
@@ -260,14 +264,15 @@ template<typename Opt> static void resize_buff_helper(
udp_zero_copy::sptr udp_zero_copy::make(
const std::string &addr,
const std::string &port,
- size_t recv_buff_size,
- size_t send_buff_size
+ const device_addr_t &hints
){
- udp_zero_copy_asio_impl::sptr udp_trans(new udp_zero_copy_asio_impl(
- addr, port,
- udp_simple::mtu, DEFAULT_NUM_ASYNC_FRAMES, //recv
- udp_simple::mtu, DEFAULT_NUM_ASYNC_FRAMES //send
- ));
+ udp_zero_copy_asio_impl::sptr udp_trans(
+ new udp_zero_copy_asio_impl(addr, port, hints)
+ );
+
+ //extract buffer size hints from the device addr
+ size_t recv_buff_size = size_t(hints.cast<double>("recv_buff_size", 0.0));
+ size_t send_buff_size = size_t(hints.cast<double>("send_buff_size", 0.0));
//call the helper to resize send and recv buffers
resize_buff_helper<asio::socket_base::receive_buffer_size>(udp_trans, recv_buff_size, "recv");
diff --git a/host/lib/transport/usb_dummy_impl.cpp b/host/lib/transport/usb_dummy_impl.cpp
index 518342aba..8a9772e7f 100644
--- a/host/lib/transport/usb_dummy_impl.cpp
+++ b/host/lib/transport/usb_dummy_impl.cpp
@@ -20,6 +20,7 @@
#include <uhd/transport/usb_zero_copy.hpp>
#include <uhd/utils/exception.hpp>
+using namespace uhd;
using namespace uhd::transport;
std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(boost::uint16_t, boost::uint16_t){
@@ -32,8 +33,7 @@ usb_control::sptr usb_control::make(usb_device_handle::sptr){
usb_zero_copy::sptr usb_zero_copy::make(
usb_device_handle::sptr,
- unsigned int, unsigned int,
- size_t, size_t, size_t, size_t
+ size_t, size_t, const device_addr_t &
){
throw std::runtime_error("no usb support -> usb_zero_copy::make not implemented");
}
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 6ebd6bb09..276ca86f6 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -106,17 +106,8 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
/***********************************************************************
* Make
**********************************************************************/
-template<typename output_type> static output_type cast_from_dev_addr(
- const device_addr_t &device_addr,
- const std::string &key,
- output_type def_val
-){
- return (device_addr.has_key(key))?
- boost::lexical_cast<output_type>(device_addr[key]) : def_val;
-}
+static device::sptr usrp1_make(const device_addr_t &device_addr){
-static device::sptr usrp1_make(const device_addr_t &device_addr)
-{
//extract the FPGA path for the USRP1
std::string usrp1_fpga_image = find_image_path(
device_addr.has_key("fpga")? device_addr["fpga"] : "usrp1_fpga.rbf"
@@ -127,29 +118,26 @@ static device::sptr usrp1_make(const device_addr_t &device_addr)
std::vector<usb_device_handle::sptr> device_list =
usb_device_handle::get_device_list(USRP1_VENDOR_ID, USRP1_PRODUCT_ID);
- //create data and control transports
- usb_zero_copy::sptr data_transport;
- usrp_ctrl::sptr usrp_ctrl;
-
-
- BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
- if (handle->get_serial() == device_addr["serial"]) {
- usb_control::sptr ctrl_transport = usb_control::make(handle);
- usrp_ctrl = usrp_ctrl::make(ctrl_transport);
- usrp_ctrl->usrp_load_fpga(usrp1_fpga_image);
-
- data_transport = usb_zero_copy::make(
- handle, // identifier
- 6, // IN endpoint
- 2, // OUT endpoint
- size_t(cast_from_dev_addr<double>(device_addr, "recv_xfer_size", 0)),
- size_t(cast_from_dev_addr<double>(device_addr, "recv_num_xfers", 0)),
- size_t(cast_from_dev_addr<double>(device_addr, "send_xfer_size", 0)),
- size_t(cast_from_dev_addr<double>(device_addr, "send_num_xfers", 0))
- );
+ //locate the matching handle in the device list
+ usb_device_handle::sptr handle;
+ BOOST_FOREACH(usb_device_handle::sptr dev_handle, device_list) {
+ if (dev_handle->get_serial() == device_addr["serial"]){
+ handle = dev_handle;
break;
}
}
+ UHD_ASSERT_THROW(handle.get() != NULL); //better be found
+
+ //create control objects and a data transport
+ usb_control::sptr ctrl_transport = usb_control::make(handle);
+ usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);
+ usrp_ctrl->usrp_load_fpga(usrp1_fpga_image);
+ usb_zero_copy::sptr data_transport = usb_zero_copy::make(
+ handle, // identifier
+ 6, // IN endpoint
+ 2, // OUT endpoint
+ device_addr // param hints
+ );
//create the usrp1 implementation guts
return device::sptr(new usrp1_impl(data_transport, usrp_ctrl));
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 33cec3cbc..07eda08c3 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -206,7 +206,7 @@ size_t usrp2_impl::send(
_io_impl->packet_handler_send_state, //last state of the send handler
buffs, num_samps, //buffer to fill
metadata, send_mode, //samples metadata
- io_type, _io_helper.get_tx_otw_type(), //input and output types to convert
+ io_type, _tx_otw_type, //input and output types to convert
_mboards.front()->get_master_clock_freq(), //master clock tick rate
uhd::transport::vrt::if_hdr_pack_be,
boost::bind(&get_send_buffs, _data_transports, _1, timeout),
@@ -226,7 +226,7 @@ size_t usrp2_impl::recv(
_io_impl->packet_handler_recv_state, //last state of the recv handler
buffs, num_samps, //buffer to fill
metadata, recv_mode, //samples metadata
- io_type, _io_helper.get_rx_otw_type(), //input and output types to convert
+ io_type, _rx_otw_type, //input and output types to convert
_mboards.front()->get_master_clock_freq(), //master clock tick rate
uhd::transport::vrt::if_hdr_unpack_be,
boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout)
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 0b9f8ee83..a0e6adfad 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -38,10 +38,10 @@ using namespace uhd::usrp;
usrp2_mboard_impl::usrp2_mboard_impl(
size_t index,
transport::udp_simple::sptr ctrl_transport,
- const usrp2_io_helper &io_helper
+ size_t recv_frame_size
):
_index(index),
- _io_helper(io_helper)
+ _recv_frame_size(recv_frame_size)
{
//make a new interface for usrp2 stuff
_iface = usrp2_iface::make(ctrl_transport);
@@ -75,7 +75,7 @@ usrp2_mboard_impl::usrp2_mboard_impl(
this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
//init the rx control registers
- _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _io_helper.get_max_recv_samps_per_packet());
+ _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _recv_frame_size);
_iface->poke32(U2_REG_RX_CTRL_NCHANNELS, 1);
_iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1); //reset
_iface->poke32(U2_REG_RX_CTRL_VRT_HEADER, 0
@@ -178,7 +178,7 @@ void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){
void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
_iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, dsp_type1::calc_stream_cmd_word(
- stream_cmd, _io_helper.get_max_recv_samps_per_packet()
+ stream_cmd, _recv_frame_size
));
_iface->poke32(U2_REG_RX_CTRL_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs()));
_iface->poke32(U2_REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(get_master_clock_freq()));
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 568c87a22..a680708ad 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -124,26 +124,7 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){
/***********************************************************************
* Make
**********************************************************************/
-template <typename out_type, typename in_type>
-out_type lexical_cast(const in_type &in){
- try{
- return boost::lexical_cast<out_type>(in);
- }catch(...){
- throw std::runtime_error(str(boost::format(
- "failed to cast \"%s\" to type \"%s\""
- ) % boost::lexical_cast<std::string>(in) % typeid(out_type).name()));
- }
-}
-
static device::sptr usrp2_make(const device_addr_t &device_addr){
- //extract the receive and send buffer sizes
- size_t recv_buff_size = 0, send_buff_size= 0 ;
- if (device_addr.has_key("recv_buff_size")){
- recv_buff_size = size_t(lexical_cast<double>(device_addr["recv_buff_size"]));
- }
- if (device_addr.has_key("send_buff_size")){
- send_buff_size = size_t(lexical_cast<double>(device_addr["send_buff_size"]));
- }
//create a ctrl and data transport for each address
std::vector<udp_simple::sptr> ctrl_transports;
@@ -154,8 +135,7 @@ static device::sptr usrp2_make(const device_addr_t &device_addr){
addr, num2str(USRP2_UDP_CTRL_PORT)
));
data_transports.push_back(udp_zero_copy::make(
- addr, num2str(USRP2_UDP_DATA_PORT),
- recv_buff_size, send_buff_size
+ addr, num2str(USRP2_UDP_DATA_PORT), device_addr
));
}
@@ -178,11 +158,23 @@ usrp2_impl::usrp2_impl(
):
_data_transports(data_transports)
{
+ //setup rx otw type
+ _rx_otw_type.width = 16;
+ _rx_otw_type.shift = 0;
+ _rx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ //setup tx otw type
+ _tx_otw_type.width = 16;
+ _tx_otw_type.shift = 0;
+ _tx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ //!!!!! set the otw type here before continuing, its used below
+
//create a new mboard handler for each control transport
for(size_t i = 0; i < ctrl_transports.size(); i++){
- _mboards.push_back(usrp2_mboard_impl::sptr(
- new usrp2_mboard_impl(i, ctrl_transports[i], _io_helper)
- ));
+ _mboards.push_back(usrp2_mboard_impl::sptr(new usrp2_mboard_impl(
+ i, ctrl_transports[i], this->get_max_recv_samps_per_packet()
+ )));
//use an empty name when there is only one mboard
std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast<std::string>(i) : "";
_mboard_dict[name] = _mboards.back();
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index e8763b284..e12c4d6d4 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -72,54 +72,6 @@ private:
};
/*!
- * The io helper class encapculates the max packet sizes and otw types.
- * The otw types are read-only for now, this will be reimplemented
- * when it becomes possible to change the otw type in the usrp2.
- */
-class usrp2_io_helper{
-public:
- usrp2_io_helper(void){
- //setup rx otw type
- _rx_otw_type.width = 16;
- _rx_otw_type.shift = 0;
- _rx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
-
- //setup tx otw type
- _tx_otw_type.width = 16;
- _tx_otw_type.shift = 0;
- _tx_otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
- }
-
- inline size_t get_max_send_samps_per_packet(void) const{
- return _max_tx_bytes_per_packet/_tx_otw_type.get_sample_size();
- }
-
- inline size_t get_max_recv_samps_per_packet(void) const{
- return _max_rx_bytes_per_packet/_rx_otw_type.get_sample_size();
- }
-
- inline const uhd::otw_type_t &get_rx_otw_type(void) const{
- return _rx_otw_type;
- }
-
- inline const uhd::otw_type_t &get_tx_otw_type(void) const{
- return _tx_otw_type;
- }
-
-private:
- uhd::otw_type_t _rx_otw_type, _tx_otw_type;
- static const size_t _max_rx_bytes_per_packet = uhd::transport::udp_simple::mtu
- - uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
- - sizeof(uhd::transport::vrt::if_packet_info_t().tlr) //forced to have trailer
- + sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
- ;
- static const size_t _max_tx_bytes_per_packet = uhd::transport::udp_simple::mtu
- - uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
- + sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
- ;
-};
-
-/*!
* USRP2 mboard implementation guts:
* The implementation details are encapsulated here.
* Handles properties on the mboard, dboard, dsps...
@@ -129,7 +81,11 @@ public:
typedef boost::shared_ptr<usrp2_mboard_impl> sptr;
//structors
- usrp2_mboard_impl(size_t index, uhd::transport::udp_simple::sptr, const usrp2_io_helper &);
+ usrp2_mboard_impl(
+ size_t index,
+ uhd::transport::udp_simple::sptr,
+ size_t recv_frame_size
+ );
~usrp2_mboard_impl(void);
inline double get_master_clock_freq(void){
@@ -139,7 +95,7 @@ public:
private:
size_t _index;
int _rev_hi, _rev_lo;
- const usrp2_io_helper &_io_helper;
+ const size_t _recv_frame_size;
//properties for this mboard
void get(const wax::obj &, wax::obj &);
@@ -229,7 +185,8 @@ public:
//the io interface
size_t get_max_send_samps_per_packet(void) const{
- return _io_helper.get_max_send_samps_per_packet();
+ const size_t bytes_per_packet = _data_transports.front()->get_send_frame_size() - _max_tx_header_bytes;
+ return bytes_per_packet/_tx_otw_type.get_sample_size();
}
size_t send(
const std::vector<const void *> &, size_t,
@@ -237,7 +194,8 @@ public:
uhd::device::send_mode_t, double
);
size_t get_max_recv_samps_per_packet(void) const{
- return _io_helper.get_max_recv_samps_per_packet();
+ const size_t bytes_per_packet = _data_transports.front()->get_recv_frame_size() - _max_rx_header_bytes;
+ return bytes_per_packet/_rx_otw_type.get_sample_size();
}
size_t recv(
const std::vector<void *> &, size_t,
@@ -257,9 +215,20 @@ private:
//io impl methods and members
std::vector<uhd::transport::udp_zero_copy::sptr> _data_transports;
- const usrp2_io_helper _io_helper;
UHD_PIMPL_DECL(io_impl) _io_impl;
void io_init(void);
+
+ //over-the-wire structs and constants
+ uhd::otw_type_t _rx_otw_type, _tx_otw_type;
+ static const size_t _max_rx_header_bytes = 0
+ + uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
+ + sizeof(uhd::transport::vrt::if_packet_info_t().tlr) //forced to have trailer
+ - sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
+ ;
+ static const size_t _max_tx_header_bytes = 0
+ + uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
+ - sizeof(uhd::transport::vrt::if_packet_info_t().cid) //no class id ever used
+ ;
};
#endif /* INCLUDED_USRP2_IMPL_HPP */