Editing Message Passing

Jump to: navigation, search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
[[Category:Usage Manual]]
 
 
== Introduction ==
 
== Introduction ==
  
Line 82: Line 81:
 
   set_msg_handler(pmt::pmt_t port_id,
 
   set_msg_handler(pmt::pmt_t port_id,
 
     boost::bind(&block_class::message_handler_function, this, _1));
 
     boost::bind(&block_class::message_handler_function, this, _1));
 
Or starting in GNU Radio 3.8 using C++11 we can avoid Boost and express the binding as a lambda function (preferred)
 
 
  set_msg_handler(pmt::pmt_t port_id,
 
    [this](pmt::pmt_t msg) { this->message_handler_function(msg); });
 
  
 
In Python:
 
In Python:
Line 180: Line 174:
  
 
There are some examples of using the message passing infrastructure
 
There are some examples of using the message passing infrastructure
through GRC in:
+
through GRC in gr-blocks/examples/msg_passing.
 
 
gr-blocks/examples/msg_passing
 
  
 
== Using Messages as Commands ==
 
== Using Messages as Commands ==
Line 189: Line 181:
  
 
* gr::qtgui::freq_sink_c: The scaling of the frequency axis can be changed by messages
 
* gr::qtgui::freq_sink_c: The scaling of the frequency axis can be changed by messages
* gr::uhd::usrp_source and gr::uhd::usrp_sink: Many transceiver-related settings can be manipulated through command messages, such as frequency, gain and LO offset
+
* gr::uhd::usrp_source and gr::uhd::usrp_sink: Many transceiver-related settings can
* gr::digital::header_payload_demux, which receives an acknowledgement from a header parser block on how many payload items there are to process
+
  be manipulated through command messages, such as frequency, gain and LO offset
 +
* gr::digital::header_payload_demux, which receives an acknowledgement from a header parser
 +
  block on how many payload items there are to process
  
 
There is no special PMT type to encode commands, however, it is strongly recommended
 
There is no special PMT type to encode commands, however, it is strongly recommended
 
to use one of the following formats:
 
to use one of the following formats:
  
* pmt::cons(KEY, VALUE): This format is useful for commands that take a single value. Think of KEY and VALUE as the argument name and value, respectively. For the case of the QT GUI Frequency Sink, KEY would be "freq" and VALUE would be the new center frequency in Hz.
+
* pmt::cons(KEY, VALUE): This format is useful for commands that take a single value.
* pmt::dict((KEY1: VALUE1), (KEY2: VALUE2), ...): This is basically the same as the previous format, but you can provide multiple key/value pairs. This is particularly useful when a single command takes multiple arguments which can't be broken into multiple command messages (e.g., the USRP blocks might have both a timestamp and a center frequency in a command message, which are closely associated).
+
  Think of KEY and VALUE as the argument name and value, respectively. For the case of
 +
  the QT GUI Frequency Sink, KEY would be "freq" and VALUE would be the new center frequency
 +
  in Hz.
 +
* pmt::dict((KEY1: VALUE1), (KEY2: VALUE2), ...): This is basically the same as the
 +
  previous format, but you can provide multiple key/value pairs. This is particularly
 +
  useful when a single command takes multiple arguments which can't be broken into
 +
  multiple command messages (e.g., the USRP blocks might have both a timestamp and a
 +
  center frequency in a command message, which are closely associated).
  
 
In both cases, all KEYs should be pmt::symbols (i.e. strings). VALUEs can be
 
In both cases, all KEYs should be pmt::symbols (i.e. strings). VALUEs can be
Line 205: Line 206:
 
However, there are some very good reasons to stick to this format:
 
However, there are some very good reasons to stick to this format:
  
* Interoperability: The more people use the standard format, the more likely it is that blocks from different sources can work together
+
* Interoperability: The more people use the standard format, the more likely it
* Inspectability: A message debug block will display more useful information about a message if it's containing both a value and a key
+
  is that blocks from different sources can work together
* Intuition: This format is pretty versatile and unlikely to create situations where it is not sufficient (especially considering that values are PMTs themselves). As a counterexample, using positional arguments (something like "the first argument is the frequency, the second the gain") is easily forgotten, or changed in one place and not another, etc.
+
* Inspectability: A message debug block will display more useful information about
 +
  a message if it's containing both a value and a key
 +
