aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/dboard/db_tvrx.cpp4
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp85
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp32
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.hpp7
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp36
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp6
-rw-r--r--host/lib/usrp/usrp_e/io_impl.cpp48
-rw-r--r--host/lib/usrp/usrp_e/usrp_e_impl.hpp6
-rw-r--r--host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp161
9 files changed, 173 insertions, 212 deletions
diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp
index 1cb74c5ae..41c52fbf5 100644
--- a/host/lib/usrp/dboard/db_tvrx.cpp
+++ b/host/lib/usrp/dboard/db_tvrx.cpp
@@ -58,7 +58,7 @@ static const bool tvrx_debug = false;
static const freq_range_t tvrx_freq_range(50e6, 860e6);
-static const std::string tvrx_antennas = std::string(""); //only got one
+static const prop_names_t tvrx_antennas = list_of(""); //only got one
static const uhd::dict<std::string, freq_range_t> tvrx_freq_ranges = map_list_of
("VHFLO", freq_range_t(50e6, 158e6))
@@ -436,7 +436,7 @@ void tvrx::rx_get(const wax::obj &key_, wax::obj &val){
return;
case SUBDEV_PROP_ANTENNA:
- val = std::string(tvrx_antennas);
+ val = std::string("");
return;
case SUBDEV_PROP_ANTENNA_NAMES:
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index aee760a83..676b1536a 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -34,35 +34,6 @@ using namespace uhd::transport;
namespace asio = boost::asio;
/***********************************************************************
- * Pseudo send buffer implementation
- **********************************************************************/
-class pseudo_managed_send_buffer : public managed_send_buffer{
-public:
-
- pseudo_managed_send_buffer(
- const boost::asio::mutable_buffer &buff,
- const boost::function<ssize_t(size_t)> &commit
- ):
- _buff(buff),
- _commit(commit)
- {
- /* NOP */
- }
-
- ssize_t commit(size_t num_bytes){
- return _commit(num_bytes);
- }
-
-private:
- const boost::asio::mutable_buffer &get(void) const{
- return _buff;
- }
-
- const boost::asio::mutable_buffer _buff;
- const boost::function<ssize_t(size_t)> _commit;
-};
-
-/***********************************************************************
* IO Implementation Details
**********************************************************************/
struct usrp1_impl::io_impl{
@@ -94,12 +65,13 @@ struct usrp1_impl::io_impl{
//all of this to ensure only full buffers are committed
managed_send_buffer::sptr send_buff;
size_t num_bytes_committed;
+ double send_timeout;
boost::uint8_t pseudo_buff[BYTES_PER_PACKET];
- ssize_t phony_commit_pseudo_buff(size_t num_bytes);
- ssize_t phony_commit_send_buff(size_t num_bytes);
- ssize_t commit_send_buff(void);
+ void phony_commit_pseudo_buff(size_t num_bytes);
+ void phony_commit_send_buff(size_t num_bytes);
+ void commit_send_buff(void);
void flush_send_buff(void);
- bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &);
+ bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &, double);
//helpers to get at the send buffer + offset
inline void *get_send_mem_ptr(void){
@@ -118,28 +90,25 @@ struct usrp1_impl::io_impl{
* The first loop iteration will fill the remainder of the send buffer.
* The second loop iteration will empty the pseudo buffer remainder.
*/
-ssize_t usrp1_impl::io_impl::phony_commit_pseudo_buff(size_t num_bytes){
+void usrp1_impl::io_impl::phony_commit_pseudo_buff(size_t num_bytes){
size_t bytes_to_copy = num_bytes, bytes_copied = 0;
while(bytes_to_copy){
size_t bytes_copied_here = std::min(bytes_to_copy, get_send_mem_size());
std::memcpy(get_send_mem_ptr(), pseudo_buff + bytes_copied, bytes_copied_here);
- ssize_t ret = phony_commit_send_buff(bytes_copied_here);
- if (ret < 0) return ret;
- bytes_to_copy -= ret;
- bytes_copied += ret;
+ phony_commit_send_buff(bytes_copied_here);
+ bytes_to_copy -= bytes_copied_here;
+ bytes_copied += bytes_copied_here;
}
- return bytes_copied;
}
/*!
* Accept a commit of num bytes to the send buffer.
* Conditionally commit the send buffer if full.
*/
-ssize_t usrp1_impl::io_impl::phony_commit_send_buff(size_t num_bytes){
+void usrp1_impl::io_impl::phony_commit_send_buff(size_t num_bytes){
num_bytes_committed += num_bytes;
- if (num_bytes_committed != send_buff->size()) return num_bytes;
- ssize_t ret = commit_send_buff();
- return (ret < 0)? ret : num_bytes;
+ if (num_bytes_committed != send_buff->size()) return;
+ commit_send_buff();
}
/*!
@@ -157,31 +126,31 @@ void usrp1_impl::io_impl::flush_send_buff(void){
* Perform an actual commit on the send buffer:
* Commit the contents of the send buffer and request a new buffer.
*/
-ssize_t usrp1_impl::io_impl::commit_send_buff(void){
- ssize_t ret = send_buff->commit(num_bytes_committed);
- send_buff = data_transport->get_send_buff();
+void usrp1_impl::io_impl::commit_send_buff(void){
+ send_buff->commit(num_bytes_committed);
+ send_buff = data_transport->get_send_buff(send_timeout);
num_bytes_committed = 0;
- return ret;
}
bool usrp1_impl::io_impl::get_send_buffs(
- vrt_packet_handler::managed_send_buffs_t &buffs
+ vrt_packet_handler::managed_send_buffs_t &buffs, double timeout
){
+ send_timeout = timeout;
UHD_ASSERT_THROW(buffs.size() == 1);
//not enough bytes free -> use the pseudo buffer
if (get_send_mem_size() < BYTES_PER_PACKET){
- buffs[0] = managed_send_buffer::sptr(new pseudo_managed_send_buffer(
+ buffs[0] = managed_send_buffer::make_safe(
boost::asio::buffer(pseudo_buff),
boost::bind(&usrp1_impl::io_impl::phony_commit_pseudo_buff, this, _1)
- ));
+ );
}
//otherwise use the send buffer offset by the bytes written
else{
- buffs[0] = managed_send_buffer::sptr(new pseudo_managed_send_buffer(
+ buffs[0] = managed_send_buffer::make_safe(
boost::asio::buffer(get_send_mem_ptr(), get_send_mem_size()),
boost::bind(&usrp1_impl::io_impl::phony_commit_send_buff, this, _1)
- ));
+ );
}
return buffs[0].get() != NULL;
@@ -216,7 +185,7 @@ static void usrp1_bs_vrt_packer(
size_t usrp1_impl::send(
const std::vector<const void *> &buffs, size_t num_samps,
const tx_metadata_t &metadata, const io_type_t &io_type,
- send_mode_t send_mode
+ send_mode_t send_mode, double timeout
){
size_t num_samps_sent = vrt_packet_handler::send(
_io_impl->packet_handler_send_state, //last state of the send handler
@@ -225,7 +194,7 @@ size_t usrp1_impl::send(
io_type, _tx_otw_type, //input and output types to convert
_clock_ctrl->get_master_clock_freq(), //master clock tick rate
&usrp1_bs_vrt_packer,
- boost::bind(&usrp1_impl::io_impl::get_send_buffs, _io_impl.get(), _1),
+ boost::bind(&usrp1_impl::io_impl::get_send_buffs, _io_impl.get(), _1, timeout),
get_max_send_samps_per_packet(),
0, //vrt header offset
_tx_subdev_spec.size() //num channels
@@ -272,18 +241,18 @@ static void usrp1_bs_vrt_unpacker(
}
static bool get_recv_buffs(
- zero_copy_if::sptr zc_if, size_t timeout_ms,
+ zero_copy_if::sptr zc_if, double timeout,
vrt_packet_handler::managed_recv_buffs_t &buffs
){
UHD_ASSERT_THROW(buffs.size() == 1);
- buffs[0] = zc_if->get_recv_buff(timeout_ms);
+ buffs[0] = zc_if->get_recv_buff(timeout);
return buffs[0].get() != NULL;
}
size_t usrp1_impl::recv(
const std::vector<void *> &buffs, size_t num_samps,
rx_metadata_t &metadata, const io_type_t &io_type,
- recv_mode_t recv_mode, size_t timeout_ms
+ recv_mode_t recv_mode, double timeout
){
size_t num_samps_recvd = vrt_packet_handler::recv(
_io_impl->packet_handler_recv_state, //last state of the recv handler
@@ -292,7 +261,7 @@ size_t usrp1_impl::recv(
io_type, _rx_otw_type, //input and output types to convert
_clock_ctrl->get_master_clock_freq(), //master clock tick rate
&usrp1_bs_vrt_unpacker,
- boost::bind(&get_recv_buffs, _data_transport, timeout_ms, _1),
+ boost::bind(&get_recv_buffs, _data_transport, timeout, _1),
&vrt_packet_handler::handle_overflow_nop,
0, //vrt header offset
_rx_subdev_spec.size() //num channels
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 793e3027d..6ebd6bb09 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -83,9 +83,7 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
//find the usrps and load firmware
BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
- usb_control::sptr ctrl_transport = usb_control::make(handle);
- usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);
- usrp_ctrl->usrp_load_firmware(usrp1_fw_image);
+ usrp_ctrl::make(usb_control::make(handle))->usrp_load_firmware(usrp1_fw_image);
}
//get descriptors again with serial number, but using the initialized VID/PID now since we have firmware
@@ -93,13 +91,13 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
pid = USRP1_PRODUCT_ID;
BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
- device_addr_t new_addr;
- new_addr["type"] = "usrp1";
- new_addr["serial"] = handle->get_serial();
- //this is a found usrp1 when a hint serial is not specified or it matches
- if (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]){
- usrp1_addrs.push_back(new_addr);
- }
+ device_addr_t new_addr;
+ new_addr["type"] = "usrp1";
+ new_addr["serial"] = handle->get_serial();
+ //this is a found usrp1 when a hint serial is not specified or it matches
+ if (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]){
+ usrp1_addrs.push_back(new_addr);
+ }
}
return usrp1_addrs;
@@ -109,12 +107,12 @@ 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
+ 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;
+ 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)
@@ -211,9 +209,9 @@ usrp1_impl::~usrp1_impl(void){
/* NOP */
}
-bool usrp1_impl::recv_async_msg(uhd::async_metadata_t &, size_t timeout_ms){
+bool usrp1_impl::recv_async_msg(uhd::async_metadata_t &, double timeout){
//dummy fill-in for the recv_async_msg
- boost::this_thread::sleep(boost::posix_time::milliseconds(timeout_ms));
+ boost::this_thread::sleep(boost::posix_time::microseconds(long(timeout*1e6)));
return false;
}
diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp
index 20ae3c02a..f2c464610 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.hpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.hpp
@@ -83,13 +83,12 @@ public:
size_t,
const uhd::tx_metadata_t &,
const uhd::io_type_t &,
- send_mode_t);
+ send_mode_t, double);
size_t recv(const std::vector<void *> &,
size_t, uhd::rx_metadata_t &,
const uhd::io_type_t &,
- recv_mode_t,
- size_t timeout);
+ recv_mode_t, double);
static const size_t BYTES_PER_PACKET = 512*4; //under the transfer size
@@ -101,7 +100,7 @@ public:
return BYTES_PER_PACKET/_rx_otw_type.get_sample_size()/_rx_subdev_spec.size();
}
- bool recv_async_msg(uhd::async_metadata_t &, size_t);
+ bool recv_async_msg(uhd::async_metadata_t &, double);
private:
/*!
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 3395f94e2..33cec3cbc 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -33,7 +33,6 @@ using namespace uhd::transport;
namespace asio = boost::asio;
static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET;
-static const double RECV_TIMEOUT_MS = 100;
/***********************************************************************
* io impl details (internal to this file)
@@ -59,9 +58,9 @@ struct usrp2_impl::io_impl{
recv_pirate_crew.join_all();
}
- bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, size_t timeout_ms){
+ bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, double timeout){
boost::this_thread::disable_interruption di; //disable because the wait can throw
- return recv_pirate_booty->pop_elems_with_timed_wait(buffs, boost::posix_time::milliseconds(timeout_ms));
+ return recv_pirate_booty->pop_elems_with_timed_wait(buffs, timeout);
}
//state management for the vrt packet handler code
@@ -91,7 +90,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(
size_t next_packet_seq = 0;
while(recv_pirate_crew_raiding){
- managed_recv_buffer::sptr buff = zc_if->get_recv_buff(RECV_TIMEOUT_MS);
+ managed_recv_buffer::sptr buff = zc_if->get_recv_buff();
if (not buff.get()) continue; //ignore timeout/error buffers
try{
@@ -151,7 +150,7 @@ void usrp2_impl::io_init(void){
std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
send_buff->commit(sizeof(data));
//drain the recv buffers (may have junk)
- while (data_transport->get_recv_buff(RECV_TIMEOUT_MS).get()){};
+ while (data_transport->get_recv_buff().get()){};
}
//the number of recv frames is the number for the first transport
@@ -169,22 +168,16 @@ void usrp2_impl::io_init(void){
_mboards.at(i), i
));
}
-
- std::cout << "RX samples per packet: " << get_max_recv_samps_per_packet() << std::endl;
- std::cout << "TX samples per packet: " << get_max_send_samps_per_packet() << std::endl;
- std::cout << "Recv pirate num frames: " << num_frames << std::endl;
}
/***********************************************************************
* Async Data
**********************************************************************/
bool usrp2_impl::recv_async_msg(
- async_metadata_t &async_metadata, size_t timeout_ms
+ async_metadata_t &async_metadata, double timeout
){
boost::this_thread::disable_interruption di; //disable because the wait can throw
- return _io_impl->async_msg_fifo->pop_with_timed_wait(
- async_metadata, boost::posix_time::milliseconds(timeout_ms)
- );
+ return _io_impl->async_msg_fifo->pop_with_timed_wait(async_metadata, timeout);
}
/***********************************************************************
@@ -192,19 +185,22 @@ bool usrp2_impl::recv_async_msg(
**********************************************************************/
static bool get_send_buffs(
const std::vector<udp_zero_copy::sptr> &trans,
- vrt_packet_handler::managed_send_buffs_t &buffs
+ vrt_packet_handler::managed_send_buffs_t &buffs,
+ double timeout
){
UHD_ASSERT_THROW(trans.size() == buffs.size());
+ bool good = true;
for (size_t i = 0; i < buffs.size(); i++){
- buffs[i] = trans[i]->get_send_buff();
+ buffs[i] = trans[i]->get_send_buff(timeout);
+ good = good and (buffs[i].get() != NULL);
}
- return true;
+ return good;
}
size_t usrp2_impl::send(
const std::vector<const void *> &buffs, size_t num_samps,
const tx_metadata_t &metadata, const io_type_t &io_type,
- send_mode_t send_mode
+ send_mode_t send_mode, double timeout
){
return vrt_packet_handler::send(
_io_impl->packet_handler_send_state, //last state of the send handler
@@ -213,7 +209,7 @@ size_t usrp2_impl::send(
io_type, _io_helper.get_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),
+ boost::bind(&get_send_buffs, _data_transports, _1, timeout),
get_max_send_samps_per_packet()
);
}
@@ -224,7 +220,7 @@ size_t usrp2_impl::send(
size_t usrp2_impl::recv(
const std::vector<void *> &buffs, size_t num_samps,
rx_metadata_t &metadata, const io_type_t &io_type,
- recv_mode_t recv_mode, size_t timeout_ms
+ recv_mode_t recv_mode, double timeout
){
return vrt_packet_handler::recv(
_io_impl->packet_handler_recv_state, //last state of the recv handler
@@ -233,6 +229,6 @@ size_t usrp2_impl::recv(
io_type, _io_helper.get_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_ms)
+ boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout)
);
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 157d17057..e8763b284 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -234,7 +234,7 @@ public:
size_t send(
const std::vector<const void *> &, size_t,
const uhd::tx_metadata_t &, const uhd::io_type_t &,
- uhd::device::send_mode_t
+ 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();
@@ -242,9 +242,9 @@ public:
size_t recv(
const std::vector<void *> &, size_t,
uhd::rx_metadata_t &, const uhd::io_type_t &,
- uhd::device::recv_mode_t, size_t
+ uhd::device::recv_mode_t, double
);
- bool recv_async_msg(uhd::async_metadata_t &, size_t);
+ bool recv_async_msg(uhd::async_metadata_t &, double);
private:
//device properties interface
diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp
index 0b5fa054b..1e577a4df 100644
--- a/host/lib/usrp/usrp_e/io_impl.cpp
+++ b/host/lib/usrp/usrp_e/io_impl.cpp
@@ -37,7 +37,7 @@ zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface);
**********************************************************************/
static const size_t tx_async_report_sid = 1;
static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET;
-static const double recv_timeout_ms = 100;
+static const bool recv_debug = true;
/***********************************************************************
* io impl details (internal to this file)
@@ -66,10 +66,10 @@ struct usrp_e_impl::io_impl{
recv_pirate_crew.join_all();
}
- bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, size_t timeout_ms){
+ bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, double timeout){
UHD_ASSERT_THROW(buffs.size() == 1);
boost::this_thread::disable_interruption di; //disable because the wait can throw
- return recv_pirate_booty->pop_with_timed_wait(buffs.front(), boost::posix_time::milliseconds(timeout_ms));
+ return recv_pirate_booty->pop_with_timed_wait(buffs.front(), timeout);
}
//a pirate's life is the life for me!
@@ -94,9 +94,17 @@ void usrp_e_impl::io_impl::recv_pirate_loop(
//size_t next_packet_seq = 0;
while(recv_pirate_crew_raiding){
- managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff(recv_timeout_ms);
+ managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff();
if (not buff.get()) continue; //ignore timeout/error buffers
+ if (recv_debug){
+ std::cout << "len " << buff->size() << std::endl;
+ for (size_t i = 0; i < 9; i++){
+ std::cout << boost::format(" 0x%08x") % buff->cast<const boost::uint32_t *>()[i] << std::endl;
+ }
+ std::cout << std::endl << std::endl;
+ }
+
try{
//extract the vrt header packet info
vrt::if_packet_info_t if_packet_info;
@@ -181,20 +189,18 @@ void usrp_e_impl::handle_overrun(size_t){
* Data Send
**********************************************************************/
bool get_send_buffs(
- zero_copy_if::sptr trans,
+ zero_copy_if::sptr trans, double timeout,
vrt_packet_handler::managed_send_buffs_t &buffs
){
UHD_ASSERT_THROW(buffs.size() == 1);
- buffs[0] = trans->get_send_buff();
+ buffs[0] = trans->get_send_buff(timeout);
return buffs[0].get() != NULL;
}
size_t usrp_e_impl::send(
- const std::vector<const void *> &buffs,
- size_t num_samps,
- const tx_metadata_t &metadata,
- const io_type_t &io_type,
- send_mode_t send_mode
+ const std::vector<const void *> &buffs, size_t num_samps,
+ const tx_metadata_t &metadata, const io_type_t &io_type,
+ send_mode_t send_mode, double timeout
){
otw_type_t send_otw_type;
send_otw_type.width = 16;
@@ -208,7 +214,7 @@ size_t usrp_e_impl::send(
io_type, send_otw_type, //input and output types to convert
MASTER_CLOCK_RATE, //master clock tick rate
uhd::transport::vrt::if_hdr_pack_le,
- boost::bind(&get_send_buffs, _io_impl->data_xport, _1),
+ boost::bind(&get_send_buffs, _io_impl->data_xport, timeout, _1),
get_max_send_samps_per_packet()
);
}
@@ -217,12 +223,9 @@ size_t usrp_e_impl::send(
* Data Recv
**********************************************************************/
size_t usrp_e_impl::recv(
- const std::vector<void *> &buffs,
- size_t num_samps,
- rx_metadata_t &metadata,
- const io_type_t &io_type,
- recv_mode_t recv_mode,
- size_t timeout_ms
+ const std::vector<void *> &buffs, size_t num_samps,
+ rx_metadata_t &metadata, const io_type_t &io_type,
+ recv_mode_t recv_mode, double timeout
){
otw_type_t recv_otw_type;
recv_otw_type.width = 16;
@@ -236,7 +239,7 @@ size_t usrp_e_impl::recv(
io_type, recv_otw_type, //input and output types to convert
MASTER_CLOCK_RATE, //master clock tick rate
uhd::transport::vrt::if_hdr_unpack_le,
- boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout_ms),
+ boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout),
boost::bind(&usrp_e_impl::handle_overrun, this, _1)
);
}
@@ -245,11 +248,8 @@ size_t usrp_e_impl::recv(
* Async Recv
**********************************************************************/
bool usrp_e_impl::recv_async_msg(
- async_metadata_t &async_metadata,
- size_t timeout_ms
+ async_metadata_t &async_metadata, double timeout
){
boost::this_thread::disable_interruption di; //disable because the wait can throw
- return _io_impl->async_msg_fifo->pop_with_timed_wait(
- async_metadata, boost::posix_time::milliseconds(timeout_ms)
- );
+ return _io_impl->async_msg_fifo->pop_with_timed_wait(async_metadata, timeout);
}
diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp
index 2457e27cc..49912050e 100644
--- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp
+++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp
@@ -82,9 +82,9 @@ public:
~usrp_e_impl(void);
//the io interface
- size_t send(const std::vector<const void *> &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t);
- size_t recv(const std::vector<void *> &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, size_t);
- bool recv_async_msg(uhd::async_metadata_t &, size_t);
+ size_t send(const std::vector<const void *> &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double);
+ size_t recv(const std::vector<void *> &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double);
+ bool recv_async_msg(uhd::async_metadata_t &, double);
size_t get_max_send_samps_per_packet(void) const{return 503;}
size_t get_max_recv_samps_per_packet(void) const{return 503;}
diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp
index 0910caa6f..e62205a3f 100644
--- a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp
+++ b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp
@@ -15,86 +15,27 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include "usrp_e_iface.hpp"
#include <uhd/transport/zero_copy.hpp>
#include <uhd/utils/assert.hpp>
#include <linux/usrp_e.h>
#include <sys/mman.h> //mmap
#include <unistd.h> //getpagesize
#include <poll.h> //poll
-#include <boost/cstdint.hpp>
-#include "usrp_e_iface.hpp"
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <iostream>
using namespace uhd;
using namespace uhd::transport;
-static const bool debug_verbose = false;
-
-/***********************************************************************
- * The managed receive buffer implementation
- **********************************************************************/
-class usrp_e_mmap_managed_recv_buffer : public managed_recv_buffer{
-public:
- usrp_e_mmap_managed_recv_buffer(
- const void *mem, size_t len, ring_buffer_info *info
- ):
- _buff(mem, len), _info(info)
- {
- /* NOP */
- }
-
- ~usrp_e_mmap_managed_recv_buffer(void){
- _info->flags = RB_KERNEL;
- }
-
-private:
- const boost::asio::const_buffer &get(void) const{
- return _buff;
- }
-
- const boost::asio::const_buffer _buff;
- ring_buffer_info *_info;
-};
-
-/***********************************************************************
- * The managed send buffer implementation
- **********************************************************************/
-class usrp_e_mmap_managed_send_buffer : public managed_send_buffer{
-public:
- usrp_e_mmap_managed_send_buffer(
- void *mem, size_t len, ring_buffer_info *info, int fd
- ):
- _buff(mem, len), _info(info), _fd(fd), _commited(false)
- {
- /* NOP */
- }
-
- ~usrp_e_mmap_managed_send_buffer(void){
- if (not _commited) this->commit(0);
- }
-
- ssize_t commit(size_t num_bytes){
- _commited = true;
- _info->len = num_bytes;
- _info->flags = RB_USER;
- ssize_t ret = ::write(_fd, NULL, 0);
- return (ret < 0)? ret : num_bytes;
- }
-
-private:
- const boost::asio::mutable_buffer &get(void) const{
- return _buff;
- }
-
- const boost::asio::mutable_buffer _buff;
- ring_buffer_info *_info;
- int _fd;
- bool _commited;
-};
+static const bool fp_verbose = true; //fast-path verbose
+static const bool sp_verbose = true; //slow-path verbose
/***********************************************************************
* The zero copy interface implementation
**********************************************************************/
-class usrp_e_mmap_zero_copy_impl : public zero_copy_if{
+class usrp_e_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this<usrp_e_mmap_zero_copy_impl> {
public:
usrp_e_mmap_zero_copy_impl(usrp_e_iface::sptr iface):
_fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0)
@@ -105,15 +46,26 @@ public:
_frame_size = page_size/2;
//calculate the memory size
- size_t map_size =
+ _map_size =
(_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size +
(_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size;
+ //print sizes summary
+ if (sp_verbose){
+ std::cout << "page_size: " << page_size << std::endl;
+ std::cout << "frame_size: " << _frame_size << std::endl;
+ std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl;
+ std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl;
+ std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl;
+ std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl;
+ std::cout << "map_size: " << _map_size << std::endl;
+ }
+
//call mmap to get the memory
- void *ring_buffer = mmap(
- NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0
+ _mapped_mem = ::mmap(
+ NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0
);
- UHD_ASSERT_THROW(ring_buffer != MAP_FAILED);
+ UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED);
//calculate the memory offsets for info and buffers
size_t recv_info_off = 0;
@@ -121,16 +73,31 @@ public:
size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size);
size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size);
+ //print offset summary
+ if (sp_verbose){
+ std::cout << "recv_info_off: " << recv_info_off << std::endl;
+ std::cout << "recv_buff_off: " << recv_buff_off << std::endl;
+ std::cout << "send_info_off: " << send_info_off << std::endl;
+ std::cout << "send_buff_off: " << send_buff_off << std::endl;
+ }
+
//set the internal pointers for info and buffers
typedef ring_buffer_info (*rbi_pta)[];
- boost::uint8_t *rb_ptr = reinterpret_cast<boost::uint8_t *>(ring_buffer);
+ char *rb_ptr = reinterpret_cast<char *>(_mapped_mem);
_recv_info = reinterpret_cast<rbi_pta>(rb_ptr + recv_info_off);
_recv_buff = rb_ptr + recv_buff_off;
_send_info = reinterpret_cast<rbi_pta>(rb_ptr + send_info_off);
_send_buff = rb_ptr + send_buff_off;
}
- managed_recv_buffer::sptr get_recv_buff(size_t timeout_ms){
+ ~usrp_e_mmap_zero_copy_impl(void){
+ if (sp_verbose) std::cout << "cleanup: munmap" << std::endl;
+ ::munmap(_mapped_mem, _map_size);
+ }
+
+ managed_recv_buffer::sptr get_recv_buff(double timeout){
+ if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl;
+
//grab pointers to the info and buffer
ring_buffer_info *info = (*_recv_info) + _recv_index;
void *mem = _recv_buff + _frame_size*_recv_index;
@@ -140,7 +107,8 @@ public:
pollfd pfd;
pfd.fd = _fd;
pfd.events = POLLIN;
- ssize_t poll_ret = poll(&pfd, 1, timeout_ms);
+ ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3));
+ if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl;
if (poll_ret <= 0) return managed_recv_buffer::sptr();
}
@@ -148,8 +116,10 @@ public:
if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0;
//return the managed buffer for this frame
- return managed_recv_buffer::sptr(
- new usrp_e_mmap_managed_recv_buffer(mem, info->len, info)
+ if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl;
+ return managed_recv_buffer::make_safe(
+ boost::asio::const_buffer(mem, info->len),
+ boost::bind(&usrp_e_mmap_zero_copy_impl::release, shared_from_this(), info)
);
}
@@ -157,7 +127,9 @@ public:
return _rb_size.num_rx_frames;
}
- managed_send_buffer::sptr get_send_buff(void){
+ managed_send_buffer::sptr get_send_buff(double timeout){
+ if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl;
+
//grab pointers to the info and buffer
ring_buffer_info *info = (*_send_info) + _send_index;
void *mem = _send_buff + _frame_size*_send_index;
@@ -167,7 +139,8 @@ public:
pollfd pfd;
pfd.fd = _fd;
pfd.events = POLLOUT;
- ssize_t poll_ret = poll(&pfd, 1, -1 /*forever*/);
+ ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3));
+ if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl;
if (poll_ret <= 0) return managed_send_buffer::sptr();
}
@@ -175,8 +148,10 @@ public:
if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0;
//return the managed buffer for this frame
- return managed_send_buffer::sptr(
- new usrp_e_mmap_managed_send_buffer(mem, _frame_size, info, _fd)
+ if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl;
+ return managed_send_buffer::make_safe(
+ boost::asio::mutable_buffer(mem, _frame_size),
+ boost::bind(&usrp_e_mmap_zero_copy_impl::commit, shared_from_this(), info, _1)
);
}
@@ -185,11 +160,35 @@ public:
}
private:
+
+ void release(ring_buffer_info *info){
+ if (fp_verbose) std::cout << "recv buff: release" << std::endl;
+ info->flags = RB_KERNEL;
+ }
+
+ void commit(ring_buffer_info *info, size_t len){
+ if (fp_verbose) std::cout << "send buff: commit " << len << std::endl;
+ info->len = len;
+ info->flags = RB_USER;
+ if (::write(_fd, NULL, 0) < 0){
+ std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl;
+ }
+ }
+
int _fd;
+
+ //the mapped memory itself
+ void *_mapped_mem;
+
+ //mapped memory sizes
usrp_e_ring_buffer_size_t _rb_size;
- size_t _frame_size;
+ size_t _frame_size, _map_size;
+
+ //pointers to sections in the mapped memory
ring_buffer_info (*_recv_info)[], (*_send_info)[];
- boost::uint8_t *_recv_buff, *_send_buff;
+ char *_recv_buff, *_send_buff;
+
+ //indexes into sub-sections of mapped memory
size_t _recv_index, _send_index;
};