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