Repository navigation
Developing your own blocks
The authoritative reference used for this guide is Gnuradio/OutOfTreeModules
You can create both Python and C++ modules. Python blocks are slower, and C++ blocks are faster.
Here we take the example of demodm2.m in Matlab, and generate an equivalent C++ block, and then connect it to gnuradio-companion using gr-baz.
The first step is to decide on your "module" name. There is a nice tool called gr_modtool for this. In the example below I've selected uqcoms as the module name. Next, I'm creating a block called demodm2. Note filenames with dashes in them will cause problems - avoid it if you can.
$ gr_modtool newmod uqcoms
$ cd uqcoms
$ gr_modtool add demodm2
We answer that the code type is general, and the argument list is int samples_per_bit, float threshold. See the end of this section for the output we expect to see. To be compatible with grc, the argument list cannot use unsigned char as a type. Using int, short, float, gr_complex is all OK.
Next we go into the lib/ directory. There is a demodm2_impl.cc and demodm2_impl.h, which are the C++ code for the block we are writing.
First let's modify demodm2_impl.h. To store the two arguments we set. Under private we add these two lines
private:
// local variables
unsigned char my_samples_per_bit;
float my_threshold;
Next, let's modify demodm2_impl.cc to do the work we want it to do.
Modify the constructor, we need to set the block to have a max/min of 1 stream for both input and output. Our input is of type float, our output is of type unsigned char (byte). Next we want to initialize the local variables that we specified for the block.
demodm2_impl::demodm2_impl(unsigned char samples_per_bit, float threshold)
: gr_block("demodm2",
gr_make_io_signature(1, 1, sizeof(float)),
gr_make_io_signature(1, 1, sizeof(unsigned char))),
my_samples_per_bit(samples_per_bit),
my_threshold(threshold)
Next, we modify the forecast function. As we have samples_per_bit input samples, converting into one output sample, we need to tell gnuradio about this.
void
demodm2_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
{
int n = noutput_items * my_samples_per_bit;
ninput_items_required[0] = (n==0 ? 1 : n);
}
Now the work function, replace <+ITYPE*> with float, and <+OTYPE*> with unsigned char.
Also, we can now add our code. Also, here is a side by side comparison of the MATLAB code that was provided for the introductory assignment in 2013 and the new C++ code: DemodM2 inside MATLAB and C++. The "work" function is actually really similar. The biggest difference is all the decorator functions which let you use this block as part of a larger system.
I also recommend looking at the end result: demodm2_impl.cc in gnuradio/gr-uqcoms/lib/demodm2_impl.cc
After all the code is written we go to the root directory and build it:
mkdir build
cd build
cmake ../
make
sudo make install
ldconfig
So that this block works in gnuradio-companion we need to build an XML description for it. We can do this with the command gr_modtool makexml demodm2.
Next we can now open gnuradio-companion, and add this new custom block. It will be in a group called 'UQCOMS'.
See the example inside `/gnuradio/example/' for both a screenshot of the flowgraph as well as the GRC file:
NOTE: to get this image you can use File... Screen Capture.
As we want to test a packet structure in Gnuradio-companion the most convenient way of doing this is using the vector source. This lets us specify a vector - very similarly to how we would inside Matlab/Octave or any other programming language.
The vector source is turned into a stream with a vector to stream converter.
NOTE: if you do not have a physical device such as a USRP, RTL-SDR etc then you MUST use a throttle somewhere in your flow graph to ensure smooth operation.
We get the following information coming up.
GNU Radio module name identified: uq-coms
Enter code type: general
Language: C++
Block/code identifier: demodm2
Enter valid argument list, including default arguments: int samples_per_bit, float threshold
Add Python QA code? [Y/n] Y
Add C++ QA code? [y/N] Y
Adding file 'demodm2_impl.h'...
Adding file 'demodm2_impl.cc'...
Adding file 'demodm2.h'...
Adding file 'qa_demodm2.cc'...
Adding file 'qa_demodm2.h'...
Editing swig/uq-coms_swig.i...
Adding file 'qa_demodm2.py'...
Editing python/CMakeLists.txt...
Adding file 'uq-coms_demodm2.xml'...
Editing grc/CMakeLists.txt...
See https://github.com/UQ-Communication-Systems/public for the latest version of these notes.