summaryrefslogtreecommitdiff
path: root/gr-uhd
diff options
context:
space:
mode:
authorPiotr Krysik <ptrkrysik@gmail.com>2018-11-16 08:35:38 +0000
committerMartin Braun <martin.braun@ettus.com>2018-12-11 14:22:22 -0800
commit94fddb6371264c79969c0448c19fdb637d6ffc31 (patch)
tree7120f6a8412fcbc0561742411fcf56244a473f3a /gr-uhd
parent3359d67e02158199d24756155fb58ab43b7b66ef (diff)
uhd: added asynchronous messages handling to the sink
UHD asynchronous messages are needed in order to obtain information about issues happening on Tx side (Underflows, Sequence Errors, Time Errors). This change adds handling of these messages to the usrp sink by adding async_event_loop() function executed in a separate thread (_async_event_thread) where these messages are: - received from the USRP, - transformed into PMT messages, - sent to the new "async_msgs" message output port. On the top level the output PMT messages are (message_type, content) pairs: - message_type is always "uhd_async_msg", - content is a dictionary with key names taken from uhd::async_metadata_t. - there is no 'has_time_spec' as in PMT it's not needed. There just won't be 'time_spec' in the PMT message when 'has_time_spec' is false. - there is no 'user_payload' - but it can be easily added in the future as pmt blob. Example message from the 'async_msgs' output is below: (uhd_async_msg (channel . 0) (time_spec 4 . 0.0608192) (event_code burst_ack)) Reviewed-By: Martin Braun <martin.braun@ettus.com>
Diffstat (limited to 'gr-uhd')
-rw-r--r--gr-uhd/grc/gen_uhd_usrp_blocks.py13
-rw-r--r--gr-uhd/lib/usrp_sink_impl.cc61
-rw-r--r--gr-uhd/lib/usrp_sink_impl.h18
3 files changed, 86 insertions, 6 deletions
diff --git a/gr-uhd/grc/gen_uhd_usrp_blocks.py b/gr-uhd/grc/gen_uhd_usrp_blocks.py
index a969ab95d1..40c674b5fa 100644
--- a/gr-uhd/grc/gen_uhd_usrp_blocks.py
+++ b/gr-uhd/grc/gen_uhd_usrp_blocks.py
@@ -113,15 +113,20 @@ inputs:
id: command
optional: true
hide: ${'$'}{hide_cmd_port}
-% if sourk == 'sink':
-- domain: stream
-% else:
+% if sourk == 'source':
outputs:
-- domain: stream
% endif
+- domain: stream
dtype: ${'$'}{type.type}
multiplicity: ${'$'}{nchan}
+% if sourk == 'sink':
+
+outputs:
+- domain: message
+ id: async_msgs
+ optional: true
+% endif
templates:
imports: |-
diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc
index 2b393443c4..92ff805191 100644
--- a/gr-uhd/lib/usrp_sink_impl.cc
+++ b/gr-uhd/lib/usrp_sink_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2010-2016 Free Software Foundation, Inc.
+ * Copyright 2010-2016,2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -47,13 +47,20 @@ namespace gr {
io_signature::make(0, 0, 0)),
usrp_block_impl(device_addr, stream_args, length_tag_name),
_length_tag_key(length_tag_name.empty() ? pmt::PMT_NIL : pmt::string_to_symbol(length_tag_name)),
- _nitems_to_send(0)
+ _nitems_to_send(0),
+ _async_event_loop_running(true)
{
+ message_port_register_out(ASYNC_MSGS_PORT_KEY);
+ _async_event_thread = gr::thread::thread([this](){
+ this->async_event_loop();
+ });
_sample_rate = get_samp_rate();
}
usrp_sink_impl::~usrp_sink_impl()
{
+ _async_event_loop_running = false;
+ _async_event_thread.join();
}
::uhd::dict<std::string, std::string>
@@ -702,5 +709,55 @@ namespace gr {
#endif /* GR_CTRLPORT */
}
+ void
+ usrp_sink_impl::async_event_loop()
+ {
+ typedef ::uhd::async_metadata_t md_t;
+ md_t metadata;
+
+ while(_async_event_loop_running) {
+ while(!_dev->get_device()->recv_async_msg(metadata, 0.1)) {
+ if(!_async_event_loop_running){
+ return;
+ }
+ }
+
+ pmt::pmt_t event_list = pmt::PMT_NIL;
+
+ if(metadata.event_code & md_t::EVENT_CODE_BURST_ACK){
+ event_list = pmt::list_add(event_list, BURST_ACK_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_UNDERFLOW){
+ event_list = pmt::list_add(event_list, UNDERFLOW_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_UNDERFLOW_IN_PACKET){
+ event_list = pmt::list_add(event_list, UNDERFLOW_IN_PACKET_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_SEQ_ERROR){
+ event_list = pmt::list_add(event_list, SEQ_ERROR_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_SEQ_ERROR_IN_BURST){
+ event_list = pmt::list_add(event_list, SEQ_ERROR_IN_BURST_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_TIME_ERROR){
+ event_list = pmt::list_add(event_list, TIME_ERROR_KEY);
+ }
+
+ if(!pmt::eq(event_list, pmt::PMT_NIL)){
+ pmt::pmt_t value = pmt::dict_add(pmt::make_dict(), EVENT_CODE_KEY, event_list);
+ if(metadata.has_time_spec){
+ pmt::pmt_t time_spec = pmt::cons(
+ pmt::from_long(metadata.time_spec.get_full_secs()),
+ pmt::from_double(metadata.time_spec.get_frac_secs())
+ );
+ value = pmt::dict_add(value, TIME_SPEC_KEY, time_spec);
+ }
+ value = pmt::dict_add(value, CHANNEL_KEY, pmt::from_uint64(metadata.channel));
+ pmt::pmt_t msg = pmt::cons(ASYNC_MSG_KEY, value);
+ message_port_pub(ASYNC_MSGS_PORT_KEY, msg);
+ }
+ }
+ }
+
} /* namespace uhd */
} /* namespace gr */
diff --git a/gr-uhd/lib/usrp_sink_impl.h b/gr-uhd/lib/usrp_sink_impl.h
index 10f55848ec..774baf1f24 100644
--- a/gr-uhd/lib/usrp_sink_impl.h
+++ b/gr-uhd/lib/usrp_sink_impl.h
@@ -30,6 +30,20 @@ static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("tx_time");
static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("tx_freq");
static const pmt::pmt_t COMMAND_KEY = pmt::string_to_symbol("tx_command");
+//Asynchronous message handling related PMTs
+static const pmt::pmt_t ASYNC_MSG_KEY = pmt::string_to_symbol("uhd_async_msg");
+static const pmt::pmt_t CHANNEL_KEY = pmt::string_to_symbol("channel");
+static const pmt::pmt_t TIME_SPEC_KEY = pmt::string_to_symbol("time_spec");
+static const pmt::pmt_t EVENT_CODE_KEY = pmt::string_to_symbol("event_code");
+static const pmt::pmt_t BURST_ACK_KEY = pmt::string_to_symbol("burst_ack");
+static const pmt::pmt_t UNDERFLOW_KEY = pmt::string_to_symbol("underflow");
+static const pmt::pmt_t UNDERFLOW_IN_PACKET_KEY = pmt::string_to_symbol("underflow_in_packet");
+static const pmt::pmt_t SEQ_ERROR_KEY = pmt::string_to_symbol("seq_error");
+static const pmt::pmt_t SEQ_ERROR_IN_BURST_KEY = pmt::string_to_symbol("seq_error_in_burst");
+static const pmt::pmt_t TIME_ERROR_KEY = pmt::string_to_symbol("time_error");
+static const pmt::pmt_t ASYNC_MSGS_PORT_KEY = pmt::string_to_symbol("async_msgs");
+
+
namespace gr {
namespace uhd {
@@ -119,6 +133,10 @@ namespace gr {
const pmt::pmt_t _length_tag_key;
long _nitems_to_send;
+ //asynchronous messages related stuff
+ bool _async_event_loop_running;
+ void async_event_loop();
+ gr::thread::thread _async_event_thread;
};
} /* namespace uhd */