Creating OOT Module in GR 4.0: Difference between revisions

From GNU Radio
Jump to navigation Jump to search
No edit summary
Line 45: Line 45:


== YML File ==
== YML File ==
=== Top level properties ===
<syntaxhighlight lang="yaml">module: myOOT
block: myblock
label: myblock
blocktype: sync_block
</syntaxhighlight>
The first section contains the top level properties.  Module and block need to match the module/filename. 
Label corresponds to how it would be displayed in GRC or other interface.
Blocktype currently can be <code>block</code>, <code>sync_block</code>, or <code>grc</code> and corresponds to the type of block that will be implemented
=== Parameters ===
<syntaxhighlight lang="yaml"># Example Parameters
parameters:
-  id: itemsize
    label: Item Size
    dtype: size
    settable: false
    default: 0
    grc:
        hide: part
</syntaxhighlight>
Next we declare the parameters in the block.  These correspond to the constructor of the block, as well as setters and getters if desired.  The example parameter that is given is for an itemsize parameter, which is by default set to 0 - this can be used to attach an untyped port to an arbitrarily typed port, in the case of e.g. a head or throttle block that doesn't really consider the type of the incoming/outgoing data
==== dtype ====
<code>dtype</code> uses sigmf data type names, and should be from the set (listed as c++, python, and grc type)
<syntaxhighlight lang="python">type_lookup = {
    'cf64': ['std::complex<double>', 'complex', 'complex'],
    'cf32': ['std::complex<float>', 'complex', 'complex'],
    'rf64': ['double', 'float', 'float'],
    'rf32': ['float', 'float', 'float'],
    'ri64': ['int64_t', 'int', 'int'],
    'ri32': ['int32_t', 'int', 'int'],
    'ri16': ['int16_t', 'int', 'short'],
    'ri8': ['int8_t', 'int', 'byte'],
    'ru64': ['uint64_t', 'int', 'int'],
    'ru32': ['uint32_t', 'int', 'int'],
    'ru16': ['uint16_t', 'int', 'short'],
    'ru8': ['uint8_t', 'int', 'byte'],
    'size': ['size_t', 'int', 'int'],
    'string': ['std::string', 'str', 'string'],
    'bool': ['bool', 'bool', 'bool'],
}</syntaxhighlight>
==== id/label ====
This gives the parameter a name, which will show up in the constructor arguments as well as the <code>pmt</code> object instantiated to represent this parameter in the base block
==== settable/gettable ====
If the <code>settable</code> is set <code>true</code> (default false), the parameter can be changed at runtime via an autogenerated callback method
<code>settable=true</code> also enables a getter method - but settable=false/gettable=true will only provide the getter
==== default ====
The value set for default is a hard default in the constructor arguments.  All parameters after this must also have a default set.  Parameters with a default value are given keyword arguments in the python bindings
==== grc ====
The grc section is passed directly to the generated grc bindings as these pertain specifically to grc fields.  These include:
- category
- hide
- default (a soft default when a block is placed on the canvas)
=== Ports ===
<syntaxhighlight lang="yaml"># Example Ports
ports:
-  domain: stream
    id: in
    direction: input
    type: untyped
    size: parameters/itemsize
-  domain: stream
    id: out
    direction: output
    type: untyped
    size: parameters/itemsize
</syntaxhighlight>
<syntaxhighlight lang="yaml">implementations:
-  id: cpu
# -  id: cuda
</syntaxhighlight>


== Implementation Files ==
== Implementation Files ==


== Autogenerated Files ==
== Autogenerated Files ==

Revision as of 13:54, 8 September 2022

Creating the OOT

In place of modtool, there is a script in the gnuradio source tree that will perform the same function

python3 $GR_PREFIX/src/gnuradio/utils/modtool/create_mod.py myOOT

This will create a skeleton OOT with the following structure:

gr4-myOOT/
├── blocklib
│   └── myOOT
│       ├── include
│       │   └── gnuradio
│       │       └── myOOT
│       │           └── meson.build
│       ├── lib
│       │   └── meson.build
│       ├── python
│       │   └── myOOT
│       │       └── __init__.py
│       └── test
│           └── meson.build
├── meson.build
└── meson_options.txt

Creating a Block

To create a block, there is a helper scripts in the gnuradio source tree:

cd gr4-myOOT
python3 $GR_PREFIX/src/gnuradio/utils/modtool/create_block.py myblock

This will create the necessary files for compiling a block by placing a minimal set of files in the following structure:

├── blocklib
│   └── myOOT
│       ├── myblock
│       │   ├── myblock_cpu.cc
│       │   ├── myblock_cpu.h
│       │   └── myblock.yml

All of the files needed to create the block are located in one place, and all of the normal boilerplate will be automatically generated.

From here let's start with the .yml file

YML File

Top level properties

module: myOOT
block: myblock
label: myblock
blocktype: sync_block


The first section contains the top level properties. Module and block need to match the module/filename.

Label corresponds to how it would be displayed in GRC or other interface.

Blocktype currently can be block, sync_block, or grc and corresponds to the type of block that will be implemented

Parameters

# Example Parameters
parameters:
-   id: itemsize
    label: Item Size
    dtype: size
    settable: false
    default: 0
    grc:
        hide: part

Next we declare the parameters in the block. These correspond to the constructor of the block, as well as setters and getters if desired. The example parameter that is given is for an itemsize parameter, which is by default set to 0 - this can be used to attach an untyped port to an arbitrarily typed port, in the case of e.g. a head or throttle block that doesn't really consider the type of the incoming/outgoing data

dtype

dtype uses sigmf data type names, and should be from the set (listed as c++, python, and grc type)

type_lookup = {
    'cf64': ['std::complex<double>', 'complex', 'complex'],
    'cf32': ['std::complex<float>', 'complex', 'complex'],
    'rf64': ['double', 'float', 'float'],
    'rf32': ['float', 'float', 'float'],
    'ri64': ['int64_t', 'int', 'int'],
    'ri32': ['int32_t', 'int', 'int'],
    'ri16': ['int16_t', 'int', 'short'],
    'ri8': ['int8_t', 'int', 'byte'],
    'ru64': ['uint64_t', 'int', 'int'],
    'ru32': ['uint32_t', 'int', 'int'],
    'ru16': ['uint16_t', 'int', 'short'],
    'ru8': ['uint8_t', 'int', 'byte'],
    'size': ['size_t', 'int', 'int'],
    'string': ['std::string', 'str', 'string'],
    'bool': ['bool', 'bool', 'bool'],
}


id/label

This gives the parameter a name, which will show up in the constructor arguments as well as the pmt object instantiated to represent this parameter in the base block

settable/gettable

If the settable is set true (default false), the parameter can be changed at runtime via an autogenerated callback method settable=true also enables a getter method - but settable=false/gettable=true will only provide the getter

default

The value set for default is a hard default in the constructor arguments. All parameters after this must also have a default set. Parameters with a default value are given keyword arguments in the python bindings

grc

The grc section is passed directly to the generated grc bindings as these pertain specifically to grc fields. These include: - category - hide - default (a soft default when a block is placed on the canvas)

Ports

# Example Ports
ports:
-   domain: stream
    id: in
    direction: input
    type: untyped
    size: parameters/itemsize

-   domain: stream
    id: out
    direction: output
    type: untyped
    size: parameters/itemsize
implementations:
-   id: cpu
# -   id: cuda

Implementation Files

Autogenerated Files