GAM

The Generic Application Module (GAM) is the component where user-algorithms are to be implemented.

The GAM offers one interface for configuration and two interfaces for real-time input and output processing.

../../../_images/GAM-1.png

Warning

No interface with operating system (e.g. reading from files/sockets) shall be implemented in the GAMs. The only exception is memory allocation during configuration.

GAMs can be conceptually divided in two sets: one where the inputs and outputs signals (number, type and dimensions) are fixed by design; and another where the algorithm behaviour varies with the signal characteristics of a given real-time application (see examples below).

Configuration

A GAM is initialised just like any other MARTe Object.

The properties related to the input and output signals are available when the Setup method is called. At this stage any of the signal related methods described in the GAM API can be used to query the signal properties.

virtual bool MyGAM::Setup () {
   ...
   uint32 numberOfInputSignals = GetNumberOfInputSignals();
   ...
   for (i = 0u; i<numberOfInputSignals; i++) {
      TypeDescriptor td = GetSignalType(InputSignals, i);
      ...
   }
   ...
}

Typical use cases of the Setup method are to validate and/or configure the algorithm against the input/output signal requirements of the specific application (e.g. the number, type and dimensions);

virtual bool MyGAM::Setup () {
   ...
   uint32 numberOfInputSignals = GetNumberOfInputSignals();
   ...
   //Only accept one input signal
   bool ok = (numberOfInputSignals == 1u);
   ...
}

In the configuration stream the input signals shall be placed inside a node named InputSignals and the output signals inside a node named OutputSignals.

...
InputSignals = {
   Counter = {
      DataSource = DDB1
      Type = uint32
   }
}
OutputSignals = {
   GainCounter = {
      DataSource = DDB1
      Type = uint32
   }
}
...

GAMs can also use registered structured types as input/output signals.

For example, the following structure can be used as a signal:

struct ModelGAMExampleStructInner1 {
   MARTe::float32 f1;
   MARTe::float32 f2;
   MARTe::float32 f3[6];
};
struct ModelGAMExampleStructSignal {
   MARTe::uint32 u1;
   ModelGAMExampleStructInner1 s1;
   ModelGAMExampleStructInner1 s2;
};
...
InputSignals = {
   Signal1 = {
      DataSource = DDB1
      Type = ModelGAMExampleStructSignal
   }
}
OutputSignals = {
   Signal1 = {
      DataSource = DDB1
      Type = ModelGAMExampleStructSignal
   }
}
...

Note that the structure will be automatically expanded into the equivalent configuration structure (this means that the GAM API will see the expanded structure):

...
InputSignals = {
   Signal1 = {
      u1 = {
         DataSource = DDB1
         Type = uint32
      }
      s1 = {
         f1 = {
            DataSource = DDB1
            Type = float32
         }
         f2 = {
            DataSource = DDB1
            Type = float32
         }
         f3 = {
            DataSource = DDB1
            Type = float32
            NumberOfDimensions = 1
            NumberOfElements = 6
         }
      }
      s2 = {
         ...
      }
   }
}
...

Signal properties

The signal name (in the context of the GAM) is the name of the node. Other properties that can be set for any signal are:

Property

Meaning

Type

The signal type as any of the supported Types or a structure type.

DataSource

The name of the DataSource from where the signal will read/written from/to.

Frequency

Only meaningful for input signals. The frequency at which the signal is expected to be produced (at most one signal per real-time thread) may have this property set.

Trigger

Only meaningful for output signals. Trigger the DataSource when this signal is written.

NumberOfElements

The number of elements (1 if the signal is a scalar).

NumberOfDimensions

The number of dimensions (0 if scalar, 1 if vector, 2 if matrix).

Samples

The number of samples to read from a DataSource. This number defines the number of samples that the DataSource shall acquire for each control cycle. Note that each sample may contain an array. Indeed, the amount of memory required to hold a signal of type T, with M samples and N elements is: sizeof(T) x M x N. Typical use cases: i) ADC: M samples, 1 element; ii) Image: 1 sample, N elements; iii) Video: M samples, N elements.

Ranges

In the case of a vector read/write only a subset. The format is a matrix, indexed to zero, of the ranges that are to be read (e.g. {{0, 1}, {3, 5}} would read elements 0, 1, 3, 4 and 5 of the array).

Alias

The name of the signal in the DataSource (which can be different from the name of the signal in the GAM).

Default

The default value to be used in the first control cycle (if needed, i.e. if it depends from a value of the previous cycle).

The structure types offer to extra properties:

Property

Meaning

MemberAliases

The name of the structured member signal in the DataSource (which can be different from the name of the signal in the GAM).

Defaults

The default value for a given member of the structure.

The following snippet shows how to change the alias and the defaults of a structure.

