Hello Daniel, hi Rich,

if you actually want to pass a string as PMT, the pmt::intern("..") is
ok (although it has a performance penalty[0]).
If you want to simply sent byte buffers, the uniform vectors approach
would be the best (have a look at make_uvector8).

As for a simple example of message passing: I didn't try very thoroughly
to understand your code, but it seems a bit complicated for what it
tries to achieve (which is simply sending a message when there's stream
items available). For one, there's message_sink / _source which already
converts from stream to message port for you; secondly, I don't
understand your meta object at all, sorry.

I think there's a simpler example for message sending in our guided
tutorials [1], specifically in part 5, with the chat application's
source code here [2], but that's python; however, C++ and python
implementations would closely resemble each other here.

Now, that example is far more general purpose -- but there's a whole
framework dedicated to processing digital signals in gr-digital. I do
recommend looking at the OFDM examples [3], but for your classical
preamble method, the test_corr_and_sync.grc[4] example is likely close
to what you want. It's centered around digital::correlate_and_sync_cc
[5]. You'll notice that it just passes through all samples, and whenever
it detects a preamble, adds stream tags [important concept here, 6]
denoting that estimate. The downstream PFB time sync and the costas loop
then use the time_est and the phase_est tag to synchronize to the
transmitter. Of course, you'd still have to "throw away" everything
that's not part of a packet yourself.

With that functionality in mind, I'd like to direct your attention to
the tx_ofdm.grc example:
1. It uses tagged streams; these are just sample streams (not message
ports), but for blocks that do care, the GNU Radio scheduler makes sure
that there's always exactly one "packet" worth of items available (as
marked by a specified tag). That's the preferred way of dealing with
packeted data -- it lets you use all the standard blocks on items (eg.
multiply etc), whilst still keeping the packeted structure.
2. It uses the packet header generator [7], which takes in bytes of
data, and generates a header for these -- which will enable the
header_payload_demux[8] to function. You'd still need a preamble and a
correlation -- but correlate_and_sync emits tags, any one of which's
keys you can use as trigger key for header_payload_demux.

Now, I must admit that I'm not absolutely sure where correlate_and_sync
adds its tags (ie. at the center of the detected preamble or somewhere
else), so it's possible you'd have to account for a fixed distance.

I hope that this gives you a few useful hints.
Best regards & happy hacking,

Marcus M

PS: By the way, simple_{framer,correlator} are in the deprecated
group[10], which I guess is the reason writing documentation had had a
low priority.