* Intuition: This format is pretty versatile and unlikely to create situations
 +
  where it is not sufficient (especially considering that values are PMTs themselves).
 +
  As a counterexample, using positional arguments (something like "the first argument
 +
  is the frequency, the second the gain") is easily forgotten, or changed in one place
 +
  and not another, etc.
  
 
== Code Examples ==
 
== Code Examples ==
 
=== C++ ===
 
  
 
The following is snippets of code from blocks currently in GNU Radio
 
The following is snippets of code from blocks currently in GNU Radio
Line 229: Line 234:
 
The constructor of this block looks like this:
 
The constructor of this block looks like this:
  
<syntaxhighlight lang="cpp">
 
 
  {
 
  {
 
   message_port_register_in(pmt::mp("print"));
 
   message_port_register_in(pmt::mp("print"));
Line 243: Line 247:
 
     boost::bind(&message_debug_impl::print_pdu, this, _1));
 
     boost::bind(&message_debug_impl::print_pdu, this, _1));
 
  }
 
  }
</syntaxhighlight>
 
  
 
The three message input ports are registered by their respective
 
The three message input ports are registered by their respective
 
names. We then use the gr::basic_block::set_msg_handler function to  
 
names. We then use the gr::basic_block::set_msg_handler function to  
 
identify this particular port name with a callback function. The  
 
identify this particular port name with a callback function. The  
Boost ''bind'' function ([http://www.boost.org/doc/libs/1_52_0/libs/bind/bind.html Boost::bind])
+
Boost ''bind'' function ([href="http://www.boost.org/doc/libs/1_52_0/libs/bind/bind.html Boost::bind])
 
here binds the callback to a function of this block's class. So now
 
here binds the callback to a function of this block's class. So now
 
the functions in the block's private implementation class,
 
the functions in the block's private implementation class,
Line 256: Line 259:
 
messages passed to them. Below is the ''print'' function for reference.
 
messages passed to them. Below is the ''print'' function for reference.
  
<syntaxhighlight lang="cpp">
 
 
  void
 
  void
 
  message_debug_impl::print(pmt::pmt_t msg)
 
  message_debug_impl::print(pmt::pmt_t msg)
Line 264: Line 266:
 
   std::cout << "**********************************\n";
 
   std::cout << "**********************************\n";
 
  }
 
  }
</syntaxhighlight>
 
  
 
The function simply takes in the PMT message and prints it. The method
 
The function simply takes in the PMT message and prints it. The method
Line 295: Line 296:
 
shown below.
 
shown below.
  
<syntaxhighlight lang="cpp">
 
 
  void
 
  void
 
  tagged_stream_to_pdu_impl::send_message()
 
  tagged_stream_to_pdu_impl::send_message()
Line 313: Line 313:
 
   d_inpdu = false;
 
   d_inpdu = false;
 
  }
 
  }
</syntaxhighlight>
 
  
 
This function does a bit of checking to make sure the PDU is OK as
 
This function does a bit of checking to make sure the PDU is OK as
Line 330: Line 329:
 
flowgraph using the gr::blocks::pdu_to_tagged_stream block.
 
flowgraph using the gr::blocks::pdu_to_tagged_stream block.
  
=== Python ===
+
For a Python block example, see [[Python Blocks#Using Message Passing]].
 
 
A Python Block example:
 
 
 
<syntaxhighlight lang="python">
 
class msg_block(gr.basic_block):
 
    def __init__(self):
 
        gr.basic_block.__init__(
 
            self,
 
            name="msg_block",
 
            in_sig=None,
 
            out_sig=None)
 
 
        self.message_port_register_out(pmt.intern('msg_out'))
 
        self.message_port_register_in(pmt.intern('msg_in'))
 
        self.set_msg_handler(pmt.intern('msg_in'), self.handle_msg)
 
 
    def handle_msg(self, msg):
 
        self.message_port_pub(pmt.intern('msg_out'), pmt.intern('message received!'))
 
</syntaxhighlight>
 

Please note that all contributions to GNU Radio are considered to be released under the Creative Commons Attribution-ShareAlike (see GNU Radio:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To edit this page, please answer the question that appears below (more info):

Cancel | Editing help (opens in new window)