...
InputSignals = {
   Signal1 = {
      DataSource = DDB1
      Type = ModelGAMExampleStructSignal
      Defaults = {
         Signal1.s1.f1 = 2
         Signal1.s1.f2 = 3
         Signal1.s1.f3 = {1, 2, 3, 4, 5, 6}
         Signal1.s2.f1 = -2
         Signal1.s2.f2 = -3
         Signal1.s2.f3 = {-1, -2, -3, -4, -5, -6}
      }
      MemberAliases = {
         //Rename of a structured member
         Signal1.s2.f2 = Signal1.s2.g2
      }
   }
...

Real-time execution

The Execute method is called at every real-time cycle.

When the method is called, the input signals will be ready to be processed by the GAM. After the method is called the output signals will be propagated accordingly.

...
bool GAM1::Setup() {
...
   inputSignal = reinterpret_cast<uint32 *>(GetInputSignalMemory(0u));
   outputSignal = reinterpret_cast<uint32 *>(GetOutputSignalMemory(0u));
...

bool GAM1::Execute() {
...
   *outputSignal = gain * *inputSignal;
...

GAMGroup

GAMs can also be grouped into a context where a set of constant data is shared between them.

../../../_images/GAMGroup-1.png

Typical use-cases for GAMGroups are the need to share initialisation data which is either onerous to compute or that requires the storing of a large amount of memory. In both cases it would be a waste of resources to repeat and store the same initialisation process on all the GAMs requiring access to this information.

The shared context is set by calling the method GAMGroup::SetContext in the class inheriting from GAMGroup. This will then trigger the calling of the method SetContext on all the GAM components that, in the configuration stream, are a child of this GAMGroup instance.

...
+GAMGroup1 = {
   Class = ParentGAMGroupExample1
   //The model to be shared by all the GAMs belonging to this group
   Model = {{2, 0, 0}, {0, 3, 0}, {1, 0, 4}}
   +GAMChild1 = {
      Class = ChildGAMGroupExample1
      ...
   }
   +GAMChild2 = {
      Class = ChildGAMGroupExample2
              ...
   }
   ...
...
class ParentGAMGroupExample1: public MARTe::GAMGroup {
...
   bool PrepareNextState(const MARTe::char8*, const MARTe::char8*) {
      ...
      ok = SetContext(matrixModelContext);
             ...

class ChildGAMGroupExample1 : public MARTe::GAM {
   ...
   bool SetContext(ConstReference context) {
      matrixModelContext = context;
      contextSet = context.IsValid();
   ...

Examples

Fixed GAM

The following is an example of GAM which has a fixed number of signals.

Fixed signals GAM (FixedGAMExample1)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
 * @file FixedGAMExample1.cpp
 * @brief Source file for class FixedGAMExample1
 * @date 06/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class FixedGAMExample1 (public, protected, and private). Be aware that some 
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "FixedGAMExample1.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/
namespace MARTe2Tutorial {
FixedGAMExample1::FixedGAMExample1() {
    gain = 0u;
    inputSignal = NULL_PTR(MARTe::uint32 *);
    outputSignal = NULL_PTR(MARTe::uint32 *);
}

FixedGAMExample1::~FixedGAMExample1() {

}

bool FixedGAMExample1::Initialise(MARTe::StructuredDataI & data) {
    using namespace MARTe;
    bool ok = GAM::Initialise(data);
    if (!ok) {
        REPORT_ERROR(ErrorManagement::ParametersError, "Could not Initialise the GAM");
    }
    if (ok) {
        ok = data.Read("Gain", gain);
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError, "The parameter Gain shall be set");
        }
    }
    if (ok) {
        REPORT_ERROR(ErrorManagement::Information, "Parameter Gain set to %d", gain);
    }
    return ok;
}

bool FixedGAMExample1::Setup() {
    using namespace MARTe;
    uint32 numberOfInputSignals = GetNumberOfInputSignals();
    uint32 numberOfOutputSignals = GetNumberOfOutputSignals();
    bool ok = (numberOfInputSignals == numberOfOutputSignals);
    if (ok) {
        ok = (numberOfOutputSignals == 1u);
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals shall be equal to 1. numberOfInputSignals = %d numberOfOutputSignals = %d",
                         numberOfInputSignals, numberOfOutputSignals);
        }
    }
    if (ok) {
        TypeDescriptor inputSignalType = GetSignalType(InputSignals, 0u);
        TypeDescriptor outputSignalType = GetSignalType(OutputSignals, 0u);
        ok = (inputSignalType == outputSignalType);
        if (ok) {
            ok = (inputSignalType == UnsignedInteger32Bit);
        }
        if (!ok) {
            const char8 * const inputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(inputSignalType);
            const char8 * const outputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(outputSignalType);
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The type of the input and output signal shall be uint32. inputSignalType = %s outputSignalType = %s", inputSignalTypeStr,
                         outputSignalTypeStr);
        }
    }
    if (ok) {
        uint32 numberOfInputSamples = 0u;
        uint32 numberOfOutputSamples = 0u;
        ok = GetSignalNumberOfSamples(InputSignals, 0u, numberOfInputSamples);
        if (ok) {
            ok = GetSignalNumberOfSamples(OutputSignals, 0u, numberOfOutputSamples);
        }
        if (ok) {
            ok = (numberOfInputSamples == numberOfOutputSamples);
        }
        if (ok) {
            ok = (numberOfInputSamples == 1u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals samples shall be equal to 1. numberOfInputSamples = %d numberOfOutputSamples = %d",
                         numberOfInputSamples, numberOfOutputSamples);
        }
    }
    if (ok) {
        uint32 numberOfInputDimensions = 0u;
        uint32 numberOfOutputDimensions = 0u;
        ok = GetSignalNumberOfDimensions(InputSignals, 0u, numberOfInputDimensions);
        if (ok) {
            ok = GetSignalNumberOfDimensions(OutputSignals, 0u, numberOfOutputDimensions);
        }
        if (ok) {
            ok = (numberOfInputDimensions == numberOfOutputDimensions);
        }
        if (ok) {
            ok = (numberOfInputDimensions == 0u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals dimensions shall be equal to 0. numberOfInputDimensions = %d numberOfOutputDimensions = %d",
                         numberOfInputDimensions, numberOfOutputDimensions);
        }
    }
    if (ok) {
        uint32 numberOfInputElements = 0u;
        uint32 numberOfOutputElements = 0u;
        ok = GetSignalNumberOfElements(InputSignals, 0u, numberOfInputElements);
        if (ok) {
            ok = GetSignalNumberOfElements(OutputSignals, 0u, numberOfOutputElements);
        }
        if (ok) {
            ok = (numberOfInputElements == numberOfOutputElements);
        }
        if (ok) {
            ok = (numberOfInputElements == 1u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals elements shall be equal to 1. numberOfInputElements = %d numberOfOutputElements = %d",
                         numberOfInputElements, numberOfOutputElements);
        }
    }
    if (ok) {
        inputSignal = reinterpret_cast<uint32 *>(GetInputSignalMemory(0u));
        outputSignal = reinterpret_cast<uint32 *>(GetOutputSignalMemory(0u));
    }
    return ok;

}

bool FixedGAMExample1::Execute() {
    *outputSignal = gain * *inputSignal;
    return true;
}

CLASS_REGISTER(FixedGAMExample1, "")
}
Fixed signals configuration (Run with NAME_OF_THE_STATE=State1 and NAME_OF_THE_CONFIGURATION_FILE=GAMs-1.cfg)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
$TestApp = {
    Class = RealTimeApplication
    +Functions = {
        Class = ReferenceContainer
        +GAMTimer = {
            Class = IOGAM
            InputSignals = {
                Counter = {                	
                    DataSource = Timer
                    Type = uint32
                }                
                Time = {          
                    Frequency = 1                     
                    DataSource = Timer
                    Type = uint32
                }
            }
            OutputSignals = {
                Counter = {                	
                    DataSource = DDB1
                    Type = uint32
                }                
                Time = {                	
                    DataSource = DDB1
                    Type = uint32
                }            
            }
        }
        +GAMFixed1 = {
            Class = FixedGAMExample1
            Gain = 2
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }                
            }
            OutputSignals = {
                GainCounter = {
                    DataSource = DDB1
                    Type = uint32
                }                
            }
        }
        +GAMDisplay = {
            Class = IOGAM            
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter = {
                    DataSource = DDB1
                    Type = uint32
                }
            } 
            OutputSignals = {
                Counter = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
                GainCounter = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }               
            }
        }
    }
    +Data = {
        Class = ReferenceContainer
        DefaultDataSource = DDB1
        +DDB1 = {
            Class = GAMDataSource
       	}        
        +LoggerDataSource = {
            Class = LoggerDataSource
        }
        +Timings = {
            Class = TimingDataSource
        }
        +Timer = {
            Class = LinuxTimer
            SleepNature = "Default"
            Signals = {
                Counter = {
                    Type = uint32
                }
                Time = {
                    Type = uint32
                }
            }
        }        
    }
    +States = {
        Class = ReferenceContainer
        +State1 = {
            Class = RealTimeState
            +Threads = {
                Class = ReferenceContainer
                +Thread1 = {
                    Class = RealTimeThread
                    CPUs = 0x1
                    Functions = {GAMTimer GAMFixed1 GAMDisplay }
                }
            }
        }        
    }
    +Scheduler = {
        Class = GAMScheduler
        TimingDataSource = Timings
    }
}

Variable GAM

