From be430761fb7e526e80b67d70e3cf488c6dd02495 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Jul 2010 19:32:47 -0700 Subject: usrp2: use the actual pointer in bind so the sptr is not copied --- host/lib/usrp/usrp2/io_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host/lib/usrp/usrp2') diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index c96528694..0853f48be 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -135,7 +135,7 @@ void usrp2_impl::io_init(void){ for (size_t i = 0; i < _data_transports.size(); i++){ _io_impl->recv_pirate_crew.create_thread(boost::bind( &usrp2_impl::io_impl::recv_pirate_loop, - _io_impl, _data_transports.at(i), + _io_impl.get(), _data_transports.at(i), _mboards.at(i), i )); } @@ -195,6 +195,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, _1) + boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1) ); } -- cgit v1.2.3 From c72bc56ba6d5b0457f03967a8f8d8e5602fdf14d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Jul 2010 23:48:09 -0700 Subject: usrp2: moved common defined for udp mtu and implemented change. The uhp mtu is now defined in uhd_simple.hpp. The fw common code does not need to know this information. Fixed a calculation bug in the usrp2 impl code for max samples. --- host/include/uhd/transport/udp_simple.hpp | 3 +++ host/lib/transport/udp_zero_copy_asio.cpp | 10 +++++----- host/lib/usrp/usrp2/fw_common.h | 8 -------- host/lib/usrp/usrp2/usrp2_iface.cpp | 9 +++++---- host/lib/usrp/usrp2/usrp2_impl.cpp | 4 ++-- host/lib/usrp/usrp2/usrp2_impl.hpp | 16 ++++++++-------- 6 files changed, 23 insertions(+), 27 deletions(-) (limited to 'host/lib/usrp/usrp2') diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp index 793ec4fd7..98dca02f0 100644 --- a/host/include/uhd/transport/udp_simple.hpp +++ b/host/include/uhd/transport/udp_simple.hpp @@ -29,6 +29,9 @@ class UHD_API udp_simple : boost::noncopyable{ public: typedef boost::shared_ptr sptr; + //! The maximum number of bytes per udp packet. + static const size_t mtu = 1500 - 20 - 8; //default ipv4 mtu - ipv4 header - udp header + /*! * Make a new connected udp transport: * This transport is for sending and receiving diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 7f9292d24..86ea275c1 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -16,6 +16,7 @@ // #include +#include //mtu #include #include #include @@ -29,7 +30,6 @@ using namespace uhd::transport; **********************************************************************/ //enough buffering for half a second of samples at full rate on usrp2 static const size_t MIN_SOCK_BUFF_SIZE = size_t(sizeof(boost::uint32_t) * 25e6 * 0.5); -static const size_t MAX_DGRAM_SIZE = 1500; //assume max size on send and recv static const double RECV_TIMEOUT = 0.1; //100 ms /*********************************************************************** @@ -51,8 +51,8 @@ public: const std::string &addr, const std::string &port ): - phony_zero_copy_recv_if(MAX_DGRAM_SIZE), - phony_zero_copy_send_if(MAX_DGRAM_SIZE) + phony_zero_copy_recv_if(udp_simple::mtu), + phony_zero_copy_send_if(udp_simple::mtu) { //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; @@ -93,11 +93,11 @@ public: //This way, the transport caller will have an idea about how much buffering to create. size_t get_num_recv_frames(void) const{ - return this->get_buff_size()/MAX_DGRAM_SIZE; + return this->get_buff_size()/udp_simple::mtu; } size_t get_num_send_frames(void) const{ - return this->get_buff_size()/MAX_DGRAM_SIZE; + return this->get_buff_size()/udp_simple::mtu; } private: diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 4c66aa41e..f1761c5a6 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -32,10 +32,6 @@ extern "C" { #define _SINS_ #endif -// define limits on bytes per udp packet -#define USRP2_MTU_BYTES 1500 -#define USRP2_UDP_BYTES ((USRP2_MTU_BYTES) - (2 + 14 + 20 + 8)) //size of headers (pad, eth, ip, udp) - //defines the protocol version in this shared header //increment this value when the protocol is changed #define USRP2_PROTO_VERSION 5 @@ -43,10 +39,6 @@ extern "C" { //used to differentiate control packets over data port #define USRP2_INVALID_VRT_HEADER 0 -// size of the vrt header and trailer to the host -#define USRP2_HOST_RX_VRT_HEADER_WORDS32 5 -#define USRP2_HOST_RX_VRT_TRAILER_WORDS32 1 //FIXME fpga sets wrong header size when no trailer present - // udp ports for the usrp2 communication // Dynamic and/or private ports: 49152-65535 #define USRP2_UDP_CTRL_PORT 49152 diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 8552edd1f..eaaa722ac 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -26,13 +26,14 @@ #include using namespace uhd; +using namespace uhd::transport; class usrp2_iface_impl : public usrp2_iface{ public: /*********************************************************************** * Structors **********************************************************************/ - usrp2_iface_impl(transport::udp_simple::sptr ctrl_transport){ + usrp2_iface_impl(udp_simple::sptr ctrl_transport){ _ctrl_transport = ctrl_transport; } @@ -160,7 +161,7 @@ public: _ctrl_transport->send(boost::asio::buffer(&out_copy, sizeof(usrp2_ctrl_data_t))); //loop until we get the packet or timeout - boost::uint8_t usrp2_ctrl_data_in_mem[USRP2_UDP_BYTES]; //allocate max bytes for recv + 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(usrp2_ctrl_data_in_mem); while(true){ size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem)); @@ -182,7 +183,7 @@ public: private: //this lovely lady makes it all possible - transport::udp_simple::sptr _ctrl_transport; + udp_simple::sptr _ctrl_transport; //used in send/recv boost::mutex _ctrl_mutex; @@ -222,6 +223,6 @@ private: /*********************************************************************** * Public make function for usrp2 interface **********************************************************************/ -usrp2_iface::sptr usrp2_iface::make(transport::udp_simple::sptr ctrl_transport){ +usrp2_iface::sptr usrp2_iface::make(udp_simple::sptr ctrl_transport){ return usrp2_iface::sptr(new usrp2_iface_impl(ctrl_transport)); } diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 3402c26b1..9d1ac991f 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -99,8 +99,8 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){ udp_transport->send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out))); //loop and recieve until the timeout - boost::uint8_t usrp2_ctrl_data_in_mem[USRP2_UDP_BYTES]; //allocate max bytes for recv - usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast(usrp2_ctrl_data_in_mem); + 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(usrp2_ctrl_data_in_mem); while(true){ size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem)); //std::cout << len << "\n"; diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 42630a3e4..186516447 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -32,6 +32,7 @@ #include #include #include +#include //mtu #include #include @@ -106,15 +107,14 @@ public: private: uhd::otw_type_t _rx_otw_type, _tx_otw_type; - static const size_t _max_rx_bytes_per_packet = - USRP2_UDP_BYTES - - USRP2_HOST_RX_VRT_HEADER_WORDS32*sizeof(boost::uint32_t) - - USRP2_HOST_RX_VRT_TRAILER_WORDS32*sizeof(boost::uint32_t) + 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 = - USRP2_UDP_BYTES - - 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 + 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 ; }; -- cgit v1.2.3 From ab617b492ed2dc47a814f8c01f60f7639ba633e7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 8 Jul 2010 00:36:47 -0700 Subject: usrp2: clean up fw common with nicer looking macro for stdint namespace --- host/lib/usrp/usrp2/fw_common.h | 45 +++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'host/lib/usrp/usrp2') diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index f1761c5a6..fd728e393 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -24,12 +24,12 @@ * Therefore, this header may only contain valid C code. */ #ifdef __cplusplus -#include -#define _SINS_ boost:://stdint namespace when in c++ + #include + #define __stdint(type) boost::type extern "C" { #else -#include -#define _SINS_ + #include + #define __stdint(type) type #endif //defines the protocol version in this shared header @@ -82,34 +82,35 @@ typedef enum{ } usrp2_clk_edge_t; typedef struct{ - _SINS_ uint32_t proto_ver; - _SINS_ uint32_t id; - _SINS_ uint32_t seq; + __stdint(uint32_t) proto_ver; + __stdint(uint32_t) id; + __stdint(uint32_t) seq; union{ - _SINS_ uint32_t ip_addr; + __stdint(uint32_t) ip_addr; struct { - _SINS_ uint8_t dev; - _SINS_ uint8_t miso_edge; - _SINS_ uint8_t mosi_edge; - _SINS_ uint8_t readback; - _SINS_ uint32_t data; - _SINS_ uint8_t num_bits; + __stdint(uint8_t) dev; + __stdint(uint8_t) miso_edge; + __stdint(uint8_t) mosi_edge; + __stdint(uint8_t) readback; + __stdint(uint32_t) data; + __stdint(uint8_t) num_bits; } spi_args; struct { - _SINS_ uint8_t addr; - _SINS_ uint8_t bytes; - _SINS_ uint8_t data[20]; + __stdint(uint8_t) addr; + __stdint(uint8_t) bytes; + __stdint(uint8_t) data[20]; } i2c_args; struct { - _SINS_ uint32_t addr; - _SINS_ uint32_t data; - _SINS_ uint32_t addrhi; - _SINS_ uint32_t datahi; - _SINS_ uint8_t num_bytes; //1, 2, 4, 8 + __stdint(uint32_t) addr; + __stdint(uint32_t) data; + __stdint(uint32_t) addrhi; + __stdint(uint32_t) datahi; + __stdint(uint8_t) num_bytes; //1, 2, 4, 8 } poke_args; } data; } usrp2_ctrl_data_t; +#undef __stdint #ifdef __cplusplus } #endif -- cgit v1.2.3 From da9d47011e02f2b18fccda00dbea0b9d9c0dc704 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 8 Jul 2010 13:01:49 -0700 Subject: usrp2: added notes on multiple device network setup, improved warnings for buff size stuff --- host/docs/usrp2.rst | 25 ++++++++++++++++++++++--- host/lib/transport/udp_zero_copy_asio.cpp | 12 ++++++------ host/lib/usrp/usrp2/usrp2_impl.cpp | 15 +++++++++++++-- 3 files changed, 41 insertions(+), 11 deletions(-) (limited to 'host/lib/usrp/usrp2') diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index d3ae1dec7..76b27fd31 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -88,7 +88,7 @@ Setup the host interface The USRP2 communicates at the IP/UDP layer over the gigabit ethernet. The default IP address of the USRP2 is **192.168.10.2** You will need to configure the host's ethernet interface with a static IP address to enable communication. -An address of **192.168.10.1** is recommended. +An address of **192.168.10.1** and a subnet mask of **255.255.255.0** is recommended. **Note:** When using the UHD, if an IP address for the USRP2 is not specified, @@ -96,6 +96,26 @@ the software will use UDP broadcast packets to locate the USRP2. On some systems, the firewall will block UDP broadcast packets. It is recommended that you change or disable your firewall settings. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Multiple device configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +As described above, you will need one ethernet interface per USRP2. +Each ethernet interface should have its own subnet, +and the corresponding USRP2 device should be assigned an address in that subnet. +Example: + +**Configuration for USRP2 device 0:** + +* Ethernet interface IPv4 address: 192.168.10.1 +* Ethernet interface subnet mask: 255.255.255.0 +* USRP2 device IPv4 address: 192.168.10.2 + +**Configuration for USRP2 device 1:** + +* Ethernet interface IPv4 address: 192.168.20.1 +* Ethernet interface subnet mask: 255.255.255.0 +* USRP2 device IPv4 address: 192.168.20.2 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Change the USRP2's IP address ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +142,7 @@ Run the following commands: :: cd /share/uhd/utils - ./usrp2_recovery.py --ifc=eth0 --new-ip=192.168.10.3 + sudo ./usrp2_recovery.py --ifc=eth0 --new-ip=192.168.10.3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Debugging networking problems @@ -181,7 +201,6 @@ The device address string representation for 2 USRP2s with IPv4 addresses 192.16 addr=192.168.10.2 192.168.20.2 - ------------------------------------------------------------------------ Resize the send and receive buffers ------------------------------------------------------------------------ diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 86ea275c1..e3f3ef5bf 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -155,17 +155,17 @@ template static void resize_buff_helper( else std::cout << boost::format( "Current %s sock buff size: %d bytes" ) % name % actual_size << std::endl; + if (actual_size < target_size) std::cerr << boost::format( + "Warning:\n" + " The %s buffer is smaller than the requested size.\n" + " The minimum recommended buffer size is %d bytes.\n" + " See the USRP2 application notes on buffer resizing.\n" + ) % name % MIN_SOCK_BUFF_SIZE << std::endl; } //otherwise, ensure that the buffer is at least the minimum size else if (udp_trans->get_buff_size() < MIN_SOCK_BUFF_SIZE){ resize_buff_helper(udp_trans, MIN_SOCK_BUFF_SIZE, name); - if (udp_trans->get_buff_size() < MIN_SOCK_BUFF_SIZE){ - std::cerr << boost::format( - "Warning: the %s buffer size is smaller than the recommended size of %d bytes.\n" - " See the USRP2 application notes on buffer resizing." - ) % name % MIN_SOCK_BUFF_SIZE << std::endl; - } } } diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 9d1ac991f..02f53bc69 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -127,14 +127,25 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){ /*********************************************************************** * Make **********************************************************************/ +template +out_type lexical_cast(const in_type &in){ + try{ + return boost::lexical_cast(in); + }catch(...){ + throw std::runtime_error(str(boost::format( + "failed to cast \"%s\" to type \"%s\"" + ) % boost::lexical_cast(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(boost::lexical_cast(device_addr["recv_buff_size"])); + recv_buff_size = size_t(lexical_cast(device_addr["recv_buff_size"])); } if (device_addr.has_key("send_buff_size")){ - send_buff_size = size_t(boost::lexical_cast(device_addr["send_buff_size"])); + send_buff_size = size_t(lexical_cast(device_addr["send_buff_size"])); } //create a ctrl and data transport for each address -- cgit v1.2.3