Problems passing the control between blocks - message passing

Hi All,

I’m working with 2 blocks that I’ve created using “UHD_AMsg_Source” as a
reference model. In these blocks, I am passing pmt_dict type as
messages,
ie:

this->post_msg(0, AMSG_KEY, dictionary,_id);

Where, dictionary contains data/metadata that I can read in the next
block
downstream.

BLOCK 1 – (pmt_dict included in the message) --> BLOCK 2

The blocks are working ok, but the problem is that when I want to
generate
several packets and post them downstream, BLOCK 1 runs until finishes
and
then BLOCK 2 takes the control until finishes. The problem is the
“return”
sentence in my work function. I did 2 possible ways

Option 1: Using -1

work {
//work here
return -1
}

In this way BLOCK 1 stops working after one iteration and it does not
run
as many times as I want.

Option 1: Not using return

work {
//work here
}

In this way BLOCK 1 runs many times and posts messages downstream all
those
times, but it gives the control to BLOCK 2 when it finishes. Then, BLOCK
2
takes the messages from the message queue. However, this implementation
is
not useful for me. BLOCK 1 should post a message downstream and then,
BLOCK
2 takes the message and work with the packet.

Any suggestion is welcome, thanks a lot for your time,

Regards,

Jose

Hi John,

I wrote the code in C++ based on UHD_AMsg_source.cc, provided in
GRExtras.
In my work function, I’ve finished it using return -1 (ie. the block has
finished processing correctly) as shown below:

int work(
const InputItems &,
const OutputItems &
){
//work definition here (ie. generate a packet and post downstream)
return -1; //done running, work done status
}

However, in that way the block in GNU Radio Companion runs only once.
The
other possibility is not to use “return” at all, but in that case what I
have is:

  1. BLOCK 1 generates a packet
  2. BLOCK 1 post the packet downstream

Step 1 and 2 repeats “N times”. When finishes, it gives the control to
BLOCK 2 to process the message. However, I need a sequence as follows:

  1. BLOCK 1 generates a packet
  2. BLOCK 1 post the packet downstream
  3. BLOCK 2 process the packet
  4. BLOCK 2 post the message again downstream and so on…

Step 1 to 4 should repeat “N times”.

Thanks again for your help,

Jose

Hi John,

Yes, I also checked the examples in your branch. In regards to your
questions.

1. BLOCK 2 is processing the data from BLOCK 1, but only when BLOCK 1
has
finished the routine “N times”. Let me post a piece of code from BLOCK
1:

int work(
const InputItems &,
const OutputItems &
){

    for (int i = 0; i < d_pkt_len; i++) {
           if (d_mode == 2)
      { elements[i] = ((i % d_pkt_len) + d_num_pkts_output) & 0xff;
              }
    else if (d_mode == 0)
      {elements[i]=0;
             }
         else // ones
    {elements[i]=0xFF;
    }
    num_output++;
  } //End of for
  d_num_pkts_output++;

  //(4.1) adding data into the dictionary
  dictionary = pmt::pmt_dict_add(dictionary, data_key, vector_data);
  std::cout << std::endl << "(4) Now, the dictionary is" << 

dictionary
<<std::endl;

  //Posting a message downstream
  this->post_msg(0, AMSG_KEY, dictionary, _d_my_unique_id);
  std::cout << std::endl << "posting the message downstream "

<<std::endl;

  return -1;  // <--The problem seems to be here

}

2. N is the number of packet that I want to transmit from BLOCK 1. In
my
code, I’m using the variable d_max_pkts. So, when d_num_pkts_output >=
d_max_pkts, the program stops:

if (d_num_pkts_output >= d_max_pkts)
  return 0;
  1. Yes, my BLOCK 1 is as follows:

block(
//“gr uhd amsg source”,
“BLOCK 1”,
gr_make_io_signature(0, 0, 0),
gr_make_io_signature(0, 0, 0),
msg_signature(false, 1)

Thanks again for your advice,

Regards,

Jose

Can you send me the files?

-John

On Wed, Oct 17, 2012 at 4:16 PM, Jose T. Diaz
<[email protected]

Hi John,

Also, I am trying to use boost::this_thread::yield() between blocks, but
when I add a third block into the chain, the control passes between
BLOCK 1
<-> BLOCK 2. When they finish, the control is passed to BLOCK 3.

Thanks again for your suggestions,

Jose

On Mon, Oct 22, 2012 at 9:17 AM, Jose T. Diaz
<[email protected]

Hi Community,

In following up this issue, we’ve tried different options (ie. returns
0,
yield or returns -1 in work function). What is happening is the block
are
running exactly once. In other words, the work() function never comes
back
and run again.

Anyone can suggest a way to solve this issue?.

Thanks for your comments,

Jose.

On Mon, Oct 22, 2012 at 5:55 PM, Jose T. Diaz
<[email protected]

On 10/22/2012 03:24 PM, Jose T. Diaz wrote:

Hi Community,

In following up this issue, we’ve tried different options (ie. returns 0,
yield or returns -1 in work function). What is happening is the block are
running exactly once. In other words, the work() function never comes back
and run again.

Anyone can suggest a way to solve this issue?.

Do you see an error when you return 0 from work? Like source block
returned 0, marking it done? If this is the case, you can update
gnuradio to get the fix.

On the other hand, its OK to block in the work function. For example,
you can block on pop_msg_queue(). Calling tb->stop() will still
interrupt this, so its safe to do.

-josh

Hi Josh,

Do you see an error when you return 0 from work? Like source block
returned 0, marking it done? If this is the case, you can update
gnuradio to get the fix.

A: I returned 0 for every block and in that case, the routines run once
only. However, I don’t see any error.

On the other hand, its OK to block in the work function. For example,
you can block on pop_msg_queue(). Calling tb->stop() will still
interrupt this, so its safe to do.

A:The first block is a source and I would like to generate several
packets
from it. If I use tb->stop(), will it stop the work function?. But, will
the work function come back again?.

Thanks a lot,

Jose.