The following is an example of GAM which adapts to the number of output signals.

Variable signals GAM (VariableGAMExample1)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/**
 * @file VariableGAMExample1.cpp
 * @brief Source file for class VariableGAMExample1
 * @date 06/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class VariableGAMExample1 (public, protected, and private). Be aware that some
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "VariableGAMExample1.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/
namespace MARTe2Tutorial {
VariableGAMExample1::VariableGAMExample1() {
    numberOfOutputSignals = 0u;
    gains = NULL_PTR(MARTe::uint32 *);
    inputSignal = NULL_PTR(MARTe::uint32 *);
    outputSignals = NULL_PTR(MARTe::uint32 **);
}

VariableGAMExample1::~VariableGAMExample1() {
    if (gains != NULL_PTR(MARTe::uint32 *)) {
        delete[] gains;
    }
    if (outputSignals != NULL_PTR(MARTe::uint32 **)) {
        delete[] outputSignals;
    }
}

bool VariableGAMExample1::Initialise(MARTe::StructuredDataI & data) {
    using namespace MARTe;
    bool ok = GAM::Initialise(data);
    if (!ok) {
        REPORT_ERROR(ErrorManagement::ParametersError, "Could not Initialise the GAM");
    }
    if (ok) {
        AnyType arrayDescription = data.GetType("Gains");
        ok = arrayDescription.GetDataPointer() != NULL_PTR(void *);
        uint32 numberOfElements = 0u;
        if (ok) {
            numberOfElements = arrayDescription.GetNumberOfElements(0u);
            ok = (numberOfElements > 0u);
            if (!ok) {
                REPORT_ERROR(ErrorManagement::ParametersError, "No elements defined in the array");
            }
        }
        if (ok) {
            //Reconfiguration...
            if (gains != NULL) {
                delete [] gains;
            }
            gains = new uint32[numberOfElements];
            Vector<uint32> readVector(gains, numberOfElements);
            ok = data.Read("Gains", readVector);
            if (ok) {
                REPORT_ERROR(ErrorManagement::Information, "Gains set to %d", readVector);
            }
            else {
                REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gains");
            }
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError, "The parameter Gains shall be set as an array");
        }
    }
    return ok;
}

bool VariableGAMExample1::Setup() {
    using namespace MARTe;
    uint32 numberOfInputSignals = GetNumberOfInputSignals();
    numberOfOutputSignals = GetNumberOfOutputSignals();
    bool ok = (numberOfInputSignals == 1u);
    if (!ok) {
        REPORT_ERROR(ErrorManagement::ParametersError, "The number of input signals shall be equal to 1. numberOfInputSignals = %d ", numberOfInputSignals);
    }
    if (ok) {
        ok = (numberOfOutputSignals > 0u);
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError, "The number of output signals shall be greater than 1. numberOfOutputSignals = %d ",
                         numberOfOutputSignals);
        }
    }
    if (ok) {
        outputSignals = new uint32*[numberOfOutputSignals];
    }
    if (ok) {
        TypeDescriptor inputSignalType = GetSignalType(InputSignals, 0u);
        uint32 n;
        for (n = 0u; (n < numberOfOutputSignals) && (ok); n++) {
            StreamString outputSignalName;
            ok = GetSignalName(OutputSignals, n, outputSignalName);
            TypeDescriptor outputSignalType = GetSignalType(OutputSignals, n);
            ok = (inputSignalType == outputSignalType);
            if (ok) {
                ok = (inputSignalType == UnsignedInteger32Bit);
            }
            if (!ok) {
                const char8 * const inputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(inputSignalType);
                const char8 * const outputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(outputSignalType);
                REPORT_ERROR(ErrorManagement::ParametersError,
                             "The type of the input and output signals shall be uint32. inputSignalType = %s outputSignalType (%s) = %s", inputSignalTypeStr,
                             outputSignalName.Buffer(), outputSignalTypeStr);
            }

            uint32 numberOfInputSamples = 0u;
            uint32 numberOfOutputSamples = 0u;
            if (ok) {
                ok = GetSignalNumberOfSamples(InputSignals, 0u, numberOfInputSamples);
            }
            if (ok) {
                ok = GetSignalNumberOfSamples(OutputSignals, n, numberOfOutputSamples);
            }
            if (ok) {
                ok = (numberOfInputSamples == numberOfOutputSamples);
            }
            if (ok) {
                ok = (numberOfInputSamples == 1u);
                if (!ok) {
                    REPORT_ERROR(
                            ErrorManagement::ParametersError,
                            "The number of input and output signals samples shall be equal to 1. numberOfInputSamples = %d numberOfOutputSamples (%s) = %d",
                            numberOfInputSamples, outputSignalName.Buffer(), numberOfOutputSamples);
                }
            }
            uint32 numberOfInputDimensions = 0u;
            uint32 numberOfOutputDimensions = 0u;
            if (ok) {
                ok = GetSignalNumberOfDimensions(InputSignals, 0u, numberOfInputDimensions);
            }
            if (ok) {
                ok = GetSignalNumberOfDimensions(OutputSignals, n, numberOfOutputDimensions);
            }
            if (ok) {
                ok = (numberOfInputDimensions == numberOfOutputDimensions);
            }
            if (ok) {
                ok = (numberOfInputDimensions == 0u);
                if (!ok) {
                    REPORT_ERROR(
                            ErrorManagement::ParametersError,
                            "The number of input and output signals dimensions shall be equal to 0. numberOfInputDimensions = %d numberOfOutputDimensions (%s) = %d",
                            numberOfInputDimensions, outputSignalName.Buffer(), numberOfOutputDimensions);
                }
            }
            uint32 numberOfInputElements = 0u;
            uint32 numberOfOutputElements = 0u;
            if (ok) {
                ok = GetSignalNumberOfElements(InputSignals, 0u, numberOfInputElements);
            }
            if (ok) {
                ok = GetSignalNumberOfElements(OutputSignals, n, numberOfOutputElements);
            }
            if (ok) {
                ok = (numberOfInputElements == numberOfOutputElements);
            }
            if (ok) {
                ok = (numberOfInputElements == 1u);
            }
            if (!ok) {
                REPORT_ERROR(ErrorManagement::ParametersError,
                             "The number of input and output signals elements shall be equal to 1. numberOfInputElements = %d numberOfOutputElements (%s) = %d",
                             numberOfInputElements, outputSignalName.Buffer(), numberOfOutputElements);
            }
            if (ok) {
                outputSignals[n] = reinterpret_cast<uint32 *>(GetOutputSignalMemory(n));
            }
        }
        if (ok) {
            inputSignal = reinterpret_cast<uint32 *>(GetInputSignalMemory(0u));
        }
    }
    return ok;
}

bool VariableGAMExample1::Execute() {
    MARTe::uint32 n;
    for (n = 0u; (n < numberOfOutputSignals); n++) {
        *(outputSignals[n]) = gains[n] * *inputSignal;
    }
    return true;
}

CLASS_REGISTER(VariableGAMExample1, "")
}
Variable signals configuration (Run with NAME_OF_THE_STATE=State1 and NAME_OF_THE_CONFIGURATION_FILE=GAMs-2.cfg)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
$TestApp = {
    Class = RealTimeApplication
    +Functions = {
        Class = ReferenceContainer
        +GAMTimer = {
            Class = IOGAM
            InputSignals = {
                Counter = {                	
                    DataSource = Timer
                    Type = uint32
                }                
                Time = {          
                    Frequency = 1                     
                    DataSource = Timer
                    Type = uint32
                }
            }
            OutputSignals = {
                Counter = {                	
                    DataSource = DDB1
                    Type = uint32
                }                
                Time = {                	
                    DataSource = DDB1
                    Type = uint32
                }            
            }
        }
        +GAMVariable1 = {
            Class = VariableGAMExample1
            Gains = {2}
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }                
            }
            OutputSignals = {
                GainCounter1 = {
                    DataSource = DDB1
                    Type = uint32
                }                
            }
        }
        +GAMVariable2 = {
            Class = VariableGAMExample1
            Gains = {3, 4, 5}
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }                
            }
            OutputSignals = {
                GainCounter2 = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter3 = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter4 = {
                    DataSource = DDB1
                    Type = uint32
                }                          
            }
        }
        +GAMDisplay = {
            Class = IOGAM            
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter1 = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter2 = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter3 = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter4 = {
                    DataSource = DDB1
                    Type = uint32
                }                
            }
            OutputSignals = {
                Counter = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
                GainCounter1 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
                GainCounter2 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
                GainCounter3 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
                GainCounter4 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
            }
        }
    }
    +Data = {
        Class = ReferenceContainer
        DefaultDataSource = DDB1
        +DDB1 = {
        	Class = GAMDataSource
       	}        
        +LoggerDataSource = {
            Class = LoggerDataSource
        }
        +Timings = {
            Class = TimingDataSource
        }
        +Timer = {
            Class = LinuxTimer
            SleepNature = "Default"
            Signals = {
                Counter = {
                    Type = uint32
                }
                Time = {
                    Type = uint32
                }
            }
        }        
    }
    +States = {
        Class = ReferenceContainer
        +State1 = {
            Class = RealTimeState
            +Threads = {
                Class = ReferenceContainer
                +Thread1 = {
                    Class = RealTimeThread
                    CPUs = 0x1
                    Functions = {GAMTimer GAMVariable1 GAMVariable2 GAMDisplay }
                }
            }
        }        
    }
    +Scheduler = {
        Class = GAMScheduler
        TimingDataSource = Timings
    }
}

Structure GAM

The following is an example of GAM which uses a (registered) structured signal in input and output.

Structured signal GAM (ModelGAMExample1)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/**
 * @file ModelGAMExample1.cpp
 * @brief Source file for class ModelGAMExample1
 * @date 09/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class ModelGAMExample1 (public, protected, and private). Be aware that some 
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "IntrospectionT.h"
#include "ModelGAMExample1.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/
//Register the structures
DECLARE_CLASS_MEMBER(ModelGAMExampleStructInner1, f1, float32, "", "");
DECLARE_CLASS_MEMBER(ModelGAMExampleStructInner1, f2, float32, "", "");
DECLARE_CLASS_MEMBER(ModelGAMExampleStructInner1, f3, float32, "[6]", "");
//The array members must follow the naming convention CLASSNAME_MEMBERNAME_introspectionEntry
static const MARTe::IntrospectionEntry* ModelGAMExampleStructInner1Entries[] = { &ModelGAMExampleStructInner1_f1_introspectionEntry,
        &ModelGAMExampleStructInner1_f2_introspectionEntry, &ModelGAMExampleStructInner1_f3_introspectionEntry, 0 };
//Finally declare the class as introspectable
DECLARE_STRUCT_INTROSPECTION(ModelGAMExampleStructInner1, ModelGAMExampleStructInner1Entries)

DECLARE_CLASS_MEMBER(ModelGAMExampleStructSignal, u1, uint32, "", "");
DECLARE_CLASS_MEMBER(ModelGAMExampleStructSignal, s1, ModelGAMExampleStructInner1, "", "");
DECLARE_CLASS_MEMBER(ModelGAMExampleStructSignal, s2, ModelGAMExampleStructInner1, "", "");
//The array members must follow the naming convention CLASSNAME_MEMBERNAME_introspectionEntry
static const MARTe::IntrospectionEntry* ModelGAMExampleStructSignalEntries[] = { &ModelGAMExampleStructSignal_u1_introspectionEntry,
        &ModelGAMExampleStructSignal_s1_introspectionEntry, &ModelGAMExampleStructSignal_s2_introspectionEntry, 0 };
//Finally declare the class as introspectable
DECLARE_STRUCT_INTROSPECTION(ModelGAMExampleStructSignal, ModelGAMExampleStructSignalEntries)

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/

ModelGAMExample1::ModelGAMExample1() {
    inputSignal = NULL_PTR(ModelGAMExampleStructSignal *);
    outputSignal = NULL_PTR(ModelGAMExampleStructSignal *);
}

ModelGAMExample1::~ModelGAMExample1() {
}

bool ModelGAMExample1::CheckSignal(MARTe::SignalDirection signalDirection, MARTe::IntrospectionEntry introEntry, MARTe::uint32 signalIdx) {
    using namespace MARTe;
    TypeDescriptor signalMemberType = GetSignalType(signalDirection, signalIdx);
    TypeDescriptor introMemberType = introEntry.GetMemberTypeDescriptor();
    StreamString signalName;
    bool ok = GetSignalName(signalDirection, signalIdx, signalName);
    if (ok) {
        ok = (signalMemberType == introMemberType);
        if (!ok) {
            const char8 * const memberTypeTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(signalMemberType);
            const char8 * const introMemberTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(introMemberType);
            REPORT_ERROR(ErrorManagement::ParametersError, "Output type signal mismatch = %s != %s for signal %s", memberTypeTypeStr, introMemberTypeStr,
                         signalName.Buffer());
        }
    }
    if (ok) {
        uint32 numberOfOutputSamples = 0u;
        ok = GetSignalNumberOfSamples(signalDirection, signalIdx, numberOfOutputSamples);
        if (ok) {
            ok = (numberOfOutputSamples == 1u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError, "The number of output signals samples shall be equal to 1. numberOfOutputSamples = %d for signal %s",
                         signalIdx, numberOfOutputSamples, signalName.Buffer());
        }
    }
    uint32 introNumberOfElements = 1u;
    if (ok) {
        uint32 signalNumberOfDimensions = 0u;
        uint8 introMemberNumberOfDimensions = introEntry.GetNumberOfDimensions();
        ok = GetSignalNumberOfDimensions(signalDirection, signalIdx, signalNumberOfDimensions);
        if (ok) {
            ok = (signalNumberOfDimensions == introMemberNumberOfDimensions);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError, "Number of dimensions mismatch = %d != %d for signal %s", signalNumberOfDimensions,
                         introMemberNumberOfDimensions, signalName.Buffer());
            ok = true;
        }
        if (ok) {
            uint32 k;
            for (k = 0; k < introMemberNumberOfDimensions; k++) {
                introNumberOfElements *= introEntry.GetNumberOfElements(k);
            }
        }
    }
    if (ok) {
        uint32 signalNumberOfElements = 0u;
        ok = GetSignalNumberOfElements(signalDirection, signalIdx, signalNumberOfElements);
        if (ok) {
            ok = (signalNumberOfElements == introNumberOfElements);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError, "Number of elements mismatch = %d != %d for signal %s", signalNumberOfElements,
                         introNumberOfElements, signalName.Buffer());
        }
    }
    return ok;
}

bool ModelGAMExample1::Setup() {
    using namespace MARTe;
    uint32 numberOfInputSignals = GetNumberOfInputSignals();
    uint32 numberOfOutputSignals = GetNumberOfOutputSignals();
    bool ok = (numberOfInputSignals == numberOfOutputSignals);
    if (!ok) {
        REPORT_ERROR(ErrorManagement::ParametersError, "The number of input signals shall be equal to the number of output signals. numberOfInputSignals = %d != numberOfOutputSignals ", numberOfInputSignals, numberOfOutputSignals);
    }

    ClassRegistryItem *cri = NULL_PTR(ClassRegistryItem *);
    if (ok) {
        cri = ClassRegistryDatabase::Instance()->Find("ModelGAMExampleStructSignal");
        ok = (cri != NULL_PTR(ClassRegistryItem *));
        if (!ok) {
            REPORT_ERROR(ErrorManagement::FatalError, "ModelGAMExampleStructSignal is not registered!");
        }
    }
    const Introspection *introspectionMainStruct = NULL_PTR(Introspection *);
    if (ok) {
        introspectionMainStruct = cri->GetIntrospection();
    }
    if (ok) {
        cri = ClassRegistryDatabase::Instance()->Find("ModelGAMExampleStructInner1");
    }
    const Introspection *introspectionInnerStruct = NULL_PTR(Introspection *);
    if (ok) {
        introspectionInnerStruct = cri->GetIntrospection();
    }

    uint32 introspectionMainStructNumberOfMembers = 0u;
    if (ok) {
        //where +1 is the //u1
        introspectionMainStructNumberOfMembers = introspectionInnerStruct->GetNumberOfMembers() * 2 + 1;
    }
    if (ok) {
        //The structure has 7 signals
        ok = (numberOfOutputSignals == introspectionMainStructNumberOfMembers);
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError, "The number of output signals shall be equal to %d. numberOfOutputSignals = %d",
                         introspectionMainStructNumberOfMembers, numberOfOutputSignals);
        }
    }
    //Check that all the properties match
    if (ok) {
        ok = CheckSignal(InputSignals, introspectionMainStruct->operator [](0), 0);
    }
    if (ok) {
        ok = CheckSignal(InputSignals, introspectionInnerStruct->operator [](0), 1);
    }
    if (ok) {
        ok = CheckSignal(InputSignals, introspectionInnerStruct->operator [](1), 2);
    }
    if (ok) {
        ok = CheckSignal(InputSignals, introspectionInnerStruct->operator [](2), 3);
    }
    if (ok) {
        ok = CheckSignal(InputSignals, introspectionInnerStruct->operator [](0), 4);
    }
    if (ok) {
        ok = CheckSignal(InputSignals, introspectionInnerStruct->operator [](1), 5);
    }
    if (ok) {
        ok = CheckSignal(InputSignals, introspectionInnerStruct->operator [](2), 6);
    }
    if (ok) {
        ok = CheckSignal(OutputSignals, introspectionMainStruct->operator [](0), 0);
    }
    if (ok) {
        ok = CheckSignal(OutputSignals, introspectionInnerStruct->operator [](0), 1);
    }
    if (ok) {
        ok = CheckSignal(OutputSignals, introspectionInnerStruct->operator [](1), 2);
    }
    if (ok) {
        ok = CheckSignal(OutputSignals, introspectionInnerStruct->operator [](2), 3);
    }
    if (ok) {
        ok = CheckSignal(OutputSignals, introspectionInnerStruct->operator [](0), 4);
    }
    if (ok) {
        ok = CheckSignal(OutputSignals, introspectionInnerStruct->operator [](1), 5);
    }
    if (ok) {
        ok = CheckSignal(OutputSignals, introspectionInnerStruct->operator [](2), 6);
    }
    if (ok) {
        inputSignal = reinterpret_cast<ModelGAMExampleStructSignal *>(GetInputSignalMemory(0u));
    }
    if (ok) {
        outputSignal = reinterpret_cast<ModelGAMExampleStructSignal *>(GetOutputSignalMemory(0u));
    }
    return ok;
}

bool ModelGAMExample1::Execute() {
    MARTe::float32 gain1 = 1.02;
    MARTe::float32 gain2 = 1.03;
    (outputSignal->u1)++;
    outputSignal->s1.f1 = gain1 * inputSignal->s1.f1;
    outputSignal->s1.f2 = gain2 * inputSignal->s1.f2;
    outputSignal->s1.f3[0] = inputSignal->s1.f1;
    outputSignal->s1.f3[1] = -inputSignal->s1.f1;
    outputSignal->s1.f3[2] = inputSignal->s1.f2;
    outputSignal->s1.f3[3] = -inputSignal->s1.f2;
    outputSignal->s1.f3[4] = inputSignal->s1.f1 + inputSignal->s1.f2;
    outputSignal->s1.f3[5] = inputSignal->s1.f1 - inputSignal->s1.f2;
    outputSignal->s2.f1 = gain1 * inputSignal->s2.f1;
    outputSignal->s2.f2 = gain2 * inputSignal->s2.f2;
    outputSignal->s2.f3[0] = inputSignal->s2.f1;
    outputSignal->s2.f3[1] = -inputSignal->s2.f1;
    outputSignal->s2.f3[2] = inputSignal->s2.f2;
    outputSignal->s2.f3[3] = -inputSignal->s2.f2;
    outputSignal->s2.f3[4] = inputSignal->s2.f1 - inputSignal->s2.f2;
    outputSignal->s2.f3[5] = inputSignal->s2.f1 + inputSignal->s2.f2;
    return true;
}

CLASS_REGISTER(ModelGAMExample1, "")
Structured signals configuration (Run with NAME_OF_THE_STATE=State1 and NAME_OF_THE_CONFIGURATION_FILE=GAMs-3.cfg)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
$TestApp = {
    Class = RealTimeApplication
    +Functions = {
        Class = ReferenceContainer
        +GAMTimer = {
            Class = IOGAM
            InputSignals = {
                Counter = {
                    DataSource = Timer
                    Type = uint32
                }
                Time = {
                    Frequency = 1
                    DataSource = Timer
                    Type = uint32
                }
            }
            OutputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }
                Time = {
                    DataSource = DDB1
                    Type = uint32
                }
            }
        }
        +GAMModel1 = {
            Class = ModelGAMExample1
            InputSignals = {
                Model1 = {
                    DataSource = DDB1
                    Type = ModelGAMExampleStructSignal
                    Defaults = {
                        Model1.s1.f1 = 2
                        Model1.s1.f2 = 3
                        Model1.s1.f3 = {1, 2, 3, 4, 5, 6}
                        Model1.s2.f1 = -2
                        Model1.s2.f2 = -3
                        Model1.s2.f3 = {-1, -2, -3, -4, -5, -6}
                    }
                    MemberAliases = {
                        Model1.s2.f2 = Model1.s2.g2
                    }
                }
            }
            OutputSignals = {
                Model1 = {
                    DataSource = DDB1
                    Type = ModelGAMExampleStructSignal
                    MemberAliases = {
                    	Model1.s2.f2 = Model1.s2.g2
                    }
                }
            }
        }
        +GAMDisplay = {
            Class = IOGAM
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }
                Model1U1 = {
                    DataSource = DDB1
                    Alias = "Model1.u1"
                    Type = uint32
                }
                Model1S1F1 = {
                    DataSource = DDB1
                    Alias = "Model1.s1.f1"
                    Type = float32
                }
                Model1S1F2 = {
                    DataSource = DDB1
                    Alias = "Model1.s1.f2"
                    Type = float32
                }
                Model1S1F3 = {
                    DataSource = DDB1
                    Alias = "Model1.s1.f3"
                    Type = float32
                }
                Model1S2F1 = {
                    DataSource = DDB1
                    Alias = "Model1.s2.f1"
                    Type = float32
                }
                Model1S2G2 = {
                    DataSource = DDB1
                    Alias = "Model1.s2.g2"
                    Type = float32
                }
                Model1S2F3 = {
                    DataSource = DDB1
                    Alias = "Model1.s2.f3"
                    Type = float32
                }
            }
            OutputSignals = {
                Counter = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
                Model1U1 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }      
                Model1S1F1 = {
                    DataSource = LoggerDataSource
                    Type = float32
                }
                Model1S1F2 = {
                    DataSource = LoggerDataSource
                    Type = float32
                }
                Model1S1F3 = {
                    DataSource = LoggerDataSource
                    Type = float32
                    NumberOfDimensions = 1
                    NumberOfElements = 6
                }                
                Model1S2F1 = {
                    DataSource = LoggerDataSource
                    Type = float32
                }
                Model1S2G2 = {
                    DataSource = LoggerDataSource
                    Type = float32
                }
                Model1S2F3 = {
                    DataSource = LoggerDataSource
                    Type = float32
                    NumberOfDimensions = 1
                    NumberOfElements = 6
                }
            }
        }
    }
    +Data = {
        Class = ReferenceContainer
        DefaultDataSource = DDB1
        +DDB1 = {
            Class = GAMDataSource
       	}
        +LoggerDataSource = {
            Class = LoggerDataSource
        }
        +Timings = {
            Class = TimingDataSource
        }
        +Timer = {
            Class = LinuxTimer
            SleepNature = "Default"
            Signals = {
                Counter = {
                    Type = uint32
                }
                Time = {
                    Type = uint32
                }
            }
        }
    }
    +States = {
        Class = ReferenceContainer
        +State1 = {
            Class = RealTimeState
            +Threads = {
                Class = ReferenceContainer
                +Thread1 = {
                    Class = RealTimeThread
                    CPUs = 0x1
                    Functions = {GAMTimer GAMModel1 GAMDisplay }
                }
            }
        }
    }
    +Scheduler = {
        Class = GAMScheduler
        TimingDataSource = Timings
    }
}

GAMGroup

The following is an example of GAMGroup which shares a Matrix with several GAMs.

Parent GAMGroup which shares a Matrix with the ChildGAMGroupExample1 and ChildGAMGroupExample2 instances.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
 * @file ParentGAMGroupExample1.cpp
 * @brief Source file for class ParentGAMGroupExample1
 * @date 06/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class ParentGAMGroupExample1 (public, protected, and private). Be aware that some
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "ParentGAMGroupExample1.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/
namespace MARTe2Tutorial {
ParentGAMGroupExample1::ParentGAMGroupExample1() {
}

ParentGAMGroupExample1::~ParentGAMGroupExample1() {

}

bool ParentGAMGroupExample1::Initialise(MARTe::StructuredDataI & data) {
    using namespace MARTe;
    bool ok = GAMGroup::Initialise(data);
    matrixModelContext = MARTe::ReferenceT<GAMGroupSharedInfoExample1>(GlobalObjectsDatabase::Instance()->GetStandardHeap());
    if (ok) {
        ok = matrixModelContext.IsValid();
    }
    if (ok) {
        ok = matrixModelContext->Initialise(data);
    }
    return ok;
}

bool ParentGAMGroupExample1::PrepareNextState(const MARTe::char8*, const MARTe::char8*) {
    using namespace MARTe;
    bool ok = matrixModelContext.IsValid();
    if (ok) {
        ok = SetContext(matrixModelContext);
    }
    return ok;
}

CLASS_REGISTER(ParentGAMGroupExample1, "")
}
Child GAMGroup which shares a Matrix with the ParentGAMGroupExample1 instance.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
 * @file ChildGAMGroupExample1.cpp
 * @brief Source file for class ChildGAMGroupExample1
 * @date 06/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class ChildGAMGroupExample1 (public, protected, and private). Be aware that some
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "ChildGAMGroupExample1.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/
namespace MARTe2Tutorial {

ChildGAMGroupExample1::ChildGAMGroupExample1() {
    contextSet = false;
    inputSignal = NULL_PTR(MARTe::Matrix<MARTe::uint32> *);
    outputSignal = NULL_PTR(MARTe::Matrix<MARTe::uint32> *);
}

ChildGAMGroupExample1::~ChildGAMGroupExample1() {
    if (inputSignal != NULL_PTR(MARTe::Matrix<MARTe::uint32> *)) {
        delete inputSignal;
    }
    if (outputSignal != NULL_PTR(MARTe::Matrix<MARTe::uint32> *)) {
        delete outputSignal;
    }
}

bool ChildGAMGroupExample1::Setup() {
    using namespace MARTe;
    uint32 numberOfInputSignals = GetNumberOfInputSignals();
    uint32 numberOfOutputSignals = GetNumberOfOutputSignals();
    bool ok = (numberOfInputSignals == numberOfOutputSignals);
    if (ok) {
        ok = (numberOfOutputSignals == 1u);
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals shall be equal to 1. numberOfInputSignals = %d numberOfOutputSignals = %d",
                         numberOfInputSignals, numberOfOutputSignals);
        }
    }
    if (ok) {
        TypeDescriptor inputSignalType = GetSignalType(InputSignals, 0u);
        TypeDescriptor outputSignalType = GetSignalType(OutputSignals, 0u);
        ok = (inputSignalType == outputSignalType);
        if (ok) {
            ok = (inputSignalType == UnsignedInteger32Bit);
        }
        if (!ok) {
            const char8 * const inputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(inputSignalType);
            const char8 * const outputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(outputSignalType);
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The type of the input and output signal shall be uint32. inputSignalType = %s outputSignalType = %s", inputSignalTypeStr,
                         outputSignalTypeStr);
        }
    }
    if (ok) {
        uint32 numberOfInputSamples = 0u;
        uint32 numberOfOutputSamples = 0u;
        ok = GetSignalNumberOfSamples(InputSignals, 0u, numberOfInputSamples);
        if (ok) {
            ok = GetSignalNumberOfSamples(OutputSignals, 0u, numberOfOutputSamples);
        }
        if (ok) {
            ok = (numberOfInputSamples == numberOfOutputSamples);
        }
        if (ok) {
            ok = (numberOfInputSamples == 1u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals samples shall be equal to 1. numberOfInputSamples = %d numberOfOutputSamples = %d",
                         numberOfInputSamples, numberOfOutputSamples);
        }
    }
    if (ok) {
        uint32 numberOfInputDimensions = 0u;
        uint32 numberOfOutputDimensions = 0u;
        ok = GetSignalNumberOfDimensions(InputSignals, 0u, numberOfInputDimensions);
        if (ok) {
            ok = GetSignalNumberOfDimensions(OutputSignals, 0u, numberOfOutputDimensions);
        }
        if (ok) {
            ok = (numberOfInputDimensions == numberOfOutputDimensions);
        }
        if (ok) {
            ok = (numberOfInputDimensions == 1u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals dimensions shall be equal to 1. numberOfInputDimensions = %d numberOfOutputDimensions = %d",
                         numberOfInputDimensions, numberOfOutputDimensions);
        }
    }
    return ok;

}

bool ChildGAMGroupExample1::SetContext(ConstReference context) {
    using namespace MARTe;

    matrixModelContext = context;
    contextSet = context.IsValid();
    bool ok = contextSet;
    //Check that the matrix dimensions are valid.
    uint32 numberOfInputElements = 0u;
    uint32 numberOfOutputElements = 0u;
    if (ok) {
        ok = GetSignalNumberOfElements(InputSignals, 0u, numberOfInputElements);
        if (ok) {
            ok = GetSignalNumberOfElements(OutputSignals, 0u, numberOfOutputElements);
        }
        if (ok) {
            ok = (numberOfInputElements == matrixModelContext->matrixModel->GetNumberOfRows());
        }
        if (ok) {
            ok = (numberOfInputElements == numberOfOutputElements);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
            "The number of input and output signals elements shall be equal. numberOfInputElements = %d numberOfOutputElements = %d",
            numberOfInputElements, numberOfOutputElements);
        }
    }
    if (ok) {
        inputSignal = new Matrix<uint32>(reinterpret_cast<uint32 *>(GetInputSignalMemory(0u)), numberOfInputElements, 1);
        outputSignal = new Matrix<uint32>(reinterpret_cast<uint32 *>(GetOutputSignalMemory(0u)), numberOfOutputElements, 1);
    }

    return contextSet;
}

bool ChildGAMGroupExample1::Execute() {
    using namespace MARTe;
    if (contextSet) {
        matrixModelContext->matrixModel->Product(*inputSignal, *outputSignal);
    }
    return contextSet;
}

CLASS_REGISTER(ChildGAMGroupExample1, "")
}
Child GAMGroup which shares a Matrix with the ParentGAMGroupExample1 instance.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/**
 * @file ChildGAMGroupExample2.cpp
 * @brief Source file for class ChildGAMGroupExample2
 * @date 06/04/2018
 * @author Andre Neto
 *
 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
 * the Development of Fusion Energy ('Fusion for Energy').
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 *
 * @warning Unless required by applicable law or agreed to in writing, 
 * software distributed under the Licence is distributed on an "AS IS"
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the Licence permissions and limitations under the Licence.

 * @details This source file contains the definition of all the methods for
 * the class ChildGAMGroupExample2 (public, protected, and private). Be aware that some
 * methods, such as those inline could be defined on the header file, instead.
 */

