Guide to help move from 3.6 to 3.7
Cmake structure for out-of-tree projects
To link against GNU Radio in 3.7:
- Remove FindGnuradioCore.cmake and FindGruel.cmake,
Replace with FindGnuradioRuntime.cmake
- Remove all GRUEL_ references and replace GNURADIO_CORE variables with GNURADIO_RUNTIME_
- Update #include<gruel/attributes.h> to <gnuradio/attributes.h>
Reorganized Blocks
We documented where we moved all blocks from gnuradio-core into their respective components. This can be found in a Google doc:
Help in documenting where Python modules moved, which we did not track since it was simply a move and not a recoding, would be welcome here.
API Changes in Blocks
gr::filter::freq_xlating_fir_filter_XXX
- The center_freq argument is now the actual center frequency of the incoming signal.
- In previous versions of GNU Radio, this was the negative of the center frequency. To fix, just change the sign.
Code structure for out-of-tree modules
The file structure is changing from this format:
gr-modname/include/modname_blockname.h gr-modname/lib/modname_blockname.cc...to:
gr-modname/include/modname/blockname.h gr-modname/lib/blockname_impl.h gr-modname/lib/blockname_impl.ccSome things to note:
include/modname/blockname.h
- This public header file declares an abstract class. Public methods declared here are pure virtual and should be of the form:virtual return_type function_name(arg_list) = 0
since these must be implemented by a subclass (theblockname_impl
class will be the concrete class).
lib/blockname_impl.h
- This private header file declares member variables and concrete implementations of methods declared in the abstract class.lib/blockname_impl.cc
- This file defines the member variables and provides the concrete implementations of methods inlib/blockname_impl.h
.
Make sure the methods in include/modname/blockname.h
are declared pure virtual so that blockname
can remain an abstract class. If blockname
is not abstract, your code may compile but SWIG will interpret the declaration as the concrete class instead of your blockname_impl
class. At runtime this will cause an error like ImportError: [...] undefined symbol
when the Python interpreter attempts to load your SWIGged object code. The new coding structure is discussed in great detail here: Blocks Coding Guide.
Recognizing Namespace Changes
All blocks and classes are under namespace in GNU Radio now. So make sure that OOT code understands this.
One big issue to remember is the changes to the class inheritance:
class MODNAME_API classname : public gr_block class MODNAME_API classname : public gr_sync_block class MODNAME_API classname : public gr_sync_decimator class MODNAME_API classname : public gr_sync_interpolator
... becomes:
class MODNAME_API classname : public gr::block class MODNAME_API classname : public gr::sync_block class MODNAME_API classname : public gr::sync_decimator class MODNAME_API classname : public gr::sync_interpolator
Update to the private implementation structure in gnuradio-runtime:
- Includes will change in form from these examples:
#include <gr_sync_block.h> #include <gr_io_signature.h> #include <audio/source.h> #include <filter/pfb_decimator_ccf.h>...to:
#include <gnuradio/sync_block.h> #include <gnuradio/io_signature.h> #include <gnuradio/audio/source.h> #include <gnuradio/filter/pfb_decimator_ccf.h>
- The C++ classes in the GNU Radio runtime will be accessed through the 'gr' namespace, so class declarations that look like:
class my_foo_block : public gr_sync_block {...}; class my_top_block : public gr_top_block {...};
...will become:
class my_foo_block : public gr::sync_block {...}; class my_top_block : public gr::top_block {...};
- Finally, creating instances of classes in the runtime will use the static class make() function, instead of calling the separate gr_make_* calls. Thus:
gr_make_io_signature(1, 1, sizeof(gr_complex)) gr_make_io_signature2(1, 1, sizeof(gr_complex))
...becomes:
gr::io_signature::make(1, 1, sizeof(gr::complex)) gr::io_signature::make2(1, 1, sizeof(gr::complex))
- Python and GRC code won't be affected by this change.
Include Directories
- As already hinted at above, all headers should be included from the gnuradio directory:
#include <gnuradio/blocks/null_source.h>
- Include directories in your project should not include gnuradio. You would use /usr/local/include. Do not use /usr/local/include/gnuradio.
- With the renaming of files, using the include/gnuradio directly could cause name clashes with other projects or standard header files. In particular, #include <math.h> could potentially find gnuradio/math.h instead of the intended system math.h.
Classes, Structs, and Typedefs
Classes and structs are all renamed and under namespaces. So gr_thing
becomes gr::thing
. This includes gr_tag_t
--> gr::tag_t
and gr_msg_queue_sptr
--> gr::msg_queue::sptr
.
However, typedefs have not been changed. This includes:
gr_complex gr_vector_void_star gr_vector_const_void_star gr_vector_int
PMT
- Import PMT in Python as
import pmt
(instead offrom gruel import pmt
).
- All PMT function names have dropped the
pmt_
prefix. So in Python usepmt.to_long
instead ofpmt.pmt_to_long
and in C++ usepmt::to_long
instead ofpmt::pmt_to_long
.
Restructure of GRC Category Names to Help Transition
- We removed all of the old blocks from the GRC component tree.
- This does not remove the blocks from GRC, so this does not affect GRC apps already created.
- The change affects how we find blocks, and the blocks in the category tree are now (almost) all from 3.7.
- We have changed the category names and reorged all of the blocks, so it might take a little bit of getting used to. But we feel the new categorization is more intuitive.
- The next section shows the new category names used.
- When using the component tree, almost all the blocks listed there are the new blocks for 3.7.
- When opening your GRC files now, if you are using a block that is from 3.6, the name will be: "Block name (old)".
- This is to make it clear that you are using a pre-3.7 block.
- The (old) name is to help identify where you can update to a new 3.7 block in your flowgraph.
- This will help prepare you for the conversion to v3.7
- A script can help migrating flowgraphs with many old blocks to the 3.7 versions. One attempt with only 15 blocks is at http://nathanwest.us/grc_to_37.sh :
#!/bin/bash # Version 0.1 # run ./grc_to_37 <appname>.grc # this will create a backup copy and attempt to convert the api calls to 3.7 GRCFILE=$1 cp $GRCFILE $GRCFILE.pre3.7upgrade_backup # I refuse to take responsibility for breaking your flowgraphs # set up a list of partial regexps to change modules list_of_block_changes=( "gr_peak_detector2_fb/blocks_peak_detector2_fb" "gr_short_to_float/blocks_short_to_float" "gr_diff_phasor_cc/digital_diff_phasor_cc" "blks2_logpwrfft_x/logpwrfft_x" "gr_rms_xx/blocks_rms_xx" "gr_probe_density_b/digital_probe_density_b" "gr_mute_xx/blocks_mute_xx" "gr_agc_xx/analog_agc_xx" "gr_ctcss_squelch_ff/analog_ctcss_squelch_ff" "gr_diff_encoder_bb/digital_diff_encoder_bb" "gr_pll_refout_cc/analog_pll_refout_cc" "gr_uchar_to_float/blocks_uchar_to_float" "gr_interp_fir_filter_xxx/interp_fir_filter_xxx" "gr_udp_sink/blocks_udp_sink" "gr_and_xx/blocks_and_xx" "gr_keep_one_in_n/blocks_keep_one_in_n" "gr_vector_sink_x/blocks_vector_sink_x" "gr_freq_xlating_fir_filter_xxx/freq_xlating_fir_filter_xxx" "gr_float_to_int/blocks_float_to_int" "gr_file_source/blocks_file_source" "gr_float_to_short/blocks_float_to_short" "gr_fft_vxx/fft_vxx" "gr_quadrature_demod_cf/analog_quadrature_demod_cf" "gr_file_sink/blocks_file_sink" "gr_pfb_clock_sync_xxx/digital_pfb_clock_sync_xxx" "gr_multiply_const_vxx/blocks_multiply_const_vxx" "gr_peak_detector_xb/blocks_peak_detector_xb" "gr_noise_source_x/analog_noise_source_x" "gr_simple_framer/digital_simple_framer" "gr_delay/blocks_delay" "gr_pfb_synthesizer_ccf/pfb_synthesizer_ccf" "gr_short_to_char/blocks_short_to_char" "gr_chunks_to_symbols_xx/digital_chunks_to_symbols_xx" "gr_interleaved_short_to_complex/blocks_interleaved_short_to_complex" "gr_frequency_modulator_fc/analog_frequency_modulator_fc" "gr_xor_xx/blocks_xor_xx" "gr_dpll_bb/analog_dpll_bb" "gr_threshold_ff/blocks_threshold_ff" "gr_nop/blocks_nop" "gr_unpack_k_bits_bb/blocks_unpack_k_bits_bb" "gr_max_xx/blocks_max_xx" "gr_int_to_float/blocks_int_to_float" "gr_stream_to_streams/blocks_stream_to_streams" "blks2_wfm_rcv/analog_wfm_rcv" "gr_fractional_interpolator_xx/fractional_interpolator_xx" "gr_conjugate_cc/blocks_conjugate_cc" "blks2_fm_demod_cf/analog_fm_demod_cf" "gr_fir_filter_xxx/fir_filter_xxx" "gr_null_source/blocks_null_source" "gr_complex_to_arg/blocks_complex_to_arg" "gr_pwr_squelch_xx/analog_pwr_squelch_xx" "gr_descrambler_bb/digital_descrambler_bb" "gr_copy/blocks_copy" "gr_complex_to_mag/blocks_complex_to_mag" "gr_throttle/blocks_throttle" "gr_additive_scrambler_bb/digital_additive_scrambler_bb" "gr_wavfile_sink/blocks_wavfile_sink" "gr_vector_source_x/blocks_vector_source_x" "gr_moving_average_xx/blocks_moving_average_xx" "gr_char_to_short/blocks_char_to_short" "blks2_fm_deemph/analog_fm_deemph" "gr_pll_freqdet_cf/analog_pll_freqdet_cf" "gr_or_xx/blocks_or_xx" "blks2_fm_preemph/analog_fm_preemph" "blks2_wfm_tx/analog_wfm_tx" "gr_stream_to_vector/blocks_stream_to_vector" "gr_glfsr_source_x/digital_glfsr_source_x" "gr_map_bb/digital_map_bb" "gr_sig_source_x/analog_sig_source_x" "gr_transcendental/blocks_transcendental" "gr_skiphead/blocks_skiphead" "gr_hilbert_fc/hilbert_fc" "blks2_nbfm_rx/analog_nbfm_rx" "random_source_x/analog_random_source_x" "gr_complex_to_real/blocks_complex_to_real" "gr_null_sink/blocks_null_sink" "gr_float_to_complex/blocks_float_to_complex" "gr_multiply_xx/blocks_multiply_xx" "gr_simple_correlator/digital_simple_correlator" "gr_sample_and_hold_xx/blocks_sample_and_hold_xx" "blks2_pfb_channelizer_ccf/pfb_channelizer_ccf" "gr_goertzel_fc/goertzel_fc" "gr_complex_to_mag_squared/blocks_complex_to_mag_squared" "gr_packed_to_unpacked_xx/blocks_packed_to_unpacked_xx" "blks2_standard_squelch/analog_standard_squelch" "blks2_am_demod_cf/analog_am_demod_cf" "gr_and_const_xx/blocks_and_const_xx" "gr_unpacked_to_packed_xx/blocks_unpacked_to_packed_xx" "gr_probe_avg_mag_sqrd_x/analog_probe_avg_mag_sqrd_x" "gr_channel_model/channels_channel_model" "gr_divide_xx/blocks_divide_xx" "gr_simple_squelch_cc/analog_simple_squelch_cc" "gr_message_source/blocks_message_source" "gr_sub_xx/blocks_sub_xx" "gr_stream_mux/blocks_stream_mux" "gr_burst_tagger/blocks_burst_tagger" "gr_float_to_uchar/blocks_float_to_uchar" "gr_scrambler_bb/digital_scrambler_bb" "gr_streams_to_vector/blocks_streams_to_vector" "gr_add_xx/blocks_add_xx" "gr_feedforward_agc_cc/analog_feedforward_agc_cc" "gr_iir_filter_ffd/iir_filter_ffd" "blks2_stream_to_vector_decimator/blocks_stream_to_vector_decimator" "gr_pn_correlator_cc/digital_pn_correlator_cc" "gr_streams_to_stream/blocks_streams_to_stream" "gr_rational_resampler_base_xxx/rational_resampler_base_xxx" "gr_vector_to_streams/blocks_vector_to_streams" "gr_interleave/blocks_interleave" "gr_add_const_vxx/blocks_add_const_vxx" "gr_message_sink/blocks_message_sink" "gr_complex_to_imag/blocks_complex_to_imag" "gr_vco_f/blocks_vco_f" "gr_deinterleave/blocks_deinterleave" "gr_argmax_xx/blocks_argmax_xx" "gr_not_xx/blocks_not_xx" "gr_udp_source/blocks_udp_source" "gr_nlog10_ff/blocks_nlog10_ff" "gr_diff_decoder_bb/digital_diff_decoder_bb" "gr_phase_modulator_fc/analog_phase_modulator_fc" "gr_complex_to_interleaved_short/blocks_complex_to_interleaved_short" "gr_float_to_char/blocks_float_to_char" "gr_head/blocks_head" "gr_fft_filter_xxx/fft_filter_xxx" "gr_cpfsk_bc/analog_cpfsk_bc" "gr_vector_to_stream/blocks_vector_to_stream" "gr_agc2_xx/analog_agc2_xx" "gr_pll_carriertracking_cc/analog_pll_carriertracking_cc" "gr_repeat/blocks_repeat" "gr_filter_delay_fc/filter_delay_fc" "blks2_rational_resampler_xxx/rational_resampler_xxx" "gr_char_to_float/blocks_char_to_float" "gr_integrate_xx/blocks_integrate_xx" "gr_wavfile_source/blocks_wavfile_source" "gr_complex_to_float/blocks_complex_to_float" "gr_single_pole_iir_filter_xx/single_pole_iir_filter_xx" "blks2_nbfm_tx/analog_nbfm_tx" "blks2_wfm_rcv_pll/analog_wfm_rcv_pll" "const_source_x/analog_const_source_x" "blks2_pfb_arb_resampler_ccf/pfb_arb_resampler_xxx" ) for block in "${list_of_block_changes[@]}" do sed --in-place "/<key/s/$block/g" $GRCFILE # only replace the keys lines because otherwise # block ids can get clobbered if there are 2 of the same block # one old, and one new that both use grc generated ids done
- The search box will return all blocks found, including the (old) blocks, so you can still get access to these, if you really want.
Note. Not all GRC blocks were converted this way on master. A lot of the hierarchical blocks that had a GRC component were not necessarily moved over to the new components on the master branch. So you might still find a few problems when opening up old GRC files in 3.7.
To see the list of blocks that are still being pulled in the old way, you can look at grc/blocks/block_tree.xml in the source code, or it is installed into ${prefix}/share/gnuradio/blocks/block_tree.xml.
This should really help with transitioning your work to 3.7 when you need to and in the meantime will not affect your current, running systems in anyway but looks.
GRC and Doxygen Components
We have completely overhauled the category naming scheme in both the Doxygen manual and in GRC.
Click Here for a spreadsheet listing all of the blocks and which categories they are in
The following categories (and the Doxygen \ingroup
group name for markup) are:
Category Name | Doxygen Group |
---|---|
Audio | audio_blk |
Boolean Operators | boolean_operators_blk |
Byte Operators | byte_operators_blk |
Channel models | channel_models_blk |
Channelizers | channelizers_blk |
Coding | coding_blk |
Debug Tools | debug_tool_blk |
Deprecated | deprecated_blk |
Equalizers | equalizers_blk |
Error Coding | error_coding_blk |
FCD | fcd_blk |
File Operators | file_operators_blk |
Filters | filter_blk |
Fourier Analysis | fourier_analysis_blk |
Widgets / QT | qtgui_blk |
Widgets / WX | wxgui_blk |
Instrumentation / QT | instrumentation_blk |
Instrumentation / WX | instrumentation_blk |
Level Controllers | level_controllers_blk |
Math Operators | math_operators_blk |
Measurement Tools | measurement_tools_blk |
Message Tools | message_tools_blk |
Misc | misc_blk |
Modulators | modulators_blk |
Networking Tools | networking_tool_blk |
NOAA | noaa_blk |
OFDM | ofdm_blk |
Packet Operators | packet_operators_blk |
Pager | pager_blk |
Peak Detectors | peak_detectors_blk |
Resamplers | resamplers_blk |
Stream Operators | stream_operators_blk |
Stream Tag Tools | |
Symbol Coding | symbol_coding_blk |
Synchronizers | synchronizers_blk |
Trellis Coding | trellis_coding_blk |
Type Converters | type_converters_blk |
UHD | uhd_blk |
Variables | |
Waveform Generators | waveform_generators_blk |
VOLK Changes
We have updated the VOLK directory structure to help in the automating of tests and building of new VOLK kernels, including the use of out-of-tree libraries of VOLK functions.
Also, a handful of the original VOLK kernels used num_bytes
as the parameter while most used num_items
. This inconsistency made it difficult to automate some tests, and it made it more difficult to work with VOLK if you didn't know which style you were working with. The VOLK in 3.7 has updated this so that all blocks now use num_items
.
The affected kernels due to the 's/num_bytes/num_items/g' change are:
volk_16i_max_star_16i_a.h volk_16i_max_star_horizontal_16i_a.h volk_16i_permute_and_scalar_add_a.h volk_16i_x4_quad_max_star_16i_a.h volk_16i_x5_add_quad_16i_x4_a.h volk_32f_x3_sum_of_poly_32f_a.h volk_32fc_index_max_16u_a.h volk_32fc_x2_conjugate_dot_prod_32fc_a.h volk_32fc_x2_conjugate_dot_prod_32fc_u.h volk_32fc_x2_dot_prod_32fc_a.h volk_32fc_x2_s32f_square_dist_scalar_mult_32f_a.h volk_32fc_x2_square_dist_32f_a.h