diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-07-25 22:57:34 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2014-07-25 22:57:34 -0400 |
commit | 1059f8bcca4cb8402d8e8edfa8a7a94f08505b88 (patch) | |
tree | 8e102b623c3c8d0b16cf8381e3bb796bd506253c /docs/doxygen/other | |
parent | 2b8888e03a4c8fff9527694a7f4526733eeb219f (diff) | |
parent | 115254847e9c6db03a417749f4e476ed3db95e70 (diff) |
Merge branch 'docs/structure'
Diffstat (limited to 'docs/doxygen/other')
-rw-r--r-- | docs/doxygen/other/build_guide.dox | 162 | ||||
-rw-r--r-- | docs/doxygen/other/components.dox | 34 | ||||
-rw-r--r-- | docs/doxygen/other/extra_pages.dox | 320 | ||||
-rw-r--r-- | docs/doxygen/other/main_page.dox | 503 | ||||
-rw-r--r-- | docs/doxygen/other/metadata.dox | 15 | ||||
-rw-r--r-- | docs/doxygen/other/msg_passing.dox | 5 | ||||
-rw-r--r-- | docs/doxygen/other/oot_config.dox | 78 | ||||
-rw-r--r-- | docs/doxygen/other/operating_fg.dox | 278 | ||||
-rw-r--r-- | docs/doxygen/other/prefs.dox | 87 | ||||
-rw-r--r-- | docs/doxygen/other/python_blocks.dox | 154 | ||||
-rw-r--r-- | docs/doxygen/other/usage.dox | 43 | ||||
-rw-r--r-- | docs/doxygen/other/volk_guide.dox | 152 |
12 files changed, 1017 insertions, 814 deletions
diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox new file mode 100644 index 0000000000..e5a1ae3cdd --- /dev/null +++ b/docs/doxygen/other/build_guide.dox @@ -0,0 +1,162 @@ +/*! \page build_guide Build Instructions and Information + +\section dependencies Dependencies + +The list of GNU Radio dependencies and the minimum required versions, +if any, to build the various GNU Radio components. + +Most of these components do not need to be individually compiled or +installed. Instead, rely on your operating system's package manager or +binary installation process (the <b>apt-get</b> system in Debian and +Ubuntu, <b>yum</b> in RedHat and Fedora, etc.). GNU Radio tries to keep an +up-to-date build guide for the majority of the supported operating +systems on gnuradio.org +(http://gnuradio.org/redmine/projects/gnuradio/wiki/BuildGuide). + +Not all dependencies are required for all components, and not all +components are required for a given installation. The list of required +components is determined by what the user requires from GNU Radio. If, +for example, you do not use any Comedi-based hardware, do not worry +about building gr-comedi. + +Before trying to build these from source, please try your system's +installation tool (apt-get, pkg_install, YaST, yum, urpmi, etc.) +first. Most recent systems have these packages available. + +\subsection dep_global Global Dependencies +\li git http://code.google.com/p/msysgit +\li cmake (>= 2.6) http://www.cmake.org/cmake/resources/software.html +\li boost (>= 1.35) http://www.boostpro.com/download +\li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html +\li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html + +\subsection dep_python Python Wrappers +\li python (>= 2.5) http://www.python.org/download/ +\li swig (>= 1.3.31) http://www.swig.org/download.html +\li numpy (>= 1.1.0) http://sourceforge.net/projects/numpy/files/NumPy/ + +\subsection dep_docs docs: Building the documentation +\li doxygen (>= 1.5) http://www.stack.nl/~dimitri/doxygen/download.html + +\subsection dep_grc grc: The GNU Radio Companion +\li Cheetah (>= 2.0) http://www.cheetahtemplate.org/ +\li pygtk (>= 2.10) http://www.pygtk.org/downloads.html + +\subsection dep_wavelet gr-wavelet: Collection of wavelet blocks +\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm + +\subsection dep_gr_qtgui gr-qtgui: The QT-based Graphical User Interface +\li qt (>= 4.4) http://qt.nokia.com/downloads/ +\li qwt (>= 5.2) http://sourceforge.net/projects/qwt/ +\li pyqt (>= 4.4) http://www.riverbankcomputing.co.uk/software/pyqt/download +\li pyqwt (>= 5.2) http://pyqwt.sourceforge.net/download.html + +\subsection dep_gr_wxgui gr-wxgui: The WX-based Graphical User Interface +\li wxpython (>= 2.8) http://www.wxpython.org/ +\li python-lxml (>= 1.3.6) http://lxml.de/ + +\subsection dep_gr_audio gr-audio: Audio Subsystems (system/OS dependent) +\li audio-alsa (>= 0.9) http://www.alsa-project.org +\li audio-jack (>= 0.8) http://jackaudio.org/ +\li portaduio (>= 19) http://www.portaudio.com/ +\li audio-oss (>= 1.0) http://www.opensound.com/oss.html +\li audio-osx +\li audio-windows + +It is not necessary to satisfy all of these dependencies; just the +one(s) that are right for your system. On Linux, don't expect +audio-osx and audio-windows to be either satisfied or built. + +\subsection dep_uhd uhd: The Ettus USRP Hardware Driver Interface +\li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki + +\subsection dep_gr_video_sdl gr-video-sdl: PAL and NTSC display +\li SDL (>= 1.2.0) http://www.libsdl.org/download-1.2.php + +\subsection dep_gr_comedi gr-comedi: Comedi hardware interface +\li comedilib (>= 0.8) http://www.comedi.org/ + +\subsection dep_gr_log gr-log: Logging Tools (Optional) +\li log4cpp (>= 1.0) http://log4cpp.sourceforge.net/ + + +\section build_gr_cmake Building GNU Radio + +GNU Radio is built using the Cmake build system +(http://www.cmake.org/). The standard build method is as follows: + +\code +$ mkdir $(builddir) +$ cd $(builddir) +$ cmake [OPTIONS] $(srcdir) +$ make +$ make test +$ sudo make install +\endcode + +The \$(builddir) is the directory in which the code is built. This +<b>cannot</b> be the same path as where the source code resides. Often, +\$(builddir) is \$(srcdir)/build. + +\subsection cmake_options Cmake Options + +Options can be used to specify where to find various library or +include file dependencies that are not automatically being found +(-DCMAKE_PREFIX_PATH) or set the install prefix +(-DCMAKE_INSTALL_PREFIX=(dir)). + +Components can also be enabled and disabled through the options. For a +component named *gr-comp*, the option to disable would look like: +-DENABLE_GR_COMP=off. The "off" could also be "false" or "no", and +cmake is not case sensitive about these options. Similarly, "true", +"on", or "yes" will turn this component on. All components are enabled +by default so long as their dependencies are met. + +An example is -DENABLE_PYTHON=False turns off building any Python or +Swigging components. The result will be the GNU Radio libraries and +C++ programs/applications/examples. No Python or GRC files will be +built or installed. + +The -DENABLE_DEFAULT=False can be used to disable all +components. Individual components can then be selectively turned back +on. For example, just buidling the VOLK library can be +done with this: + +\code +cmake -DENABLE_DEFAULT=Off -DENABLE_VOLK=True <srcdir> +\endcode + + +The build type allows you to specify the build as a debug or release +version. Each type sets different flags for different purposes. To set +the build type, use: + +\code +-DCMAKE_BUILD_TYPE="Release"|"Debug"|"RelWithDebInfo" +\endcode + +If not specified, the "Release" mode is the defaulted to. + +"Release" mode sets the '-O3' optimization flag. + +"Debug" mode sets '-g -O2' flags to export debug symbols and reduce +the optimization to make the libraries easier to debug and step +through. + +"RelWithDebInfo" builds with the release mode optimization of "-O3" +but also exports debug symbols with "-g". + + +\subsection build_gr_cmake_e100 Building for the E100 + +To build GNU Radio on the Ettus Research E100 embedded platforms, +Cmake has to know that the processors uses the NEON extensions. Use +the + +\code +cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ + -DCMAKE_C_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ + <gr_source_dir> +\endcode + +*/ diff --git a/docs/doxygen/other/components.dox b/docs/doxygen/other/components.dox new file mode 100644 index 0000000000..1e98beb6f2 --- /dev/null +++ b/docs/doxygen/other/components.dox @@ -0,0 +1,34 @@ +/*! \page page_components Components + +\section components_blocks GNU Radio Blocks + +GNU Radio uses discrete signal processing blocks that are connected +together to perform your signal processing application. This manual +contain a list of all GNU Radio <a href="modules.html"><b>C++ Blocks</b></a>, +sorted by category. + +Please note that at this time, we haven't found an acceptable way to +provide unified documentation for the C++ parts of the system and the +parts written in Python (mostly hierarchical blocks). Until this gets +worked out, please bear with us, or better yet, solve it for us! + +\section components_list In-tree components + +All our in-tree components have their own top-level documentation: + +\li \subpage page_analog +\li \subpage page_audio +\li \subpage page_blocks +\li \subpage page_channels +\li \subpage page_ctrlport +\li \subpage page_digital +\li \subpage page_fcd +\li \subpage page_fec +\li \subpage page_fft +\li \subpage page_filter +\li \subpage page_qtgui +\li \subpage page_uhd +\li \subpage page_vocoder +\li \subpage page_zeromq + +*/ diff --git a/docs/doxygen/other/extra_pages.dox b/docs/doxygen/other/extra_pages.dox deleted file mode 100644 index 2a707f81aa..0000000000 --- a/docs/doxygen/other/extra_pages.dox +++ /dev/null @@ -1,320 +0,0 @@ -/*! \page build_guide Build Instructions and Information - -\section dependencies Dependencies - -The list of GNU Radio dependencies and the minimum required versions, -if any, to build the various GNU Radio components. - -Most of these components do not need to be individually compiled or -installed. Instead, rely on your operating system's package manager or -binary installation process (the <b>apt-get</b> system in Debian and -Ubuntu, <b>yum</b> in RedHat and Fedora, etc.). GNU Radio tries to keep an -up-to-date build guide for the majority of the supported operating -systems on gnuradio.org -(http://gnuradio.org/redmine/projects/gnuradio/wiki/BuildGuide). - -Not all dependencies are required for all components, and not all -components are required for a given installation. The list of required -components is determined by what the user requires from GNU Radio. If, -for example, you do not use any Comedi-based hardware, do not worry -about building gr-comedi. - -Before trying to build these from source, please try your system's -installation tool (apt-get, pkg_install, YaST, yum, urpmi, etc.) -first. Most recent systems have these packages available. - -\subsection dep_global Global Dependencies -\li git http://code.google.com/p/msysgit -\li cmake (>= 2.6) http://www.cmake.org/cmake/resources/software.html -\li boost (>= 1.35) http://www.boostpro.com/download -\li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html -\li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html - -\subsection dep_python Python Wrappers -\li python (>= 2.5) http://www.python.org/download/ -\li swig (>= 1.3.31) http://www.swig.org/download.html -\li numpy (>= 1.1.0) http://sourceforge.net/projects/numpy/files/NumPy/ - -\subsection dep_docs docs: Building the documentation -\li doxygen (>= 1.5) http://www.stack.nl/~dimitri/doxygen/download.html - -\subsection dep_grc grc: The GNU Radio Companion -\li Cheetah (>= 2.0) http://www.cheetahtemplate.org/ -\li pygtk (>= 2.10) http://www.pygtk.org/downloads.html - -\subsection dep_wavelet gr-wavelet: Collection of wavelet blocks -\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm - -\subsection dep_gr_qtgui gr-qtgui: The QT-based Graphical User Interface -\li qt (>= 4.4) http://qt.nokia.com/downloads/ -\li qwt (>= 5.2) http://sourceforge.net/projects/qwt/ -\li pyqt (>= 4.4) http://www.riverbankcomputing.co.uk/software/pyqt/download -\li pyqwt (>= 5.2) http://pyqwt.sourceforge.net/download.html - -\subsection dep_gr_wxgui gr-wxgui: The WX-based Graphical User Interface -\li wxpython (>= 2.8) http://www.wxpython.org/ -\li python-lxml (>= 1.3.6) http://lxml.de/ - -\subsection dep_gr_audio gr-audio: Audio Subsystems (system/OS dependent) -\li audio-alsa (>= 0.9) http://www.alsa-project.org -\li audio-jack (>= 0.8) http://jackaudio.org/ -\li portaudio (>= 19) http://www.portaudio.com/ -\li audio-oss (>= 1.0) http://www.opensound.com/oss.html -\li audio-osx -\li audio-windows - -It is not necessary to satisfy all of these dependencies; just the -one(s) that are right for your system. On Linux, don't expect -audio-osx and audio-windows to be either satisfied or built. - -\subsection dep_uhd uhd: The Ettus USRP Hardware Driver Interface -\li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki - -\subsection dep_gr_video_sdl gr-video-sdl: PAL and NTSC display -\li SDL (>= 1.2.0) http://www.libsdl.org/download-1.2.php - -\subsection dep_gr_comedi gr-comedi: Comedi hardware interface -\li comedilib (>= 0.8) http://www.comedi.org/ - -\subsection dep_gr_log gr-log: Logging Tools (Optional) -\li log4cpp (>= 1.0) http://log4cpp.sourceforge.net/ - - -\section build_gr_cmake Building GNU Radio - -GNU Radio is built using the Cmake build system -(http://www.cmake.org/). The standard build method is as follows: - -\code -$ mkdir $(builddir) -$ cd $(builddir) -$ cmake [OPTIONS] $(srcdir) -$ make -$ make test -$ sudo make install -\endcode - -The \$(builddir) is the directory in which the code is built. This -<b>cannot</b> be the same path as where the source code resides. Often, -\$(builddir) is \$(srcdir)/build. - -\subsection Cmake Options - -Options can be used to specify where to find various library or -include file dependencies that are not automatically being found -(-DCMAKE_PREFIX_PATH) or set the prefix -(-DCMAKE_INSTALL_PREFIX=(dir)). - -Components can also be enabled and disabled through the options. For a -component named *gr-comp*, the option to disable would look like: --DENABLE_GR_COMP=off. The "off" could also be "false" or "no", and -cmake is not case sensitive about these options. Similarly, "true", -"on", or "yes" will turn this component on. All components are enabled -by default. - -An example is -DENABLE_PYTHON=False turns off building any Python or -Swigging components. The result will be the GNU Radio libraries and -C++ programs/applications/examples. No Python or GRC files will be -built or installed. - -The -DENABLE_DEFAULT=False can be used to disable all -components. Individual components can then be selectively turned back -on. For example, just buidling the VOLK library can be -done with this: - -\code -cmake -DENABLE_DEFAULT=Off -DENABLE_VOLK=True <srcdir> -\endcode - - -The build type allows you to specify the build as a debug or release -version. Each type sets different flags for different purposes. To set -the build type, use: - -\code --DCMAKE_BUILD_TYPE="Release"|"Debug" -\endcode - -If not specified, the "Release" mode is the defaulted to. - -"Release" mode sets the '-O3' optimization flag. - -"Debug" mode sets '-g -O2' flags to export debug symbols and reduce -the optimization to make the libraries easier to debug and step -through. - - -\subsection build_gr_cmake_e100 Building for the E100 - -To build GNU Radio on the Ettus Research E100 embedded platforms, -Cmake has to know that the processors uses the NEON extensions. Use -the - -\code -cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ - -DCMAKE_C_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ - <gr_source_dir> -\endcode - -*/ - - - -/*! \page volk_guide Instructions for using VOLK in GNU Radio - -\section volk_intro Introduction - -VOLK is the Vector-Optimized Library of Kernels. It is a library that -contains kernels of hand-written SIMD code for different mathematical -operations. Since each SIMD architecture can be greatly different and -no compiler has yet come along to handle vectorization properly or -highly efficiently, VOLK approaches the problem differently. For each -architecture or platform that a developer wishes to vectorize for, a -new proto-kernel is added to VOLK. At runtime, VOLK will select the -correct proto-kernel. In this way, the users of VOLK call a kernel for -performing the operation that is platform/architecture agnostic. This -allows us to write portable SIMD code. - -VOLK kernels are always defined with a 'generic' proto-kernel, which -is written in plain C. With the generic kernel, the kernel becomes -portable to any platform. Kernels are then extended by adding -proto-kernels for new platforms in which they are desired. - -A good example of a VOLK kernel with multiple proto-kernels defined is -the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar -multiplication of a vector of floating point numbers (each item in the -vector is multiplied by the same value). This kernel has the following -proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'orc.' - -\code - void volk_32f_s32f_multiply_32f_a_generic - void volk_32f_s32f_multiply_32f_a_sse - void volk_32f_s32f_multiply_32f_a_avx - void volk_32f_s32f_multiply_32f_a_orc -\endcode - -These proto-kernels means that on platforms with AVX support, VOLK can -select this option or the SSE option, depending on which is faster. On -other platforms, the ORC SIMD compiler might provide a solution. If -all else fails, VOLK can fall back on the generic proto-kernel, which -will always work. - -Just a note on ORC. ORC is a SIMD compiler library that uses a generic -assembly-like language for SIMD commands. Based on the available SIMD -architecture of a system, it will try and compile a good -solution. Tests show that the results of ORC proto-kernels are -generally better than the generic versions but often not as good as -the hand-tuned proto-kernels for a specific SIMD architecture. This -is, of course, to be expected, and ORC provides a nice intermediary -step to performance improvements until a specific hand-tuned -proto-kernel can be made for a given platform. - -See <a -href="http://gnuradio.org/redmine/projects/gnuradio/wiki/Volk">VOLK on -gnuradio.org</a> for details on the VOLK naming scheme. - - -\section volk_alignment Setting and Using Memory Alignment Information - -For VOLK to work as best as possible, we want to use memory-aligned -SIMD calls, which means we have to have some way of knowing and -controlling the alignment of the buffers passed to gr_block's work -function. We set the alignment requirement for SIMD aligned memory -calls with: - -\code - const int alignment_multiple = - volk_get_alignment() / output_item_size; - set_alignment(std::max(1,alignment_multiple)); -\endcode - -The VOLK function 'volk_get_alignment' provides the alignment of the -the machine architecture. We then base the alignment on the number of -output items required to maintain the alignment, so we divide the -number of alignment bytes by the number of bytes in an output items -(sizeof(float), sizeof(gr_complex), etc.). This value is then set per -block with the 'set_alignment' function. - -Because the scheduler tries to optimize throughput, the number of -items available per call to work will change and depends on the -availability of the read and write buffers. This means that it -sometimes cannot produce a buffer that is properly memory -aligned. This is an inevitable consequence of the scheduler -system. Instead of requiring alignment, the scheduler enforces the -alignment as much as possible, and when a buffer becomes unaligned, -the scheduler will work to correct it as much as possible. If a -block's buffers are unaligned, then, the scheduler sets a flag to -indicate as much so that the block can then decide what best to -do. The next section discusses the use of the aligned/unaligned -information in a gr_block's work function. - - -\section volk_work Calling VOLK kernels in Work() - -The buffers passed to work/general_work in a gr_block are not -guaranteed to be aligned, but they will mostly be aligned whenever -possible. When not aligned, the 'is_unaligned()' flag will be set so -the scheduler knows to try to realign the buffers. We actually make -calls to the VOLK dispatcher, which is mainly designed to check the -buffer alignments and call the correct version of the kernel for -us. From the user-level view of VOLK, calling the dispatcher allows us -to ignore the concept of aligned versus unaligned. This looks like: - -\code -int -gr_some_block::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - // Call the dispatcher to check alignment and call the _a or _u - // version of the kernel. - volk_32f_something_32f(out, in, noutput_items); - - return noutput_items; -} -\endcode - - - -\section volk_tuning Tuning VOLK Performance - -VOLK comes with a profiler that will build a config file for the best -SIMD architecture for your processor. Run volk_profile that is -installed into $PREFIX/bin. This program tests all known VOLK kernels -for each architecture supported by the processor. When finished, it -will write to $HOME/.volk/volk_config the best architecture for the -VOLK function. This file is read when using a function to know the -best version of the function to execute. - -\subsection volk_hand_tuning Hand-Tuning Performance - -If you know a particular architecture works best for your processor, -you can specify the particular architecture to use in the VOLK -preferences file: $HOME/.volk/volk_config - -The file looks like: - -\code - volk_<FUNCTION_NAME> <ARCHITECTURE> -\endcode - -Where the "FUNCTION_NAME" is the particular function that you want to -over-ride the default value and "ARCHITECTURE" is the VOLK SIMD -architecture to use (generic, sse, sse2, sse3, avx, etc.). For -example, the following config file tells VOLK to use SSE3 for the -aligned and unaligned versions of a function that multiplies two -complex streams together. - -\code - volk_32fc_x2_multiply_32fc_a sse3 - volk_32fc_x2_multiply_32fc_u sse3 -\endcode - -\b Tip: if benchmarking GNU Radio blocks, it can be useful to have a -volk_config file that sets all architectures to 'generic' as a way to -test the vectorized versus non-vectorized implementations. - -*/ diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 62ea8a9929..67487ddfd6 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -4,505 +4,22 @@ Welcome to GNU Radio! -For details about GNU Radio and using it, please see the <a -href="http://gnuradio.org" target="_blank"><b>main project page</b></a>. +For details about GNU Radio and using it, please see the +<a href="http://gnuradio.org" target="_blank"><b>main project page</b></a>. Other information about the project and discussion about GNU Radio, software radio, and communication theory in general can be found at the <a href="http://www.trondeau.com" target="_blank"><b>GNU Radio blog</b></a>. +This manual is split into two parts: A usage manual and a reference. The usage manual +deals with concepts of GNU Radio, introductions, how to build GNU Radio etc. +The reference contains a list of all GNU Radio components, sorted by in-tree components, +modules, files, namespaces and classes. -\section build Building GNU Radio +To access these parts, follow these links or use the tree browser in the left sidebar. +A search function is also available at the top right. -See the \ref build_guide page for details about the project's -dependencies and build process. - -Once built, look on <a href="http://gnuradio.org" target="_blank">gnuradio.org</a> for -tutorials on using the software system and see \ref -page_exploring_gnuradio for a few simple examples exploring GNU Radio. - - -\section blocks GNU Radio Blocks - -GNU Radio uses discrete signal processing blocks that are connected -together to perform your signal processing application. This manual -contain a list of all GNU Radio <a href="modules.html"><b>C++ Blocks</b></a>. - -Please note that at this time, we haven't found an acceptable way to -provide unified documentation for the C++ parts of the system and the -parts written in Python (mostly hierarchical blocks). Until this gets -worked out, please bear with us, or better yet, solve it for us! - - -\section toc Manual Contents -More details on packages in GNU Radio: -\li \ref page_audio -\li \ref page_digital -\li \ref page_qtgui -\li \ref page_uhd -\li \ref page_vocoder - -More details on GNU Radio concepts: -\li \ref page_logger -\li \ref page_pmt -\li \ref page_msg_passing -\li \ref page_stream_tags -\li \ref page_metadata -\li \ref volk_guide -\li \ref page_perf_counters -\li \ref page_pfb -\li \ref page_affinity -\li \ref page_tagged_stream_blocks -\li \ref page_ofdm -\li \ref page_packet_data - - -\section flowgraph Operating a Flowgraph - -The basic data structure in GNU Radio is the flowgraph, which -represents the connections of the blocks through which a continuous -stream of samples flows. The concept of a flowgraph is an acyclic -directional graph with one or more source blocks (to insert samples -into the flowgraph), one or more sink blocks (to terminate or export -samples from the flowgraph), and any signal processing blocks in -between. - -A program must at least create a GNU Radio 'top_block', which -represents the top-most structure of the flowgraph. The top blocks -provide the overall control and hold methods such as 'start,' 'stop,' -and 'wait.' - -The general construction of a GNU Radio application is to create a -gr_top_block, instantiate the blocks, connect the blocks together, and -then start the gr_top_block. The following program shows how this is -done. A single source and sink are used with a FIR filter between -them. - -\code - from gnuradio import gr, blocks, filter, analog - - class my_topblock(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - amp = 1 - taps = filter.firdes.low_pass(1, 1, 0.1, 0.01) - - self.src = analog.noise_source_c(analog.GR_GAUSSIAN, amp) - self.flt = filter.fir_filter_ccf(1, taps) - self.snk = blocks.null_sink(gr.sizeof_gr_complex) - - self.connect(self.src, self.flt, self.snk) - - if __name__ == "__main__": - tb = my_topblock() - tb.start() - tb.wait() -\endcode - -The 'tb.start()' starts the data flowing through the flowgraph while -the 'tb.wait()' is the equivalent of a thread's 'join' operation and -blocks until the gr_top_block is done. - -An alternative to using the 'start' and 'wait' methods, a 'run' method is -also provided for convenience that is a blocking start call; -equivalent to the above 'start' followed by a 'wait.' - - -\subsection latency Latency and Throughput - -By default, GNU Radio runs a scheduler that attempts to optimize -throughput. Using a dynamic scheduler, blocks in a flowgraph pass -chunks of items from sources to sinks. The sizes of these chunks will -vary depending on the speed of processing. For each block, the number -of items is can process is dependent on how much space it has in its -output buffer(s) and how many items are available on the input -buffer(s). - -The consequence of this is that often a block may be called with a very -large number of items to process (several thousand). In terms of -speed, this is efficient since now the majority of the processing time -is taken up with processing samples. Smaller chunks mean more calls -into the scheduler to retrieve more data. The downside to this is that -it can lead to large latency while a block is processing a large chunk -of data. - -To combat this problem, the gr_top_block can be passed a limit on the -number of output items a block will ever receive. A block may get less -than this number, but never more, and so it serves as an upper limit -to the latency any block will exhibit. By limiting the number of items -per call to a block, though, we increase the overhead of the -scheduler, and so reduce the overall efficiency of the application. - -To set the maximum number of output items, we pass a value into the -'start' or 'run' method of the gr_top_block: - -\code - tb.start(1000) - tb.wait() -or - tb.run(1000) -\endcode - -Using this method, we place a global restriction on the size of items -to all blocks. Each block, though, has the ability to overwrite this -with its own limit. Using the 'set_max_noutput_items(m)' method for an -individual block will overwrite the global setting. For example, in -the following code, the global setting is 1000 items max, except for -the FIR filter, which can receive up to 2000 items. - -\code - tb.flt.set_max_noutput_items(2000) - tb.run(1000) -\endcode - -In some situations, you might actually want to restrict the size of -the buffer itself. This can help to prevent a buffer who is blocked -for data from just increasing the amount of items in its buffer, which -will then cause an increased latency for new samples. You can set the -size of an output buffer for each output port for every block. - -WARNING: This is an advanced feature in GNU Radio and should not be -used without a full understanding of this concept as explained below. - -To set the output buffer size of a block, you simply call: - -\code - tb.blk0.set_max_output_buffer(2000) - tb.blk1.set_max_output_buffer(1, 2000) - tb.start() - print tb.blk1.max_output_buffer(0) - print tb.blk1.max_output_buffer(1) -\endcode - -In the above example, all ports of blk0 are set to a buffer size of -2000 in _items_ (not bytes), and blk1 only sets the size for output -port 1, any and all other ports use the default. The third and fourth -lines just print out the buffer sizes for ports 0 and 1 of blk1. This -is done after start() is called because the values are updated based -on what is actually allocated to the block's buffers. - -NOTES: - -1. Buffer length assignment is done once at runtime (i.e., when run() -or start() is called). So to set the max buffer lengths, the -set_max_output_buffer calls must be done before this. - -2. Once the flowgraph is started, the buffer lengths for a block are -set and cannot be dynamically changed, even during a -lock()/unlock(). If you need to change the buffer size, you will have -to delete the block and rebuild it, and therefore must disconnect and -reconnect the blocks. - -3. This can affect throughput. Large buffers are designed to improve -the efficiency and speed of the program at the expense of -latency. Limiting the size of the buffer may decrease performance. - -4. The real buffer size is actually based on a minimum granularity of -the system. Typically, this is a page size, which is typically 4096 -bytes. This means that any buffer size that is specified with this -command will get rounded up to the nearest granularity (e.g., page) -size. When calling max_output_buffer(port) after the flowgraph is -started, you will get how many items were actually allocated in the -buffer, which may be different than what was initially specified. - - -\section reconfigure Reconfiguring Flowgraphs - -It is possible to reconfigure the flowgraph at runtime. The -reconfiguration is meant for changes in the flowgraph structure, not -individual parameter settings of the blocks. For example, changing the -constant in a gr::blocks::add_const_cc block can be done while the flowgraph is -running using the 'set_k(k)' method. - -Reconfiguration is done by locking the flowgraph, which stops it from -running and processing data, performing the reconfiguration, and then -restarting the graph by unlocking it. - -The following example code shows a graph that first adds two -gr::analog::noise_source_c blocks and then replaces the -gr::blocks::add_cc block with a gr::blocks::sub_cc block to then -subtract the sources. - -\code -from gnuradio import gr, analog, blocks -import time - -class mytb(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - self.src0 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) - self.src1 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) - self.add = blocks.add_cc() - self.sub = blocks.sub_cc() - self.head = blocks.head(gr.sizeof_gr_complex, 1000000) - self.snk = blocks.file_sink(gr.sizeof_gr_complex, "output.32fc") - - self.connect(self.src0, (self.add,0)) - self.connect(self.src1, (self.add,1)) - self.connect(self.add, self.head) - self.connect(self.head, self.snk) - -def main(): - tb = mytb() - tb.start() - time.sleep(0.01) - - # Stop flowgraph and disconnect the add block - tb.lock() - tb.disconnect(tb.add, tb.head) - tb.disconnect(tb.src0, (tb.add,0)) - tb.disconnect(tb.src1, (tb.add,1)) - - # Connect the sub block and restart - tb.connect(tb.sub, tb.head) - tb.connect(tb.src0, (tb.sub,0)) - tb.connect(tb.src1, (tb.sub,1)) - tb.unlock() - - tb.wait() - -if __name__ == "__main__": - main() -\endcode - -During reconfiguration, the maximum noutput_items value can be changed -either globally using the 'set_max_noutput_items(m)' on the gr_top_block -object or locally using the 'set_max_noutput_items(m)' on any given -block object. - -A block also has a 'unset_max_noutput_items()' method that unsets the -local max noutput_items value so that block reverts back to using the -global value. - -The following example expands the previous example but sets and resets -the max noutput_items both locally and globally. - -\code -from gnuradio import gr, analog, blocks -import time - -class mytb(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - self.src0 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) - self.src1 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) - self.add = blocks.add_cc() - self.sub = blocks.sub_cc() - self.head = blocks.head(gr.sizeof_gr_complex, 1000000) - self.snk = blocks.file_sink(gr.sizeof_gr_complex, "output.32fc") - - self.connect(self.src0, (self.add,0)) - self.connect(self.src1, (self.add,1)) - self.connect(self.add, self.head) - self.connect(self.head, self.snk) - -def main(): - # Start the gr_top_block after setting some max noutput_items. - tb = mytb() - tb.src1.set_max_noutput_items(2000) - tb.start(100) - time.sleep(0.01) - - # Stop flowgraph and disconnect the add block - tb.lock() - - tb.disconnect(tb.add, tb.head) - tb.disconnect(tb.src0, (tb.add,0)) - tb.disconnect(tb.src1, (tb.add,1)) - - # Connect the sub block - tb.connect(tb.sub, tb.head) - tb.connect(tb.src0, (tb.sub,0)) - tb.connect(tb.src1, (tb.sub,1)) - - # Set new max_noutput_items for the gr_top_block - # and unset the local value for src1 - tb.set_max_noutput_items(1000) - tb.src1.unset_max_noutput_items() - tb.unlock() - - tb.wait() - -if __name__ == "__main__": - main() -\endcode - - -\section volk_main Using Volk in GNU Radio - -The \ref volk_guide page provides an overview of how to incorporate -and use Volk in GNU Radio blocks. - -Many blocks have already been converted to use Volk in their calls, so -they can also serve as examples. See the -gr::blocks::complex_to_<type>.h files for examples of various blocks -that make use of Volk. - - -\section prefs Configuration / Preference Files - -GNU Radio defines some of its basic behavior through a set of -configuration files located in -${prefix}/etc/gnuradio/conf.d. Different components have different -files listed in here for the various properties. These will be read -once when starting a GNU Radio application, so updates during runtime -will not affect them. - -The configuration files use the following format: - -\code -# Stuff from section 1 -[section1] -var1 = value1 -var2 = value2 # value of 2 - -# Stuff from section 2 -[section2] -var3 = value3 -\endcode - -In this file, the hash mark ('#') indicates a comment and blank lines -are ignored. Section labels are defined inside square brackets as a -group distinguisher. All options must be associated with a section -name. The options are listed one per line with the option name is -given followed by an equals ('=') sign and then the value. - -All section and option names must not have white spaces. If a value -must have white space, the it MUST be put inside quotes. Any quoted -value will have its white space preserved and the quotes internally -will be stripped. As an example, on Apple desktops, an output device -of "Display Audio" is a possible output device and can be set as: - -\code -[audio_osx] -default_output_device = "Display Audio" -\endcode - -The result will pass Display Audio to the audio setup. - -The value of an option can be a string or number and retrieved through -a few different interfaces. There is a single preference object -created when GNU Radio is launched. In Python, you can get this by -making a new variable: - -\code -p = gr.prefs() -\endcode - -Similarly, in C++, we get a reference to the object by explicitly -calling for the singleton of the object: - -\code - prefs *p = prefs::singleton(); -\endcode - -The methods associated with this preferences object are (from class gr::prefs): - -\code - bool has_section(string section) - bool has_option(string section, string option) - string get_string(string section, string option, string default_val) - bool get_bool(string section, string option, bool default_val) - long get_long(string section, string option, long default_val) - double get_double(string section, string option, double default_val) -\endcode - -When setting a Boolean value, we can use 0, 1, "True", "true", -"False", "false", "On", "on", "Off", and "off". - -All configuration preferences in these files can also be overloaded by -an environmental variable. The environmental variable is named based -on the section and option name from the configuration file as: - -\code - GR_CONF_<SECTION>_<OPTION> = <value> -\endcode - -The "GR_CONF_" is a prefix to identify this as a GNU Radio -configuration variable and the section and option names are in -uppercase. The value is the same format that would be used in the -config file itself. - - - -\section oot_config_page Out-of-Tree Configuration - -New as of 3.6.5. - -Using gr_modtool, each package comes with the ability to easily locate -the gnuradio-runtime library using the 'find_package(GnuradioRuntime)' -cmake command. This only locates the gnuradio-runtime library and -include directory, which is enough for most simple projects. - -As projects become more complicated and start needing to rely on other -GNU Radio components like gnuradio-blocks or gnuradio-filter, for -example, and when they become dependent on certain API compatibility -versions of GNU Radio, we need something more. And so we have -introduced the GnuradioConfig.cmake file. - -When GNU Radio is installed, it also installs a GNU Radio-specific -cmake config file that we can use for more advanced compatibility -issues of our projects. This tool allows us to specific the API -compatible version and a set of components that are required. - -Taking the above example, say we have built against version 3.6.5 with -features that were introduced in this version and we need the blocks -and filter components as well as the main core library. We fist set a -cmake variable GR_REQUIRED_COMPONENTS to the components we need. We -then use the 'find_package' command and also set a minimum required -API compatible version. Since we are on the 3.6 API version, the -minimum required version is "3.6.5". The code in the CMakeLists.txt -file would look like this: - -\code - set(GR_REQUIRED_COMPONENTS RUNTIME BLOCKS FILTER) - find_package(Gnuradio 3.6.5) -\endcode - -Note that the capitalization is important on both lines. - -If the installed version of GNU Radio is 3.6.4 or some other API -version like 3.5 or 3.7, the Cmake configuration will fail with the -version error. Likewise, if libgnuradio-filter was not installed as -part of GNU Radio, the configuration will also fail. - -\subsection oot_config_path_page Install Path - -Cmake has to know where to find either the package config files or the -GnuradioConfig.cmake script. The package config files are located in -$prefix/lib/pkgconfig while all of the Cmake scripts from GNU Radio -are installed into $prefix/lib/cmake/gnuradio. - -If the installed GNU Radio $prefix is '/usr' or '/usr/local', then -everything should work fine. If the GNU Radio install $prefix is -something else, then Cmake must be told where to find it. This can be -done in a few ways: - -1. If you are installing the out-of-tree module into the same $prefix, -then you would be setting '-DCMAKE_INSTALL_PREFIX' on the -configuration command line. This is enough to tell Cmake where to look -for the configuration files. - -2. Cmake will try to find the package config (*.pc) files. If it can, -these files will instruct Cmake where to look for the rest of the -configuration options. If this is not set, it can be set as: - -\code - export PKG_CONFIG_PATH=$prefix/lib/pkgconfg:$PKG_CONFIG_PATH -\endcode - -3. Set the CMAKE_PREFIX_PATH environmental variable to $prefix. - -\code - export CMAKE_PREFIX_PATH=$prefix:$CMAKE_PREFIX_PATH -\endcode - - -With method 1, you will be installing your OOT project into the same -$prefix as GNU Radio. With methods 2 and 3, you can install your -component anywhere you like (using -DCMAKE_INSTALL_PREFIX). +\li \subpage page_usage "Part I - GNU Radio Usage" +\li \subpage page_components "Part II - Reference" */ diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox index 03ebe591e4..e29adf306e 100644 --- a/docs/doxygen/other/metadata.dox +++ b/docs/doxygen/other/metadata.dox @@ -20,7 +20,20 @@ about the item size, data type, if it's complex, the sample rate of the segment, the time stamp of the first sample of the segment, and information regarding the header size and segment size. -Headers have two main tags associated with them: +The first static portion of the header file contains the following +information. + +- version: (char) version number (usually set to METADATA_VERSION) +- rx_rate: (double) Stream's sample rate +- rx_time: (pmt::pmt_t pair - (uint64_t, double)) Time stamp (format from UHD) +- size: (int) item size in bytes - reflects vector length if any. +- type: (int) data type (enum below) +- cplx: (bool) true if data is complex +- strt: (uint64_t) start of data relative to current header +- bytes: (uint64_t) size of following data segment in bytes + +An optional extra section of the header stores information in any +received tags. The two main tags associated with tags are: - rx_rate: the sample rate of the stream. - rx_time: the time stamp of the first item in the segment. diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox index 11abf35728..882252bee2 100644 --- a/docs/doxygen/other/msg_passing.dox +++ b/docs/doxygen/other/msg_passing.dox @@ -145,6 +145,11 @@ function. When a new message is pushed onto a port's message queue, it is this function that is used to process the message. +\section python_msg_passing Message Passing in Python Blocks + +ADD STUFF HERE + + \section examples Code Examples The following is snippets of code from blocks current in GNU Radio diff --git a/docs/doxygen/other/oot_config.dox b/docs/doxygen/other/oot_config.dox new file mode 100644 index 0000000000..bb441c5060 --- /dev/null +++ b/docs/doxygen/other/oot_config.dox @@ -0,0 +1,78 @@ +/*! \page page_oot_config Out-of-Tree Configuration + +New as of 3.6.5. + +Using gr_modtool, each package comes with the ability to easily locate +the gnuradio-runtime library using the 'find_package(GnuradioRuntime)' +cmake command. This only locates the gnuradio-runtime library and +include directory, which is enough for most simple projects. + +As projects become more complicated and start needing to rely on other +GNU Radio components like gnuradio-blocks or gnuradio-filter, for +example, and when they become dependent on certain API compatibility +versions of GNU Radio, we need something more. And so we have +introduced the GnuradioConfig.cmake file. + +When GNU Radio is installed, it also installs a GNU Radio-specific +cmake config file that we can use for more advanced compatibility +issues of our projects. This tool allows us to specific the API +compatible version and a set of components that are required. + +Taking the above example, say we have built against version 3.6.5 with +features that were introduced in this version and we need the blocks +and filter components as well as the main core library. We fist set a +cmake variable GR_REQUIRED_COMPONENTS to the components we need. We +then use the 'find_package' command and also set a minimum required +API compatible version. Since we are on the 3.6 API version, the +minimum required version is "3.6.5". The code in the CMakeLists.txt +file would look like this: + +\code + set(GR_REQUIRED_COMPONENTS RUNTIME BLOCKS FILTER) + find_package(Gnuradio 3.6.5) +\endcode + +Note that the capitalization is important on both lines. + +If the installed version of GNU Radio is 3.6.4 or some other API +version like 3.5 or 3.7, the Cmake configuration will fail with the +version error. Likewise, if libgnuradio-filter was not installed as +part of GNU Radio, the configuration will also fail. + +\section oot_config_path_page Install Path + +Cmake has to know where to find either the package config files or the +GnuradioConfig.cmake script. The package config files are located in +$prefix/lib/pkgconfig while all of the Cmake scripts from GNU Radio +are installed into $prefix/lib/cmake/gnuradio. + +If the installed GNU Radio $prefix is '/usr' or '/usr/local', then +everything should work fine. If the GNU Radio install $prefix is +something else, then Cmake must be told where to find it. This can be +done in a few ways: + +1. If you are installing the out-of-tree module into the same $prefix, +then you would be setting '-DCMAKE_INSTALL_PREFIX' on the +configuration command line. This is enough to tell Cmake where to look +for the configuration files. + +2. Cmake will try to find the package config (*.pc) files. If it can, +these files will instruct Cmake where to look for the rest of the +configuration options. If this is not set, it can be set as: + +\code + export PKG_CONFIG_PATH=$prefix/lib/pkgconfg:$PKG_CONFIG_PATH +\endcode + +3. Set the CMAKE_PREFIX_PATH environmental variable to $prefix. + +\code + export CMAKE_PREFIX_PATH=$prefix:$CMAKE_PREFIX_PATH +\endcode + + +With method 1, you will be installing your OOT project into the same +$prefix as GNU Radio. With methods 2 and 3, you can install your +component anywhere you like (using -DCMAKE_INSTALL_PREFIX). + +*/ diff --git a/docs/doxygen/other/operating_fg.dox b/docs/doxygen/other/operating_fg.dox new file mode 100644 index 0000000000..b075ca648a --- /dev/null +++ b/docs/doxygen/other/operating_fg.dox @@ -0,0 +1,278 @@ +/*! \page page_operating_fg Handling flow graphs + +\section flowgraph Operating a Flowgraph + +The basic data structure in GNU Radio is the flowgraph, which +represents the connections of the blocks through which a continuous +stream of samples flows. The concept of a flowgraph is an acyclic +directional graph with one or more source blocks (to insert samples +into the flowgraph), one or more sink blocks (to terminate or export +samples from the flowgraph), and any signal processing blocks in +between. + +A program must at least create a GNU Radio 'top_block', which +represents the top-most structure of the flowgraph. The top blocks +provide the overall control and hold methods such as 'start,' 'stop,' +and 'wait.' + +The general construction of a GNU Radio application is to create a +gr_top_block, instantiate the blocks, connect the blocks together, and +then start the gr_top_block. The following program shows how this is +done. A single source and sink are used with a FIR filter between +them. + +\code + from gnuradio import gr, blocks, filter, analog + + class my_topblock(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + amp = 1 + taps = filter.firdes.low_pass(1, 1, 0.1, 0.01) + + self.src = analog.noise_source_c(analog.GR_GAUSSIAN, amp) + self.flt = filter.fir_filter_ccf(1, taps) + self.snk = blocks.null_sink(gr.sizeof_gr_complex) + + self.connect(self.src, self.flt, self.snk) + + if __name__ == "__main__": + tb = my_topblock() + tb.start() + tb.wait() +\endcode + +The 'tb.start()' starts the data flowing through the flowgraph while +the 'tb.wait()' is the equivalent of a thread's 'join' operation and +blocks until the gr_top_block is done. + +An alternative to using the 'start' and 'wait' methods, a 'run' method is +also provided for convenience that is a blocking start call; +equivalent to the above 'start' followed by a 'wait.' + + +\subsection latency Latency and Throughput + +By default, GNU Radio runs a scheduler that attempts to optimize +throughput. Using a dynamic scheduler, blocks in a flowgraph pass +chunks of items from sources to sinks. The sizes of these chunks will +vary depending on the speed of processing. For each block, the number +of items is can process is dependent on how much space it has in its +output buffer(s) and how many items are available on the input +buffer(s). + +The consequence of this is that often a block may be called with a very +large number of items to process (several thousand). In terms of +speed, this is efficient since now the majority of the processing time +is taken up with processing samples. Smaller chunks mean more calls +into the scheduler to retrieve more data. The downside to this is that +it can lead to large latency while a block is processing a large chunk +of data. + +To combat this problem, the gr_top_block can be passed a limit on the +number of output items a block will ever receive. A block may get less +than this number, but never more, and so it serves as an upper limit +to the latency any block will exhibit. By limiting the number of items +per call to a block, though, we increase the overhead of the +scheduler, and so reduce the overall efficiency of the application. + +To set the maximum number of output items, we pass a value into the +'start' or 'run' method of the gr_top_block: + +\code + tb.start(1000) + tb.wait() +or + tb.run(1000) +\endcode + +Using this method, we place a global restriction on the size of items +to all blocks. Each block, though, has the ability to overwrite this +with its own limit. Using the 'set_max_noutput_items(m)' method for an +individual block will overwrite the global setting. For example, in +the following code, the global setting is 1000 items max, except for +the FIR filter, which can receive up to 2000 items. + +\code + tb.flt.set_max_noutput_items(2000) + tb.run(1000) +\endcode + +In some situations, you might actually want to restrict the size of +the buffer itself. This can help to prevent a buffer who is blocked +for data from just increasing the amount of items in its buffer, which +will then cause an increased latency for new samples. You can set the +size of an output buffer for each output port for every block. + +WARNING: This is an advanced feature in GNU Radio and should not be +used without a full understanding of this concept as explained below. + +To set the output buffer size of a block, you simply call: + +\code + tb.blk0.set_max_output_buffer(2000) + tb.blk1.set_max_output_buffer(1, 2000) + tb.start() + print tb.blk1.max_output_buffer(0) + print tb.blk1.max_output_buffer(1) +\endcode + +In the above example, all ports of blk0 are set to a buffer size of +2000 in _items_ (not bytes), and blk1 only sets the size for output +port 1, any and all other ports use the default. The third and fourth +lines just print out the buffer sizes for ports 0 and 1 of blk1. This +is done after start() is called because the values are updated based +on what is actually allocated to the block's buffers. + +NOTES: + +1. Buffer length assignment is done once at runtime (i.e., when run() +or start() is called). So to set the max buffer lengths, the +set_max_output_buffer calls must be done before this. + +2. Once the flowgraph is started, the buffer lengths for a block are +set and cannot be dynamically changed, even during a +lock()/unlock(). If you need to change the buffer size, you will have +to delete the block and rebuild it, and therefore must disconnect and +reconnect the blocks. + +3. This can affect throughput. Large buffers are designed to improve +the efficiency and speed of the program at the expense of +latency. Limiting the size of the buffer may decrease performance. + +4. The real buffer size is actually based on a minimum granularity of +the system. Typically, this is a page size, which is typically 4096 +bytes. This means that any buffer size that is specified with this +command will get rounded up to the nearest granularity (e.g., page) +size. When calling max_output_buffer(port) after the flowgraph is +started, you will get how many items were actually allocated in the +buffer, which may be different than what was initially specified. + + +\section reconfigure Reconfiguring Flowgraphs + +It is possible to reconfigure the flowgraph at runtime. The +reconfiguration is meant for changes in the flowgraph structure, not +individual parameter settings of the blocks. For example, changing the +constant in a gr::blocks::add_const_cc block can be done while the flowgraph is +running using the 'set_k(k)' method. + +Reconfiguration is done by locking the flowgraph, which stops it from +running and processing data, performing the reconfiguration, and then +restarting the graph by unlocking it. + +The following example code shows a graph that first adds two +gr::analog::noise_source_c blocks and then replaces the +gr::blocks::add_cc block with a gr::blocks::sub_cc block to then +subtract the sources. + +\code +from gnuradio import gr, analog, blocks +import time + +class mytb(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + self.src0 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) + self.src1 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) + self.add = blocks.add_cc() + self.sub = blocks.sub_cc() + self.head = blocks.head(gr.sizeof_gr_complex, 1000000) + self.snk = blocks.file_sink(gr.sizeof_gr_complex, "output.32fc") + + self.connect(self.src0, (self.add,0)) + self.connect(self.src1, (self.add,1)) + self.connect(self.add, self.head) + self.connect(self.head, self.snk) + +def main(): + tb = mytb() + tb.start() + time.sleep(0.01) + + # Stop flowgraph and disconnect the add block + tb.lock() + tb.disconnect(tb.add, tb.head) + tb.disconnect(tb.src0, (tb.add,0)) + tb.disconnect(tb.src1, (tb.add,1)) + + # Connect the sub block and restart + tb.connect(tb.sub, tb.head) + tb.connect(tb.src0, (tb.sub,0)) + tb.connect(tb.src1, (tb.sub,1)) + tb.unlock() + + tb.wait() + +if __name__ == "__main__": + main() +\endcode + +During reconfiguration, the maximum noutput_items value can be changed +either globally using the 'set_max_noutput_items(m)' on the gr_top_block +object or locally using the 'set_max_noutput_items(m)' on any given +block object. + +A block also has a 'unset_max_noutput_items()' method that unsets the +local max noutput_items value so that block reverts back to using the +global value. + +The following example expands the previous example but sets and resets +the max noutput_items both locally and globally. + +\code +from gnuradio import gr, analog, blocks +import time + +class mytb(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + self.src0 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) + self.src1 = analog.noise_source_c(analog.GR_GAUSSIAN, 1) + self.add = blocks.add_cc() + self.sub = blocks.sub_cc() + self.head = blocks.head(gr.sizeof_gr_complex, 1000000) + self.snk = blocks.file_sink(gr.sizeof_gr_complex, "output.32fc") + + self.connect(self.src0, (self.add,0)) + self.connect(self.src1, (self.add,1)) + self.connect(self.add, self.head) + self.connect(self.head, self.snk) + +def main(): + # Start the gr_top_block after setting some max noutput_items. + tb = mytb() + tb.src1.set_max_noutput_items(2000) + tb.start(100) + time.sleep(0.01) + + # Stop flowgraph and disconnect the add block + tb.lock() + + tb.disconnect(tb.add, tb.head) + tb.disconnect(tb.src0, (tb.add,0)) + tb.disconnect(tb.src1, (tb.add,1)) + + # Connect the sub block + tb.connect(tb.sub, tb.head) + tb.connect(tb.src0, (tb.sub,0)) + tb.connect(tb.src1, (tb.sub,1)) + + # Set new max_noutput_items for the gr_top_block + # and unset the local value for src1 + tb.set_max_noutput_items(1000) + tb.src1.unset_max_noutput_items() + tb.unlock() + + tb.wait() + +if __name__ == "__main__": + main() +\endcode + + +*/ + diff --git a/docs/doxygen/other/prefs.dox b/docs/doxygen/other/prefs.dox new file mode 100644 index 0000000000..46f68c447e --- /dev/null +++ b/docs/doxygen/other/prefs.dox @@ -0,0 +1,87 @@ +/*! \page page_prefs Configuration files + +\section prefs Configuration / Preference Files + +GNU Radio defines some of its basic behavior through a set of +configuration files located in +${prefix}/etc/gnuradio/conf.d. Different components have different +files listed in here for the various properties. These will be read +once when starting a GNU Radio application, so updates during runtime +will not affect them. + +The configuration files use the following format: + +\code +# Stuff from section 1 +[section1] +var1 = value1 +var2 = value2 # value of 2 + +# Stuff from section 2 +[section2] +var3 = value3 +\endcode + +In this file, the hash mark ('#') indicates a comment and blank lines +are ignored. Section labels are defined inside square brackets as a +group distinguisher. All options must be associated with a section +name. The options are listed one per line with the option name is +given followed by an equals ('=') sign and then the value. + +All section and option names must not have white spaces. If a value +must have white space, the it MUST be put inside quotes. Any quoted +value will have its white space preserved and the quotes internally +will be stripped. As an example, on Apple desktops, an output device +of "Display Audio" is a possible output device and can be set as: + +\code +[audio_osx] +default_output_device = "Display Audio" +\endcode + +The result will pass Display Audio to the audio setup. + +The value of an option can be a string or number and retrieved through +a few different interfaces. There is a single preference object +created when GNU Radio is launched. In Python, you can get this by +making a new variable: + +\code +p = gr.prefs() +\endcode + +Similarly, in C++, we get a reference to the object by explicitly +calling for the singleton of the object: + +\code + prefs *p = prefs::singleton(); +\endcode + +The methods associated with this preferences object are (from class gr::prefs): + +\code + bool has_section(string section) + bool has_option(string section, string option) + string get_string(string section, string option, string default_val) + bool get_bool(string section, string option, bool default_val) + long get_long(string section, string option, long default_val) + double get_double(string section, string option, double default_val) +\endcode + +When setting a Boolean value, we can use 0, 1, "True", "true", +"False", "false", "On", "on", "Off", and "off". + +All configuration preferences in these files can also be overloaded by +an environmental variable. The environmental variable is named based +on the section and option name from the configuration file as: + +\code + GR_CONF_<SECTION>_<OPTION> = <value> +\endcode + +The "GR_CONF_" is a prefix to identify this as a GNU Radio +configuration variable and the section and option names are in +uppercase. The value is the same format that would be used in the +config file itself. + +*/ diff --git a/docs/doxygen/other/python_blocks.dox b/docs/doxygen/other/python_blocks.dox new file mode 100644 index 0000000000..811eb84b68 --- /dev/null +++ b/docs/doxygen/other/python_blocks.dox @@ -0,0 +1,154 @@ +/*! \page page_python_blocks Python Blocks + +How to create blocks in Python + +\subsection pyblocks_streaming Streaming Data Blocks + +We create blocks in Python very much like we would in C++, just with +more Python. Figure out which type of block you want to create: + +\li general block (gr.basic_block) +\li synchronous block (gr.sync_block) +\li decimator (gr.sync_decimator) +\li interpolator (gr.sync_interpolator) + +The block class inherits from one of these base classes, and then in +defining the parent class, we set the I/O signature. However, unlike +in C++ where we use the gr::io_signature class, here we can just +create a Python list of the I/O data sizes using numpy data types: + +\li numpy.int8 +\li numpy.int16 +\li numpy.int32 +\li numpy.float32 +\li numpy.float64 + +Like a normal C++ version of the block, we then create and initialize +any variables in the constructor, define any setters and getters, and +create the work function. The prototype for the work function is quite +simple: + +\code +def work(self, input_items, output_items) +\endcode + +The input_items and output_items are lists of lists. The input_items +contains a vector of input samples for every input stream, and the +output_items is a vector for each output stream where we can place +items. Then length of output_items[0] is equivalent to the +noutput_items concept we are so familiar with from the C++ blocks. + +Following is an example Python block that adds two input streams +together. This block is used in the qa_block_gateway.py test code. + +\code +class add_2_f32_1_f32(gr.sync_block): + def __init__(self): + gr.sync_block.__init__( + self, + name = "add 2 f32", + in_sig = [numpy.float32, numpy.float32], + out_sig = [numpy.float32], + ) + + def work(self, input_items, output_items): + output_items[0][:] = input_items[0] + input_items[1] + return len(output_items[0]) +\endcode + +The block defines two input floating point streams by setting in_sig +to "[numpy.float32, numpy.float32]" and a single output float stream +in out_sig of "[numpy.float32]." + +The work function then just adds the two input streams together. The +streams are input_items[0] and input_items[1]. The block still returns +the concept of noutput_items like we use in C++, only we get it here +by getting len(output_items[0]). Because this is a sync_block, we also +know that the size of the input_items for both streams is the same as +the size of the output_items vector. + + + +\subsection pyblocks_tags Using Stream Tags + +Python blocks have access to the stream tag system like their C++ +counterparts. The interface is almost identical except they behave +just a bit more like we would expect in Python. + +To add tags to the data stream, we use the add_item_tag function: + +\code +def work(self, input_items, output_items): + .... + add_item_tag(which_output, abs_offset, + key, value, srcid) + .... +\endcode + +The abs_offset is an integer of the sample that the tag is attached +to, and key and value are both PMTs to set the key:value pair of the +tag information, and the srcid is an optional PMT to define the source +of the block that generate the tag. + +We then can get tags using either the get_tags_in_range or +get_tags_in_window. Again, like their C++ counter parts, the +get_tags_in_range uses the absolute item offset numbering (using +nitems_read) while the get_tags_in_window uses relative offsets within +the current window of items available to the work function. The main +difference from the C++ function is that instead of having the first +argument be a vector where the tags are stored, the Python version +just returns a list of tags. We would use it like this: + +\code +def work(self, input_items, output_items): + .... + tags = get_tags_in_window(which_input, rel_start, rel_end) + .... +\endcode + + + +\subsection pyblocks_msgs Using Message Passing + +Again, like their C++ counterparts, Python blocks can use the +asynchronous message passing interface. We define output message +handlers using: + +\code +self.message_port_register_out(pmt.intern("<port name>")) +\endcode + +We can then post messages to this using the message_port_pub function: + +\code +self.message_port_pub(pmt.intern("<port name>"), <pmt message>) +\endcode + +We then register input messages and handlers in similar ways: + +\code +self.message_port_register_in(pmt.intern("<port name>")) +self.set_msg_handler(pmt.intern("<port name>"), <msg handler function>) +\endcode + +Putting this together below is a very simple example: + +\code +class msg_block(gr.basic_block): + def __init__(self): + gr.basic_block.__init__( + self, + name="msg_block", + in_sig=None, + out_sig=None) + + self.message_port_register_out(pmt.intern('msg_out')) + self.message_port_register_in(pmt.intern('msg_in')) + self.set_msg_handler(pmt.intern('msg_in'), self.handle_msg) + + def handle_msg(self, msg): + self.message_port_pub(pmt.intern('msg_out'), + pmt.intern('message received!')) +\endcode + +*/
\ No newline at end of file diff --git a/docs/doxygen/other/usage.dox b/docs/doxygen/other/usage.dox new file mode 100644 index 0000000000..717f14e610 --- /dev/null +++ b/docs/doxygen/other/usage.dox @@ -0,0 +1,43 @@ +/*! \page page_usage Usage Manual + +Note: Once built, check out <a href="http://gnuradio.org" target="_blank">gnuradio.org</a> for +more tutorials on using the software system and examples. + +<b>Getting Started</b> + +\li \subpage build_guide - Installation notes, dependencies etc. +\li \subpage page_exploring_gnuradio +\li \subpage page_operating_fg + + +<b>Metadata and Messages</b> + +\li \subpage page_pmt +\li \subpage page_metadata +\li \subpage page_msg_passing +\li \subpage page_stream_tags +\li \subpage page_tagged_stream_blocks + +<b>Advanced Development Topics</b> + +\li \subpage page_logger +\li \subpage page_perf_counters +\li \subpage page_affinity +\li \subpage page_prefs +\li \subpage page_python_blocks + +<b>Signal Processing and Digital Communications</b> + +\li \subpage page_pfb +\li \subpage page_ofdm +\li \subpage page_packet_data + +<b>Out-of-tree Modules</b> + +\li \subpage page_oot_config + +<b>VOLK</b> + +\li \subpage volk_guide - How to incorporate and use VOLK in GNU Radio blocks + +*/ diff --git a/docs/doxygen/other/volk_guide.dox b/docs/doxygen/other/volk_guide.dox new file mode 100644 index 0000000000..a6a24457a6 --- /dev/null +++ b/docs/doxygen/other/volk_guide.dox @@ -0,0 +1,152 @@ +/*! \page volk_guide Instructions for using VOLK in GNU Radio + +Note: Many blocks have already been converted to use VOLK in their calls, so +they can also serve as examples. See the +gr::blocks::complex_to_<type>.h files for examples of various blocks +that make use of VOLK. + +\section volk_intro Introduction + +VOLK is the Vector-Optimized Library of Kernels. It is a library that +contains kernels of hand-written SIMD code for different mathematical +operations. Since each SIMD architecture can be greatly different and +no compiler has yet come along to handle vectorization properly or +highly efficiently, VOLK approaches the problem differently. For each +architecture or platform that a developer wishes to vectorize for, a +new proto-kernel is added to VOLK. At runtime, VOLK will select the +correct proto-kernel. In this way, the users of VOLK call a kernel for +performing the operation that is platform/architecture agnostic. This +allows us to write portable SIMD code. + +VOLK kernels are always defined with a 'generic' proto-kernel, which +is written in plain C. With the generic kernel, the kernel becomes +portable to any platform. Kernels are then extended by adding +proto-kernels for new platforms in which they are desired. + +A good example of a VOLK kernel with multiple proto-kernels defined is +the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar +multiplication of a vector of floating point numbers (each item in the +vector is multiplied by the same value). This kernel has the following +proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'neon' + +\code + void volk_32f_s32f_multiply_32f_a_generic + void volk_32f_s32f_multiply_32f_a_sse + void volk_32f_s32f_multiply_32f_a_avx + void volk_32f_s32f_multiply_32f_a_neon +\endcode + +These proto-kernels means that on platforms with AVX support, VOLK can +select this option or the SSE option, depending on which is faster. If +all else fails, VOLK can fall back on the generic proto-kernel, which +will always work. + +See <a +href="http://gnuradio.org/redmine/projects/gnuradio/wiki/Volk">VOLK on +gnuradio.org</a> for details on the VOLK naming scheme. + + +\section volk_alignment Setting and Using Memory Alignment Information + +For VOLK to work as best as possible, we want to use memory-aligned +SIMD calls, which means we have to have some way of knowing and +controlling the alignment of the buffers passed to gr_block's work +function. We set the alignment requirement for SIMD aligned memory +calls with: + +\code + const int alignment_multiple = + volk_get_alignment() / output_item_size; + set_alignment(std::max(1,alignment_multiple)); +\endcode + +The VOLK function 'volk_get_alignment' provides the alignment of the +the machine architecture. We then base the alignment on the number of +output items required to maintain the alignment, so we divide the +number of alignment bytes by the number of bytes in an output items +(sizeof(float), sizeof(gr_complex), etc.). This value is then set per +block with the 'set_alignment' function. + +Because the scheduler tries to optimize throughput, the number of +items available per call to work will change and depends on the +availability of the read and write buffers. This means that it +sometimes cannot produce a buffer that is properly memory +aligned. This is an inevitable consequence of the scheduler +system. Instead of requiring alignment, the scheduler enforces the +alignment as much as possible, and when a buffer becomes unaligned, +the scheduler will work to correct it as much as possible. If a +block's buffers are unaligned, then, the scheduler sets a flag to +indicate as much so that the block can then decide what best to +do. The next section discusses the use of the aligned/unaligned +information in a gr_block's work function. + + +\section volk_work Calling VOLK kernels in Work() + +The buffers passed to work/general_work in a gr_block are not +guaranteed to be aligned, but they will mostly be aligned whenever +possible. When not aligned, the 'is_unaligned()' flag will be set so +the scheduler knows to try to realign the buffers. We actually make +calls to the VOLK dispatcher, which is mainly designed to check the +buffer alignments and call the correct version of the kernel for +us. From the user-level view of VOLK, calling the dispatcher allows us +to ignore the concept of aligned versus unaligned. This looks like: + +\code +int +gr_some_block::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + // Call the dispatcher to check alignment and call the _a or _u + // version of the kernel. + volk_32f_something_32f(out, in, noutput_items); + + return noutput_items; +} +\endcode + + + +\section volk_tuning Tuning VOLK Performance + +VOLK comes with a profiler that will build a config file for the best +SIMD architecture for your processor. Run volk_profile that is +installed into $PREFIX/bin. This program tests all known VOLK kernels +for each architecture supported by the processor. When finished, it +will write to $HOME/.volk/volk_config the best architecture for the +VOLK function. This file is read when using a function to know the +best version of the function to execute. + +\subsection volk_hand_tuning Hand-Tuning Performance + +If you know a particular architecture works best for your processor, +you can specify the particular architecture to use in the VOLK +preferences file: $HOME/.volk/volk_config + +The file looks like: + +\code + volk_<FUNCTION_NAME> <ARCHITECTURE> +\endcode + +Where the "FUNCTION_NAME" is the particular function that you want to +over-ride the default value and "ARCHITECTURE" is the VOLK SIMD +architecture to use (generic, sse, sse2, sse3, avx, etc.). For +example, the following config file tells VOLK to use SSE3 for the +aligned and unaligned versions of a function that multiplies two +complex streams together. + +\code + volk_32fc_x2_multiply_32fc_a sse3 + volk_32fc_x2_multiply_32fc_u sse3 +\endcode + +\b Tip: if benchmarking GNU Radio blocks, it can be useful to have a +volk_config file that sets all architectures to 'generic' as a way to +test the vectorized versus non-vectorized implementations. + +*/ |