/*---------------------------------------------------------------------------*/
/*                         Standard header includes                          */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                         Project header includes                           */
/*---------------------------------------------------------------------------*/
#include "AdvancedErrorManagement.h"
#include "ChildGAMGroupExample2.h"

/*---------------------------------------------------------------------------*/
/*                           Static definitions                              */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*                           Method definitions                              */
/*---------------------------------------------------------------------------*/
namespace MARTe2Tutorial {

ChildGAMGroupExample2::ChildGAMGroupExample2() {
    contextSet = false;
    inputSignal = NULL_PTR(MARTe::Matrix<MARTe::uint32> *);
    outputSignal = NULL_PTR(MARTe::Matrix<MARTe::uint32> *);
    transposedModel = NULL_PTR(MARTe::Matrix<MARTe::uint32> *);
}

ChildGAMGroupExample2::~ChildGAMGroupExample2() {
    if (inputSignal != NULL_PTR(MARTe::Matrix<MARTe::uint32> *)) {
        delete inputSignal;
    }
    if (outputSignal != NULL_PTR(MARTe::Matrix<MARTe::uint32> *)) {
        delete outputSignal;
    }
    if (transposedModel != NULL_PTR(MARTe::Matrix<MARTe::uint32> *)) {
        delete transposedModel;
    }
}

bool ChildGAMGroupExample2::Setup() {
    using namespace MARTe;
    uint32 numberOfInputSignals = GetNumberOfInputSignals();
    uint32 numberOfOutputSignals = GetNumberOfOutputSignals();
    bool ok = (numberOfInputSignals == numberOfOutputSignals);
    if (ok) {
        ok = (numberOfOutputSignals == 1u);
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals shall be equal to 1. numberOfInputSignals = %d numberOfOutputSignals = %d",
                         numberOfInputSignals, numberOfOutputSignals);
        }
    }
    if (ok) {
        TypeDescriptor inputSignalType = GetSignalType(InputSignals, 0u);
        TypeDescriptor outputSignalType = GetSignalType(OutputSignals, 0u);
        ok = (inputSignalType == outputSignalType);
        if (ok) {
            ok = (inputSignalType == UnsignedInteger32Bit);
        }
        if (!ok) {
            const char8 * const inputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(inputSignalType);
            const char8 * const outputSignalTypeStr = TypeDescriptor::GetTypeNameFromTypeDescriptor(outputSignalType);
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The type of the input and output signal shall be uint32. inputSignalType = %s outputSignalType = %s", inputSignalTypeStr,
                         outputSignalTypeStr);
        }
    }
    if (ok) {
        uint32 numberOfInputSamples = 0u;
        uint32 numberOfOutputSamples = 0u;
        ok = GetSignalNumberOfSamples(InputSignals, 0u, numberOfInputSamples);
        if (ok) {
            ok = GetSignalNumberOfSamples(OutputSignals, 0u, numberOfOutputSamples);
        }
        if (ok) {
            ok = (numberOfInputSamples == numberOfOutputSamples);
        }
        if (ok) {
            ok = (numberOfInputSamples == 1u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals samples shall be equal to 1. numberOfInputSamples = %d numberOfOutputSamples = %d",
                         numberOfInputSamples, numberOfOutputSamples);
        }
    }
    if (ok) {
        uint32 numberOfInputDimensions = 0u;
        uint32 numberOfOutputDimensions = 0u;
        ok = GetSignalNumberOfDimensions(InputSignals, 0u, numberOfInputDimensions);
        if (ok) {
            ok = GetSignalNumberOfDimensions(OutputSignals, 0u, numberOfOutputDimensions);
        }
        if (ok) {
            ok = (numberOfInputDimensions == numberOfOutputDimensions);
        }
        if (ok) {
            ok = (numberOfInputDimensions == 1u);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
                         "The number of input and output signals dimensions shall be equal to 1. numberOfInputDimensions = %d numberOfOutputDimensions = %d",
                         numberOfInputDimensions, numberOfOutputDimensions);
        }
    }
    return ok;

}

