diff options
Diffstat (limited to 'docs/doxygen')
-rw-r--r-- | docs/doxygen/Doxyfile.in | 4 | ||||
-rw-r--r-- | docs/doxygen/README.doxyxml | 2 | ||||
-rw-r--r-- | docs/doxygen/doxyxml/doxyindex.py | 21 | ||||
-rw-r--r-- | docs/doxygen/images/example_ofdm_packet_rx.png | bin | 0 -> 170252 bytes | |||
-rw-r--r-- | docs/doxygen/images/ofdm_rx_core.png | bin | 0 -> 22751 bytes | |||
-rw-r--r-- | docs/doxygen/images/ofdm_tx_core.png | bin | 0 -> 15496 bytes | |||
-rw-r--r-- | docs/doxygen/other/extra_pages.dox | 3 | ||||
-rw-r--r-- | docs/doxygen/other/logger.dox | 38 | ||||
-rw-r--r-- | docs/doxygen/other/main_page.dox | 12 | ||||
-rw-r--r-- | docs/doxygen/other/msg_passing.dox | 2 | ||||
-rw-r--r-- | docs/doxygen/other/ofdm.dox | 143 | ||||
-rw-r--r-- | docs/doxygen/other/packet_txrx.dox | 82 | ||||
-rw-r--r-- | docs/doxygen/other/pfb_intro.dox | 4 |
13 files changed, 273 insertions, 38 deletions
diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 7d7c03357d..f87efd031d 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -629,8 +629,6 @@ EXCLUDE = @abs_top_builddir@/docs/doxygen/html \ @abs_top_builddir@/gr-pager/lib \ @abs_top_srcdir@/gr-qtgui/lib \ @abs_top_builddir@/gr-qtgui/lib \ - @abs_top_srcdir@/gr-shd/lib \ - @abs_top_builddir@/gr-shd/lib \ @abs_top_srcdir@/gr-trellis/lib \ @abs_top_builddir@/gr-trellis/lib \ @abs_top_srcdir@/gr-uhd/lib \ @@ -737,7 +735,7 @@ INPUT_FILTER = # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. -FILTER_PATTERNS = *.py=@top_srcdir@/gnuradio-core/doc/other/doxypy.py +FILTER_PATTERNS = *.py=@top_srcdir@/docs/doxygen/other/doxypy.py # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source diff --git a/docs/doxygen/README.doxyxml b/docs/doxygen/README.doxyxml index fef71e106f..701c7ab8bc 100644 --- a/docs/doxygen/README.doxyxml +++ b/docs/doxygen/README.doxyxml @@ -11,7 +11,7 @@ Doxygen. $ python swig_doc.py \ $(top_builddir)/docstrings/docs/doxygen/xml \ - $(top_srcdir)/gnuradio-core/src/lib/swig/swig_doc.i + $(top_srcdir)/gnuradio-runtime/swig/swig_doc.i This uses the XML output of Doxygen to to rebuild a SWIG file that contains all of the current Doxygen markups. diff --git a/docs/doxygen/doxyxml/doxyindex.py b/docs/doxygen/doxyxml/doxyindex.py index 8c5502a61f..69c6de07f5 100644 --- a/docs/doxygen/doxyxml/doxyindex.py +++ b/docs/doxygen/doxyxml/doxyindex.py @@ -43,13 +43,16 @@ class DoxyIndex(Base): self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) for mem in self._root.compound: converted = self.convert_mem(mem) - # For files we want the contents to be accessible directly - # from the parent rather than having to go through the file - # object. + # For files and namespaces we want the contents to be + # accessible directly from the parent rather than having + # to go through the file object. if self.get_cls(mem) == DoxyFile: if mem.name.endswith('.h'): self._members += converted.members() self._members.append(converted) + elif self.get_cls(mem) == DoxyNamespace: + self._members += converted.members() + self._members.append(converted) else: self._members.append(converted) @@ -227,7 +230,17 @@ class DoxyNamespace(DoxyCompound): __module__ = "gnuradio.utils.doxyxml" kind = 'namespace' - + + def _parse(self): + if self._parsed: + return + super(DoxyNamespace, self)._parse() + self.retrieve_data() + self.set_descriptions(self._retrieved_data.compounddef) + if self._error: + return + self.process_memberdefs() + Base.mem_classes.append(DoxyNamespace) diff --git a/docs/doxygen/images/example_ofdm_packet_rx.png b/docs/doxygen/images/example_ofdm_packet_rx.png Binary files differnew file mode 100644 index 0000000000..6b8813ced6 --- /dev/null +++ b/docs/doxygen/images/example_ofdm_packet_rx.png diff --git a/docs/doxygen/images/ofdm_rx_core.png b/docs/doxygen/images/ofdm_rx_core.png Binary files differnew file mode 100644 index 0000000000..e00d36b395 --- /dev/null +++ b/docs/doxygen/images/ofdm_rx_core.png diff --git a/docs/doxygen/images/ofdm_tx_core.png b/docs/doxygen/images/ofdm_tx_core.png Binary files differnew file mode 100644 index 0000000000..e98558be08 --- /dev/null +++ b/docs/doxygen/images/ofdm_tx_core.png diff --git a/docs/doxygen/other/extra_pages.dox b/docs/doxygen/other/extra_pages.dox index 8d9b69a87b..617e00d553 100644 --- a/docs/doxygen/other/extra_pages.dox +++ b/docs/doxygen/other/extra_pages.dox @@ -70,9 +70,6 @@ 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_shd shd: The Symplex Hardware Driver Interface -\li shd (>= 3.0.0) - \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 diff --git a/docs/doxygen/other/logger.dox b/docs/doxygen/other/logger.dox index f5228cfc55..3eb487d9af 100644 --- a/docs/doxygen/other/logger.dox +++ b/docs/doxygen/other/logger.dox @@ -30,7 +30,7 @@ to disable a logger. \subsection configfile Logging Configuration -The logging configuration can be found in the gnuradio-core.conf file +The logging configuration can be found in the gnuradio-runtime.conf file under the [LOG] section. This allows us fairly complete control over the logging facilities. The main configuration functions are to set up the level of the loggers and set the default output behavior of the @@ -83,7 +83,7 @@ data members of d_logger and d_debug_logger of gr_block and pass them to our pre-defined macros: \code - GR_LOG_<level>(<logger>, "<Message to print>"); + gr::LOG_<level>(<logger>, "<Message to print>"); \endcode Where \<level\> is one of the levels as mentioned above, \<logger\> is @@ -93,8 +93,8 @@ message to the standard logger and a WARN level message to the debug logger, it would look like this: \code - GR_LOG_INFO(d_logger, "Some info about the block"); - GR_LOG_WARN(d_debug_logger, "Some warning about the block"); + gr::LOG_INFO(d_logger, "Some info about the block"); + gr::LOG_WARN(d_debug_logger, "Some warning about the block"); \endcode When this is printed to wherever you are directing the output of the @@ -115,15 +115,15 @@ The various logging macros are defined in gr_logger.h. Here are some simple examples of using them: \code - GR_LOG_DEBUG(LOG, "DEBUG message"); - GR_LOG_INFO(LOG, "INFO message"); - GR_LOG_NOTICE(LOG, "NOTICE message"); - GR_LOG_WARN(LOG, "WARNING message"); - GR_LOG_ERROR(LOG, "ERROR message"); - GR_LOG_CRIT(LOG, "CRIT message"); - GR_LOG_ALERT(LOG, "ALERT message"); - GR_LOG_FATAL(LOG, "FATAL message"); - GR_LOG_EMERG(LOG, "EMERG message"); + gr::LOG_DEBUG(LOG, "DEBUG message"); + gr::LOG_INFO(LOG, "INFO message"); + gr::LOG_NOTICE(LOG, "NOTICE message"); + gr::LOG_WARN(LOG, "WARNING message"); + gr::LOG_ERROR(LOG, "ERROR message"); + gr::LOG_CRIT(LOG, "CRIT message"); + gr::LOG_ALERT(LOG, "ALERT message"); + gr::LOG_FATAL(LOG, "FATAL message"); + gr::LOG_EMERG(LOG, "EMERG message"); \endcode If the logger is not enabled, then these macros become nops and do @@ -188,20 +188,20 @@ a singleton in the system, but we need to get a pointer to the right logger and then set it up for our local use. The following code snippet shows how to do this to get access to the standard logger, which has a root of "gr_log." (access to the debug logger is similar -except we would use "gr_log_debug." in the GR_LOG_GETLOGGER call): +except we would use "gr_log_debug." in the gr::LOG_GETLOGGER call): \code - gr_prefs *p = gr_prefs::singleton(); + prefs *p = prefs::singleton(); std::string log_file = p->get_string("LOG", "log_config", ""); std::string log_level = p->get_string("LOG", "log_level", "off"); - GR_CONFIG_LOGGER(log_file); - GR_LOG_GETLOGGER(LOG, "gr_log." + "my_logger_name"); - GR_LOG_SET_LEVEL(LOG, log_level); + gr::CONFIG_LOGGER(log_file); + gr::LOG_GETLOGGER(LOG, "gr_log." + "my_logger_name"); + gr::LOG_SET_LEVEL(LOG, log_level); \endcode This creates a pointer called LOG (which is instantiated as a log4cpp:LoggerPtr in the macro) that we can now use locally as the -input to our logging macros like 'GR_LOG_INFO(LOG, "message")'. +input to our logging macros like 'gr::LOG_INFO(LOG, "message")'. \section logPy Logging from Python diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 498e2f5803..85c3ff4fac 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -46,6 +46,8 @@ More details on GNU Radio concepts: \li \ref volk_guide \li \ref page_pfb \li \ref page_tagged_stream_blocks +\li \ref page_ofdm +\li \ref page_packet_data \section flowgraph Operating a Flowgraph @@ -376,10 +378,10 @@ Similarly, in C++, we get a reference to the object by explicitly calling for the singleton of the object: \code - gr_prefs *p = gr_prefs::singleton(); + prefs *p = prefs::singleton(); \endcode -The methods associated with this preferences object are (from class gr_prefs): +The methods associated with this preferences object are (from class gr::prefs): \code bool has_section(string section) @@ -413,9 +415,9 @@ config file itself. New as of 3.6.5. Using gr_modtool, each package comes with the ability to easily locate -the gnuradio-core library using the 'find_package(GnuradioCore)' cmake -command. This only locates that the library and include directories -exist, which is enough for most simple projects. +the gnuradio-runtime library using the 'find_package(GnuradioRuntime)' +cmake command. This only locates that the library and include +directories exist, 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 diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox index 7035f291e4..dc0d5bbb3f 100644 --- a/docs/doxygen/other/msg_passing.dox +++ b/docs/doxygen/other/msg_passing.dox @@ -264,6 +264,6 @@ All of these mechanisms are explored and tested in the QA code of the file qa_pdu.py. There are some examples of using the message passing infrastructure -through GRC in gnuradio-core/src/examples/msg_passing. +through GRC in gr-blocks/examples/msg_passing. */ diff --git a/docs/doxygen/other/ofdm.dox b/docs/doxygen/other/ofdm.dox new file mode 100644 index 0000000000..62efa0cce5 --- /dev/null +++ b/docs/doxygen/other/ofdm.dox @@ -0,0 +1,143 @@ +/*! \page page_ofdm OFDM + +\section intro Introduction + +GNU Radio provides some blocks to transmit and receive OFDM-modulated signals. +In the following, we assume the reader is familiar with OFDM and how it works, +for an introduction to OFDM refer to standard textbooks on digital communication. + +The blocks are designed in a very generic fashion. As a developer, this means that +often, a desired functionality can be achieved by correct parametrization of the +available blocks, but in some cases, custom blocks have to be included. The design +of the OFDM components is such that adding own functionality is possible with +very little friction. + +\ref page_packet_data has an example of how to use OFDM in a packet-based +receiver. + +\section conventions Conventions and Notations + +\subsection fftshift FFT Shifting + +In all cases where OFDM symbols are passed between blocks, the default behaviour +is to FFT-Shift these symbols, i.e. that the DC carrier is in the middle (to be +precise, it is on carrier \f$\lfloor N/2 \rfloor\f$ where N is the FFT length and +carrier indexing starts at 0). + +The reason for this convention is that some blocks require FFT-shifted ordering +of the symbols to function (such as gr::digital::ofdm_chanest_vcvc), and for +consistency's sake, this was chosen as a default for all blocks that pass OFDM +symbols. Also, when viewing OFDM symbols, FFT-shifted symbols are in their +natural order, i.e. as they appear in the pass band. + +\subsection indexing Carrier Indexing + +Carriers are always index starting at the DC carrier, which has the index 0 +(you usually don't want to occupy this carrier). The carriers right of the +DC carrier (the ones at higher frequencies) are indexed with 1 through N/2-1 +(N being the FFT length again). + +The carriers left of the DC carrier (with lower frequencies) can be indexed +-N/2 through -1 or N/2 through N-1. Carrier indices N-1 and -1 are thus +equivalent. The advantage of using negative carrier indices is that the +FFT length can be changed without changing the carrier indexing. + +\subsection carrieralloc Carrier and Symbol Allocation + +Many blocks require knowledge of which carriers are allocated, and whether they +carry data or pilot symbols. GNU Radio blocks uses three objects for this, typically +called \p occupied_carriers (for the data symbols), \p pilot_carriers and +\p pilot_symbols (for the pilot symbols). + +Every one of these objects is a vector of vectors. \p occupied_carriers and +\p pilot_carriers identify the position within a frame where data and pilot +symbols are stored, respectively. + +\p occupied_carriers[0] identifies which carriers are occupied on the first +OFDM symbol, \p occupied_carriers[1] does the same on the second OFDM symbol etc. + +Here's an example: +\code + occupied_carriers = ((-2, -1, 1, 3), (-3, -1, 1, 2)) + pilot_carriers = ((-3, 2), (-2, 3)) +\endcode +Every OFDM symbol carries 4 data symbols. On the first OFDM symbol, they are on carriers -2, -1, 1 and 3. +Carriers -3 and 2 are not used, so they are where the pilot symbols can be placed. +On the second OFDM symbol, the occupied carriers are -3, -1, 1 and 2. The pilot +symbols must thus be placed elsewhere, and are put on carriers -2 and 3. + +If there are more symbols in the OFDM frame than the length of \p occupied_carriers +or \p pilot_carriers, they wrap around (in this example, the third OFDM symbol +uses the allocation in \p occupied_carriers[0]). + +But how are the pilot symbols set? This is a valid parametrization: +\code + pilot_symbols = ((-1, 1j), (1, -1j), (-1, 1j), (-1j, 1)) +\endcode + +The position of these symbols are thos in \p pilot_carriers. So on the first OFDM +symbol, carrier -3 will transmit a -1, and carrier 2 will transmit a 1j. +Note that \p pilot_symbols is longer than \p pilot_carriers in this example-- +this is valid, the symbols in \p pilot_symbols[2] will be mapped according +to \p pilot_carriers[0]. + +\section detectsync Detection and Synchronisation + +Before anything happens, an OFDM frame must be detected, the beginning of OFDM +symbols must be identified, and frequency offset must be estimated. + +\section tx Transmitting + +\image html ofdm_tx_core.png "Core elements of an OFDM transmitter" + +This image shows a very simple example of a transmitter. It is assumed that the +input is a stream of complex scalars with a length tag, i.e. the transmitter +will work on one frame at a time. + +The first block is the carrier allocator (gr::digital::ofdm_carrier_allocator_cvc). +This sorts the incoming complex scalars onto OFDM carriers, and also places the +pilot symbols onto the correct positions. +There is also the option to pass OFDM symbols which are prepended in front of every +frame (i.e. preamble symbols). These can be used for detection, synchronisation +and channel estimation. + +The carrier allocator outputs OFDM symbols (i.e. complex vectors of FFT length). +These must be converted to time domain signals before continuing, which is why +they are piped into an (I)FFT block. Note that because all the OFDM symbols are +treated in the shifted form, the IFFT block must be shifting as well. + +Finally, the cyclic prefix is added to the OFDM symbols. The gr::digital::ofdm_cyclic_prefixer +can also perform pulse shaping on the OFDM symbols (raised cosine flanks in the +time domain). + +\section rx Receiving + +On the receiver side, some more effort is necessary. The following flow graph +assumes that the input starts at the beginning of an OFDM frame and is prepended +with a Schmidl & Cox preamble for coarse frequency correction and channel +estimation. Also assumed is that the fine frequency offset is already corrected +and that the cyclic prefix has been removed. The latter can be achieved by a +gr::digital::header_payload_demux, the former can be done using a +gr::digital::ofdm_sync_sc_cc. + +\image html ofdm_rx_core.png "Core elements of an OFDM receiver" + +First, an FFT shifts the OFDM symbols into the frequency domain, where the signal +processing is performed (the OFDM frame is thus in the memory in matrix form). +It is passed to a block that uses the preambles to perform channel estimation +and coarse frequency offset. Both of these values are added to the output stream +as tags; the preambles are then removed from the stream and not propagated. + +Note that this block does not correct the OFDM frame. Both the coarse frequency +offset correction and the equalizing (using the initial channel state estimate) +are done in the following block, gr::digital::ofdm_frame_equalizer_vcvc. +The interesting property about this block is that it uses a +gr::digital::ofdm_equalizer_base derived object to perform the actual equalization. + +The last block in the frequency domain is the gr::digital::ofdm_serializer_vcc, +which is the inverse block to the carrier allocator. +It plucks the data symbols from the \p occupied_carriers and outputs them as a +stream of complex scalars. These can then be directly converted to bits, or passed +to a forward error correction decoder. + +*/ diff --git a/docs/doxygen/other/packet_txrx.dox b/docs/doxygen/other/packet_txrx.dox new file mode 100644 index 0000000000..afe84240ff --- /dev/null +++ b/docs/doxygen/other/packet_txrx.dox @@ -0,0 +1,82 @@ +/*! \page page_packet_data Packet Data Transmission + +\section intro Introduction + +In many cases, the PHY layer of a digital transceiver uses <em>packets</em>to break +down the transmission (as opposed to continuously broadcasting data), and GNU Radio +natively supports this kind of transmission. The basic mechanisms which allow this +are the \ref page_msg_passing and the \ref page_tagged_stream_blocks. + +With the tools provided in GNU Radio, simple digital packet transmission schemes +are easily implemented, allowing the creation of packet-based communication links +and even -networks. + +\section packetstructure Structure of a packet + +Typically, a packet consists of the following elements: + +- A preamble. This is used for detection, synchronization (in time and frequency) and possibly initial channel state estimation. +- A header. This is of fixed length and stores information about the packet, such as (most importantly) its length, but potentially other information, such as the packet number, its intended recipient etc. +- The payload. +- A checksum, typically a CRC value, to validate the packet contents. + +At the transmitter stage, these are modulated and prepared for transmission (a forward error correction code may also be applied). Because the transmitter knows te packet length, is a trivial matter to create the transmit frames using the tagged stream blocks. + +The receiver has to perform a multitude of things to obtain the packet again. +Most importantly, it has to convert an infinite stream (coming from the receiver +device, e.g. a UHD source block) into a packetized, tagged stream. + +\section hpdemuxer The Header/Payload Demuxer and header parser + +The key element to return back to packetized state is the gr::digital::header_payload_demux. +At its first input, it receives a continuous stream of sample data, coming from +the receiver device. It discards all the incoming samples, until the beginning +of a packet is signalled, either by a stream tag, or a trigger signal on its second input. + +Once such a beginning is detected, the demultiplexer copies the preamble and header +to the first output (it must know the exact length of these elements). The header +can then be demodulated with any suitable set of GNU Radio blocks. + +To turn the information stored in the demodulated header bits into metadata +which can be understood by GNU Radio, a gr::digital::packet_headerparser_b block +is used to turn the header data into a message, which is passed back to the +header/payload demuxer. The latter then knows the length of the payload, and +passes that out on the second output, along with all the metadata obtained +in the header demodulation chain. + +The knowledge of the header structure (i.e. how to turn a sequence of bits into +a payload length etc.) is stored in an object of type gr::digital::packet_header_default. +This must be passed to the header parser block. + +\section ofdm Packet receiver example: OFDM + +\image html example_ofdm_packet_rx.png "Example: OFDM Packet Receiver" + +The image above shows an example of a simple OFDM receiver. It has no forward error correction, +and uses the simplest possible frame structure. + +The four elements of the packet receiver are highlighted. The first part is the packet detector +and synchronizer. The samples piped into the header/payload demuxer are fine frequency corrected, +and a trigger signal is sent to mark the beginning of the burst. + +Next, the header demodulation receiver chain is activated. The FFT shifts OFDM symbols to the +frequency domain. The coarse frequency offset and initial channel state are estimated from the +preamble and are added to the stream as tags. The OFDM symbol containing the header is passed +to an equalizer, which also corrects the coarse frequency offset. A serializer picks the data +symbols from the OFDM symbol and outputs them as a sequence of scalar complex values, which +are then demodulated into bits (in this case BPSK is used). + +The bits are interpreted by the header parser, which uses a gr::digital::packet_header_ofdm +object to interpret the bits (the latter is derived form gr::digital::packet_header_default). +The result from the header parser is then fed back to the demuxer, which now knows the length of +payload and outputs that as a tagged stream. + +The payload demodulation chain is the same as the header demodulation chain, only the +channel estimator block is unnecessary as the channel state information is still available +as metadata on the payload tagged stream. + +This flow graph, as well as the corresponding transmitter, can be found in +gr-digital/examples/ofdm/rx_ofdm.grc and gr-digital/examples/ofdm/tx_ofdm.grc + + +*/ diff --git a/docs/doxygen/other/pfb_intro.dox b/docs/doxygen/other/pfb_intro.dox index d3c3ee63be..43e27b4a3c 100644 --- a/docs/doxygen/other/pfb_intro.dox +++ b/docs/doxygen/other/pfb_intro.dox @@ -11,7 +11,7 @@ in all sorts of applications. See the documentation for the individual blocks for details about what they can do and how they should be used. Furthermore, there are -examples for these blocks in <b>gnuradio-examples/python/pfb</b>. +examples for these blocks in <b>gr-filter/examples</b>. The main issue when using the PFB blocks is defining the prototype filter, which is passed to all of the blocks as a vector of \p @@ -19,7 +19,7 @@ taps. The taps from the prototype filter which get partitioned among the \p N channels of the channelizer. An example of creating a set of filter taps for a PFB channelizer is -found on line 49 of <b>gnuradio-examples/python/pfb/channelizer.py</b> +found on line 49 of <b>gr-filter/examples/channelizer.py</b> and reproduced below. Notice that the sample rate is the sample rate at the input to the channelizer while the bandwidth and transition width are defined for the channel bandwidths. This makes a fairly long |