diff options
| author | Josh Blum <josh@joshknows.com> | 2010-07-19 10:57:39 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2010-07-19 10:57:39 -0700 | 
| commit | ef9a395414acc203cc02e551e1790277cd0ef1f9 (patch) | |
| tree | 1a6cc02ca18cb30bf1f4f253f3550743d7d43ea9 | |
| parent | 8a7a824848f0a6276c0dc209bbd3ceeeb1eb7bd5 (diff) | |
| download | uhd-ef9a395414acc203cc02e551e1790277cd0ef1f9.tar.gz uhd-ef9a395414acc203cc02e551e1790277cd0ef1f9.tar.bz2 uhd-ef9a395414acc203cc02e551e1790277cd0ef1f9.zip | |
usrp2: add a timeout to udp control and make it large for usrp2 control transactions
| -rw-r--r-- | host/include/uhd/transport/udp_simple.hpp | 3 | ||||
| -rw-r--r-- | host/lib/transport/udp_simple.cpp | 21 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 14 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 5 | 
4 files changed, 30 insertions, 13 deletions
| diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp index 98dca02f0..c84393ecf 100644 --- a/host/include/uhd/transport/udp_simple.hpp +++ b/host/include/uhd/transport/udp_simple.hpp @@ -73,9 +73,10 @@ public:       * Receive into the provided buffer.       * Blocks until data is received or a timeout occurs.       * \param buff a mutable buffer to receive into +     * \param timeout_ms the timeout in milliseconds       * \return the number of bytes received or zero on timeout       */ -    virtual size_t recv(const boost::asio::mutable_buffer &buff) = 0; +    virtual size_t recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms) = 0;  };  }} //namespace diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index f339127ad..89750f99d 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -34,12 +34,13 @@ using namespace uhd::transport;   * This is okay bacause this is the slow-path implementation.   *   * \param socket the asio socket + * \param timeout_ms the timeout in milliseconds   */  static void reasonable_recv_timeout( -    boost::asio::ip::udp::socket &socket +    boost::asio::ip::udp::socket &socket, size_t timeout_ms  ){      boost::asio::deadline_timer timer(socket.get_io_service()); -    timer.expires_from_now(boost::posix_time::milliseconds(100)); +    timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms));      while (not (socket.available() or timer.expires_from_now().is_negative())){          boost::this_thread::sleep(boost::posix_time::milliseconds(1));      } @@ -55,8 +56,8 @@ public:      ~udp_connected_impl(void);      //send/recv -    size_t send(const boost::asio::const_buffer &buff); -    size_t recv(const boost::asio::mutable_buffer &buff); +    size_t send(const boost::asio::const_buffer &); +    size_t recv(const boost::asio::mutable_buffer &, size_t);  private:      boost::asio::ip::udp::socket   *_socket; @@ -85,8 +86,8 @@ size_t udp_connected_impl::send(const boost::asio::const_buffer &buff){      return _socket->send(boost::asio::buffer(buff));  } -size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff){ -    reasonable_recv_timeout(*_socket); +size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){ +    reasonable_recv_timeout(*_socket, timeout_ms);      if (not _socket->available()) return 0;      return _socket->receive(boost::asio::buffer(buff));  } @@ -101,8 +102,8 @@ public:      ~udp_broadcast_impl(void);      //send/recv -    size_t send(const boost::asio::const_buffer &buff); -    size_t recv(const boost::asio::mutable_buffer &buff); +    size_t send(const boost::asio::const_buffer &); +    size_t recv(const boost::asio::mutable_buffer &, size_t);  private:      boost::asio::ip::udp::socket   *_socket; @@ -136,8 +137,8 @@ size_t udp_broadcast_impl::send(const boost::asio::const_buffer &buff){      return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint);  } -size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff){ -    reasonable_recv_timeout(*_socket); +size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){ +    reasonable_recv_timeout(*_socket, timeout_ms);      if (not _socket->available()) return 0;      boost::asio::ip::udp::endpoint sender_endpoint;      return _socket->receive_from(boost::asio::buffer(buff), sender_endpoint); diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index eaaa722ac..a21157d76 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -28,6 +28,18 @@  using namespace uhd;  using namespace uhd::transport; +/*! + * FIXME: large timeout, ethernet pause frames... + * + * Use a large timeout to work-around the fact that + * flow-control may throttle outgoing control packets + * due to its use of ethernet pause frames. + * + * This will be fixed when host-based flow control is implemented, + * along with larger incoming send buffers using the on-board SRAM. + */ +static const size_t CONTROL_TIMEOUT_MS = 3000; //3 seconds +  class usrp2_iface_impl : public usrp2_iface{  public:  /*********************************************************************** @@ -164,7 +176,7 @@ public:          boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv          const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem);          while(true){ -            size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem)); +            size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CONTROL_TIMEOUT_MS);              if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_PROTO_VERSION){                  throw std::runtime_error(str(                      boost::format("Expected protocol version %d, but got %d\n" diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 02f53bc69..2c314c085 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -35,6 +35,9 @@ using namespace uhd::usrp;  using namespace uhd::transport;  namespace asio = boost::asio; +//! wait this long for a control response when discovering devices +static const size_t DISCOVERY_TIMEOUT_MS = 100; +  /***********************************************************************   * Helper Functions   **********************************************************************/ @@ -102,7 +105,7 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){      boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv      const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem);      while(true){ -        size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem)); +        size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem), DISCOVERY_TIMEOUT_MS);          //std::cout << len << "\n";          if (len > offsetof(usrp2_ctrl_data_t, data)){              //handle the received data | 