bool ChildGAMGroupExample2::SetContext(ConstReference context) {
    using namespace MARTe;

    matrixModelContext = context;
    contextSet = context.IsValid();
    bool ok = contextSet;
    //Check that the matrix dimensions are valid.
    uint32 numberOfInputElements = 0u;
    uint32 numberOfOutputElements = 0u;
    if (ok) {
        ok = GetSignalNumberOfElements(InputSignals, 0u, numberOfInputElements);
        if (ok) {
            ok = GetSignalNumberOfElements(OutputSignals, 0u, numberOfOutputElements);
        }
        if (ok) {
            ok = (numberOfInputElements == matrixModelContext->matrixModel->GetNumberOfRows());
        }
        if (ok) {
            ok = (numberOfInputElements == numberOfOutputElements);
        }
        if (!ok) {
            REPORT_ERROR(ErrorManagement::ParametersError,
            "The number of input and output signals elements shall be equal. numberOfInputElements = %d numberOfOutputElements = %d",
            numberOfInputElements, numberOfOutputElements);
        }
    }
    if (ok) {
        inputSignal = new Matrix<uint32>(reinterpret_cast<uint32 *>(GetInputSignalMemory(0u)), numberOfInputElements, 1);
        outputSignal = new Matrix<uint32>(reinterpret_cast<uint32 *>(GetOutputSignalMemory(0u)), numberOfOutputElements, 1);
        transposedModel = new Matrix<uint32>(numberOfInputElements, numberOfInputElements);
    }

    return contextSet;
}