[0] Strings are internalized in PMT, ie. they are hashed upon creation
and a new PMT is only
[1] https://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorials
[2]
https://github.com/gnuradio/gr-tutorial/blob/master/python/chat_blocks.py
[3]
https://github.com/gnuradio/gnuradio/tree/master/gr-digital/examples/ofdm ;
These files are usually installed somewhere like
/usr/share/gnuradio/examples/digital
[4]
https://github.com/gnuradio/gnuradio/blob/master/gr-digital/examples/demod/test_corr_and_sync.grc
[5]
http://gnuradio.org/doc/doxygen/classgr_1_1digital_1_1correlate__and__sync__cc.html
[6]
https://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorial_Programming_Topics#52-Stream-Tags
[7]
http://gnuradio.org/doc/doxygen/classgr_1_1digital_1_1packet__headergenerator__bb.html
[8]
http://gnuradio.org/doc/doxygen/classgr_1_1digital_1_1header__payload__demux.html
[10] http://gnuradio.org/doc/doxygen/group__deprecated__blk.html
On 02/08/2015 02:48 AM, Daniel Franch wrote:
> Earlier today, I've posted a question on how to do frame detection and
> extraction in GNU Radio
> (http://gnuradio.4.n7.nabble.com/Simple-Frame-Detection-td52233.html).
> I have a feeling that the best way to accomplish what I need is using
> the message passing system. 
>
> But I simply can't find an easy enough example to understand how
> message passing works. So I tried to create two simple blocks in order
> to better understand this system. I simply wanted a block that would
> receive a stream (not neccesarily tagged) of bytes and then post them
> as a message. The other one would receive this message and then output
> the same stream of bytes. I know there are message source/sink blocks
> that do this, but as I understand, they work on a previous message
> passing system. 
>
> My blocks were written this way: 
>
> Message writing: 
> message_write_b_impl::message_write_b_impl() 
>       : gr::sync_block("message_write_b", 
>               gr::io_signature::make(1, 1, sizeof(char)), 
>               gr::io_signature::make(0, 0, 0)) 
>     { 
>         message_port_register_out(pmt::mp("out")); 
>         buffer = new char[128]; 
>         counter = 0; 
>     } 
>
>     /* 
>      * Our virtual destructor. 
>      */ 
>     message_write_b_impl::~message_write_b_impl() 
>     { 
>         delete[] buffer; 
>     } 
>     
>     void 
>     message_write_b_impl::send_message() 
>     { 
>         pmt::pmt_t meta = pmt::make_dict(); 
>         pmt::pmt_t payload = pmt::from_long(long(buffer[counter++])); 
>         message_port_pub(pmt::mp("out"), pmt::cons(meta, payload)); 
>         std::memset(buffer, 0, sizeof(buffer)); 
>     } 
>
>     int 
>     message_write_b_impl::work(int noutput_items, 
>                           gr_vector_const_void_star &input_items, 
>                           gr_vector_void_star &output_items) 
>     { 
>         const char *in = (const char *) input_items[0]; 
>
>         for(int i = 0; i < noutput_items; i++) 
>         { 
>             buffer[counter] = in[i]; 
>             this->send_message(); 
>             
>             if(counter >= 128) 
>             { 
>                 counter = 0; 
>             }             
>         } 
>         consume_each(noutput_items); 
>         
>         return 0; 
>     } 
>
> Message read: 
> message_read_b_impl::message_read_b_impl() 
>       : gr::sync_block("message_read_b", 
>               gr::io_signature::make(0, 0, 0), 
>               gr::io_signature::make(1, 1, sizeof(char))) 
>     { 
>         message_port_register_in(pmt::mp("in")); 
>         set_msg_handler(pmt::mp("in"), 
>         boost::bind(&message_read_b_impl::in_handling, this, _1)); 
>         
>         buffer = new char[128]; 
>         counter = 0; 
>         rx_check = false; 
>     } 
>
>     /* 
>      * Our virtual destructor. 
>      */ 
>     message_read_b_impl::~message_read_b_impl() 
>     { 
>         delete[] buffer; 
>     } 
>     
>     void 
>     message_read_b_impl::in_handling(pmt::pmt_t msg) 
>     { 
>         if(pmt::is_integer(msg)) 
>         { 
>             buffer[counter++] = char(pmt::from_long(msg)); 
>             rx_check = true; 
>         } 
>         if(counter == 128) 
>         { 
>             counter = 0; 
>             rx_check = false; 
>         } 
>     } 
>
>     int 
>     message_read_b_impl::work(int noutput_items, 
>                           gr_vector_const_void_star &input_items, 
>                           gr_vector_void_star &output_items) 
>     { 
>         char *out = (char *) output_items[0]; 
>
>         for(int i = 0; i < noutput_items; i++) 
>         {       
>             while(!rx_check); 
>             out[i] = buffer[i]; 
>         } 
>         return noutput_items; 
>     } 
>
> As far as I understand, this could be the simplest case to send bytes
> through messages. But I feel there is something wrong, as the pmt
> doesn't seem to have a method to deal with chars, so I have to do lots
> of conversions. Still, this didn't seem to be a reason of bigger
> concerns. 
>
> My python QA block simply does a message connect between their message
> ports. But when I try to run the test, the tb simply freezes and I
> have to finish with ctrl+C. 
>
> Is there any easier way to implement message passing? 
>
> Thanks in advance, 
> Dan Franch
>
>
> _______________________________________________
> Discuss-gnuradio mailing list
> Discuss-gnuradio@gnu.org
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to