diff options
author | Piotr Krysik <ptrkrysik@gmail.com> | 2018-11-16 08:35:38 +0000 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-12-11 14:22:22 -0800 |
commit | 94fddb6371264c79969c0448c19fdb637d6ffc31 (patch) | |
tree | 7120f6a8412fcbc0561742411fcf56244a473f3a /gr-uhd | |
parent | 3359d67e02158199d24756155fb58ab43b7b66ef (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.py | 13 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_sink_impl.cc | 61 | ||||
-rw-r--r-- | gr-uhd/lib/usrp_sink_impl.h | 18 |
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 */ |