diff options
-rw-r--r-- | host/include/uhd/transport/vrt.hpp | 48 | ||||
-rwxr-xr-x | host/lib/transport/gen_vrt.py | 74 | ||||
-rw-r--r-- | host/lib/transport/vrt_packet_handler.hpp | 20 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 2 | ||||
-rw-r--r-- | host/test/vrt_test.cpp | 4 |
5 files changed, 112 insertions, 36 deletions
diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp index f2f42f9eb..fb6efc99c 100644 --- a/host/include/uhd/transport/vrt.hpp +++ b/host/include/uhd/transport/vrt.hpp @@ -29,7 +29,7 @@ namespace vrt{ static const size_t max_header_words32 = 5; //hdr+sid+tsi+tsf (no class id supported) /*! - * Pack a vrt header from metadata. + * Pack a vrt header from metadata (big endian format). * \param metadata the tx metadata with flags and timestamps * \param header_buff memory to write the packed vrt header * \param num_header_words32 number of words in the vrt header @@ -38,7 +38,7 @@ namespace vrt{ * \param packet_count the packet count sequence number * \param tick_rate ticks per second used in time conversion */ - UHD_API void pack( + UHD_API void pack_be( const tx_metadata_t &metadata, //input boost::uint32_t *header_buff, //output size_t &num_header_words32, //output @@ -49,7 +49,7 @@ namespace vrt{ ); /*! - * Unpack a vrt header to metadata. + * Unpack a vrt header to metadata (big endian format). * \param metadata the rx metadata with flags and timestamps * \param header_buff memory to read the packed vrt header * \param num_header_words32 number of words in the vrt header @@ -58,7 +58,47 @@ namespace vrt{ * \param packet_count the packet count sequence number * \param tick_rate ticks per second used in time conversion */ - UHD_API void unpack( + UHD_API void unpack_be( + rx_metadata_t &metadata, //output + const boost::uint32_t *header_buff, //input + size_t &num_header_words32, //output + size_t &num_payload_words32, //output + size_t num_packet_words32, //input + size_t &packet_count, //output + double tick_rate //input + ); + + /*! + * Pack a vrt header from metadata (little endian format). + * \param metadata the tx metadata with flags and timestamps + * \param header_buff memory to write the packed vrt header + * \param num_header_words32 number of words in the vrt header + * \param num_payload_words32 the length of the payload + * \param num_packet_words32 the length of the packet + * \param packet_count the packet count sequence number + * \param tick_rate ticks per second used in time conversion + */ + UHD_API void pack_le( + const tx_metadata_t &metadata, //input + boost::uint32_t *header_buff, //output + size_t &num_header_words32, //output + size_t num_payload_words32, //input + size_t &num_packet_words32, //output + size_t packet_count, //input + double tick_rate //input + ); + + /*! + * Unpack a vrt header to metadata (little endian format). + * \param metadata the rx metadata with flags and timestamps + * \param header_buff memory to read the packed vrt header + * \param num_header_words32 number of words in the vrt header + * \param num_payload_words32 the length of the payload + * \param num_packet_words32 the length of the packet + * \param packet_count the packet count sequence number + * \param tick_rate ticks per second used in time conversion + */ + UHD_API void unpack_le( rx_metadata_t &metadata, //output const boost::uint32_t *header_buff, //input size_t &num_header_words32, //output diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py index c34ffb198..1417240ab 100755 --- a/host/lib/transport/gen_vrt.py +++ b/host/lib/transport/gen_vrt.py @@ -27,28 +27,42 @@ The generated code infers jump tables to speed-up the parsing time. TMPL_TEXT = """ #import time - -######################################################################## -## setup predicates -######################################################################## -#set $sid_p = 0b00001 -#set $cid_p = 0b00010 -#set $tsi_p = 0b00100 -#set $tsf_p = 0b01000 -#set $tlr_p = 0b10000 - /*********************************************************************** * This file was generated by $file on $time.strftime("%c") **********************************************************************/ \#include <uhd/transport/vrt.hpp> -\#include <boost/asio.hpp> //endianness conversion +\#include <uhd/utils/byteswap.hpp> \#include <stdexcept> +//define the endian macros to convert integers +\#ifdef HAVE_BIG_ENDIAN + \#define BE_MACRO(x) (x) + \#define LE_MACRO(x) uhd::byteswap(x) +\#else + \#define BE_MACRO(x) uhd::byteswap(x) + \#define LE_MACRO(x) (x) +\#endif + +#set $XE_MACRO = "BE_MACRO" + using namespace uhd; using namespace uhd::transport; -void vrt::pack( +######################################################################## +#def gen_code($XE_MACRO, $suffix) +######################################################################## + +######################################################################## +## setup predicates +######################################################################## +#set $sid_p = 0b00001 +#set $cid_p = 0b00010 +#set $tsi_p = 0b00100 +#set $tsf_p = 0b01000 +#set $tlr_p = 0b10000 + +void vrt::pack_$(suffix)( const tx_metadata_t &metadata, //input boost::uint32_t *header_buff, //output size_t &num_header_words32, //output @@ -70,29 +84,29 @@ void vrt::pack( #set $flags = 0 ########## Stream ID ########## #if $pred & $sid_p - header_buff[$num_header_words] = htonl(metadata.stream_id); + header_buff[$num_header_words] = $(XE_MACRO)(metadata.stream_id); #set $num_header_words += 1 #set $flags |= (0x1 << 28); #end if ########## Class ID ########## #if $pred & $cid_p - header_buff[$num_header_words] = htonl(0); + header_buff[$num_header_words] = 0; #set $num_header_words += 1 - header_buff[$num_header_words] = htonl(0); + header_buff[$num_header_words] = 0; #set $num_header_words += 1 #set $flags |= (0x1 << 27); #end if ########## Integer Time ########## #if $pred & $tsi_p - header_buff[$num_header_words] = htonl(metadata.time_spec.secs); + header_buff[$num_header_words] = $(XE_MACRO)(metadata.time_spec.secs); #set $num_header_words += 1 #set $flags |= (0x3 << 22); #end if ########## Fractional Time ########## #if $pred & $tsf_p - header_buff[$num_header_words] = htonl(0); + header_buff[$num_header_words] = 0; #set $num_header_words += 1 - header_buff[$num_header_words] = htonl(metadata.time_spec.get_ticks(tick_rate)); + header_buff[$num_header_words] = $(XE_MACRO)(metadata.time_spec.get_ticks(tick_rate)); #set $num_header_words += 1 #set $flags |= (0x1 << 20); #end if @@ -116,13 +130,13 @@ void vrt::pack( if (metadata.end_of_burst) vrt_hdr_flags |= $hex(0x1 << 24); //fill in complete header word - header_buff[0] = htonl(vrt_hdr_flags | + header_buff[0] = $(XE_MACRO)(vrt_hdr_flags | ((packet_count & 0xf) << 16) | (num_packet_words32 & 0xffff) ); } -void vrt::unpack( +void vrt::unpack_$(suffix)( rx_metadata_t &metadata, //output const boost::uint32_t *header_buff, //input size_t &num_header_words32, //output @@ -135,7 +149,7 @@ void vrt::unpack( metadata = rx_metadata_t(); //extract vrt header - boost::uint32_t vrt_hdr_word = ntohl(header_buff[0]); + boost::uint32_t vrt_hdr_word = $(XE_MACRO)(header_buff[0]); size_t packet_words32 = vrt_hdr_word & 0xffff; packet_count = (vrt_hdr_word >> 16) & 0xf; @@ -160,7 +174,7 @@ void vrt::unpack( ########## Stream ID ########## #if $pred & $sid_p metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[$num_header_words]); + metadata.stream_id = $(XE_MACRO)(header_buff[$num_header_words]); #set $num_header_words += 1 #end if ########## Class ID ########## @@ -172,7 +186,7 @@ void vrt::unpack( #if $pred & $tsi_p metadata.has_time_spec = true; #set $set_has_time_spec = True - metadata.time_spec.secs = ntohl(header_buff[$num_header_words]); + metadata.time_spec.secs = $(XE_MACRO)(header_buff[$num_header_words]); #set $num_header_words += 1 #end if ########## Fractional Time ########## @@ -182,7 +196,7 @@ void vrt::unpack( #set $set_has_time_spec = True #end if #set $num_header_words += 1 - metadata.time_spec.set_ticks(ntohl(header_buff[$num_header_words]), tick_rate); + metadata.time_spec.set_ticks($(XE_MACRO)(header_buff[$num_header_words]), tick_rate); #set $num_header_words += 1 #end if ########## Trailer ########## @@ -198,13 +212,19 @@ void vrt::unpack( #end for } } -""" -import sys +######################################################################## +#end def +######################################################################## + +$gen_code("BE_MACRO", "be") +$gen_code("LE_MACRO", "le") +""" -from Cheetah.Template import Template def parse_tmpl(_tmpl_text, **kwargs): + from Cheetah.Template import Template return str(Template(_tmpl_text, kwargs)) if __name__ == '__main__': + import sys open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=__file__)) diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index d6b863040..8dfc7b3d0 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -66,10 +66,12 @@ namespace vrt_packet_handler{ * Unpack a received vrt header and set the copy buffer. * - helper function for vrt_packet_handler::_recv1 ******************************************************************/ + template<typename vrt_unpacker_type> static UHD_INLINE void _recv1_helper( recv_state &state, uhd::rx_metadata_t &metadata, double tick_rate, + vrt_unpacker_type vrt_unpacker, size_t vrt_header_offset_words32 ){ size_t num_packet_words32 = state.managed_buff->size()/sizeof(boost::uint32_t); @@ -79,7 +81,7 @@ namespace vrt_packet_handler{ } const boost::uint32_t *vrt_hdr = state.managed_buff->cast<const boost::uint32_t *>() + vrt_header_offset_words32; size_t num_header_words32_out, num_payload_words32_out, packet_count_out; - uhd::transport::vrt::unpack( + vrt_unpacker( metadata, //output vrt_hdr, //input num_header_words32_out, //output @@ -106,6 +108,7 @@ namespace vrt_packet_handler{ * Recv data, unpack a vrt header, and copy-convert the data. * - helper function for vrt_packet_handler::recv ******************************************************************/ + template<typename vrt_unpacker_type> static UHD_INLINE size_t _recv1( recv_state &state, void *recv_mem, @@ -114,6 +117,7 @@ namespace vrt_packet_handler{ const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, double tick_rate, + vrt_unpacker_type vrt_unpacker, const get_recv_buff_t &get_recv_buff, //use these two params to handle a layer above vrt size_t vrt_header_offset_words32, @@ -127,7 +131,7 @@ namespace vrt_packet_handler{ recv_cb(state.managed_buff); //callback before vrt unpack try{ _recv1_helper( - state, metadata, tick_rate, vrt_header_offset_words32 + state, metadata, tick_rate, vrt_unpacker, vrt_header_offset_words32 ); }catch(const std::exception &e){ std::cerr << "Error (recv): " << e.what() << std::endl; @@ -164,6 +168,7 @@ namespace vrt_packet_handler{ /******************************************************************* * Recv vrt packets and copy convert the samples into the buffer. ******************************************************************/ + template<typename vrt_unpacker_type> static UHD_INLINE size_t recv( recv_state &state, const boost::asio::mutable_buffer &buff, @@ -172,6 +177,7 @@ namespace vrt_packet_handler{ const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, double tick_rate, + vrt_unpacker_type vrt_unpacker, const get_recv_buff_t &get_recv_buff, //use these two params to handle a layer above vrt size_t vrt_header_offset_words32 = 0, @@ -192,6 +198,7 @@ namespace vrt_packet_handler{ metadata, io_type, otw_type, tick_rate, + vrt_unpacker, get_recv_buff, vrt_header_offset_words32, recv_cb @@ -211,6 +218,7 @@ namespace vrt_packet_handler{ (accum_num_samps == 0)? metadata : tmp_md, //only the first metadata gets kept io_type, otw_type, tick_rate, + vrt_unpacker, get_recv_buff, vrt_header_offset_words32, recv_cb @@ -249,6 +257,7 @@ namespace vrt_packet_handler{ * Pack a vrt header, copy-convert the data, and send it. * - helper function for vrt_packet_handler::send ******************************************************************/ + template<typename vrt_packer_type> static UHD_INLINE void _send1( send_state &state, const void *send_mem, @@ -257,6 +266,7 @@ namespace vrt_packet_handler{ const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, double tick_rate, + vrt_packer_type vrt_packer, const get_send_buff_t &get_send_buff, size_t vrt_header_offset_words32, const send_cb_t& send_cb @@ -269,7 +279,7 @@ namespace vrt_packet_handler{ size_t packet_count = state.next_packet_seq++; //pack metadata into a vrt header - uhd::transport::vrt::pack( + vrt_packer( metadata, //input tx_mem, //output num_header_words32, //output @@ -295,6 +305,7 @@ namespace vrt_packet_handler{ /******************************************************************* * Send vrt packets and copy convert the samples into the buffer. ******************************************************************/ + template<typename vrt_packer_type> static UHD_INLINE size_t send( send_state &state, const boost::asio::const_buffer &buff, @@ -303,6 +314,7 @@ namespace vrt_packet_handler{ const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, double tick_rate, + vrt_packer_type vrt_packer, const get_send_buff_t &get_send_buff, size_t max_samples_per_packet, //use these two params to handle a layer above vrt @@ -324,6 +336,7 @@ namespace vrt_packet_handler{ metadata, io_type, otw_type, tick_rate, + vrt_packer, get_send_buff, vrt_header_offset_words32, send_cb @@ -358,6 +371,7 @@ namespace vrt_packet_handler{ md, io_type, otw_type, tick_rate, + vrt_packer, get_send_buff, vrt_header_offset_words32, send_cb diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 1c7113197..6cb2a735b 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -139,6 +139,7 @@ size_t usrp2_impl::send( buff, metadata, send_mode, //buffer to empty and samples metadata io_type, _tx_otw_type, //input and output types to convert get_master_clock_freq(), //master clock tick rate + uhd::transport::vrt::pack_be, boost::bind(&zero_copy_if::get_send_buff, _data_transport), get_max_send_samps_per_packet() ); @@ -158,6 +159,7 @@ size_t usrp2_impl::recv( buff, metadata, recv_mode, //buffer to fill and samples metadata io_type, _rx_otw_type, //input and output types to convert get_master_clock_freq(), //master clock tick rate + uhd::transport::vrt::unpack_be, boost::bind(&usrp2_impl::io_impl::get_recv_buff, _io_impl) ); } diff --git a/host/test/vrt_test.cpp b/host/test/vrt_test.cpp index 939a61eb4..3e596164c 100644 --- a/host/test/vrt_test.cpp +++ b/host/test/vrt_test.cpp @@ -30,7 +30,7 @@ static void pack_and_unpack( size_t num_packet_words32; //pack metadata into a vrt header - vrt::pack( + vrt::pack_be( metadata, //input header_buff, //output num_header_words32, //output @@ -46,7 +46,7 @@ static void pack_and_unpack( size_t packet_count_out; //unpack the vrt header back into metadata - vrt::unpack( + vrt::unpack_be( metadata_out, //output header_buff, //input num_header_words32_out, //output |