bool ChildGAMGroupExample2::Execute() {
    using namespace MARTe;
    if (contextSet) {
        matrixModelContext->matrixModel->Transpose(*transposedModel);
        transposedModel->Product(*inputSignal, *outputSignal);
    }
    return contextSet;
}

CLASS_REGISTER(ChildGAMGroupExample2, "")
}
GAMGroup example (Run with NAME_OF_THE_STATE=State1 and NAME_OF_THE_CONFIGURATION_FILE=GAMs-4.cfg)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
$TestApp = {
    Class = RealTimeApplication
    +Functions = {
        Class = ReferenceContainer
        +GAMTimer = {
            Class = IOGAM
            InputSignals = {
                Counter = {
                    DataSource = Timer
                    Type = uint32
                }
                Time = {
                    Frequency = 1
                    DataSource = Timer
                    Type = uint32
                }
            }
            OutputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }
                Time = {
                    DataSource = DDB1
                    Type = uint32
                }
            }
        }
        +GAMFixed1 = {
            Class = FixedGAMExample1
            Gain = 2
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }
            }
            OutputSignals = {
                GainCounter = {
                    DataSource = DDB1
                    Type = uint32
                }
            }
        }
        +GAMGroup1 = {
            Class = ParentGAMGroupExample1
            Model = {{2, 0, 0}, {0, 3, 0}, {1, 0, 4}}
            +GAMChild1 = {
                Class = ChildGAMGroupExample1
                InputSignals = {
                    Signal3 = {
                        DataSource = DDB1
                        Type = uint32
                        NumberOfDimensions = 1
                        NumberOfElements = 3
                    }
                }
                OutputSignals = {
                    Signal1 = {
                        DataSource = DDB1
                        Type = uint32
                        NumberOfDimensions = 1 
                        NumberOfElements = 3
                        Default = {1, 1, 1}
                    }
                 }
            } 
            +GAMChild2 = {
                Class = ChildGAMGroupExample2
                InputSignals = {
                    Signal1 = {
                        DataSource = DDB1
                        Type = uint32
                        NumberOfDimensions = 1
                        NumberOfElements = 3
                    }
                }
                OutputSignals = {
                    Signal2 = {
                        DataSource = DDB1
                        Type = uint32
                        NumberOfDimensions = 1 
                        NumberOfElements = 3
                        Default = {1, 1, 1}
                    }
                 }
            }
            +GAMChild3 = {
                Class = ChildGAMGroupExample1
                InputSignals = {
                    Signal2 = {
                        DataSource = DDB1
                        Type = uint32
                        NumberOfDimensions = 1 
                        NumberOfElements = 3
                    }
                }
                OutputSignals = {
                    Signal3 = {
                        DataSource = DDB1
                        Type = uint32
                        NumberOfDimensions = 1 
                        NumberOfElements = 3
                        Default = {1, 1, 1}
                    }
                }
             }
        }
        +GAMDisplay = {
            Class = IOGAM
            InputSignals = {
                Counter = {
                    DataSource = DDB1
                    Type = uint32
                }
                GainCounter = {
                    DataSource = DDB1
                    Type = uint32
                }
                Signal1 = {
                    DataSource = DDB1
                    Type = uint32
                }
                Signal2 = {
                    DataSource = DDB1
                    Type = uint32
                }
                Signal3 = {
                    DataSource = DDB1
                    Type = uint32
                }
            }
            OutputSignals = {
                Counter = {
                    DataSource = LoggerDataSource
                    Type = uint32
                }
                GainCounter = {
                    DataSource = LoggerDataSource
                    Type = uint32
                } 
                Signal1 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                    NumberOfElements = 3
                    NumberOfDimensions = 1
                }              
                Signal2 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                    NumberOfElements = 3
                    NumberOfDimensions = 1
                }
                Signal3 = {
                    DataSource = LoggerDataSource
                    Type = uint32
                    NumberOfElements = 3
                    NumberOfDimensions = 1
                }
            }
        }
    }
    +Data = {
        Class = ReferenceContainer
        DefaultDataSource = DDB1
        +DDB1 = {
            Class = GAMDataSource
        }        
        +LoggerDataSource = {
            Class = LoggerDataSource
        }
        +Timings = {
            Class = TimingDataSource
        }
        +Timer = {
            Class = LinuxTimer
            SleepNature = "Default"
            Signals = {
                Counter = {
                    Type = uint32
                }
                Time = {
                    Type = uint32
                }
            }
        }
    }
    +States = {
        Class = ReferenceContainer
        +State1 = {
            Class = RealTimeState
            +Threads = {
                Class = ReferenceContainer
                +Thread1 = {
                    Class = RealTimeThread
                    CPUs = 0x1
                    //Note that only the GAMGroup1 has to be scheduled for execution (all the GAMGroup child GAMs will be automatically executed)
                    Functions = {GAMTimer GAMFixed1 GAMGroup1 GAMDisplay }
                }
            }
        }
    }
    +Scheduler = {
        Class = GAMScheduler
        TimingDataSource = Timings
    }
}

Instructions on how to compile and execute the examples can be found here.