summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/transport/vrt.hpp48
-rwxr-xr-xhost/lib/transport/gen_vrt.py74
-rw-r--r--host/lib/transport/vrt_packet_handler.hpp20
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp2
-rw-r--r--host/test/vrt_test.cpp4
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