Data-driven applications

Using the mechanisms described in the Objects and References and in the Object configuration sections, together with a special syntax, the framework is capable of instantiating a tree of objects based on a configuration stream (e.g. a file).

Syntax

The Initialise method of the ReferenceContainer will look for any name starting with the character +.

When the + character is found, the property Class=LIB::CLASS shall exist in the subtree. LIB is the name of the shared library holding the compiled CLASS.

The CLASS shall inherit from Object and shall implement the macros defined in the Objects section.

If LIB is not defined, it is assumed that the class was already registered (e.g. because it was statically linked) or that the name of the library is equal to the name of the class.

This process is recursively repeated and a tree of Objects is built. The name of the Object is automatically set to the name of the node.

In the following example, an object named A, of type AClass, would be created, together with another object of type AClass, named B, and with an object of type CClass named C. It is assumed that the AClass inherits from ReferenceContainer and that, as a consequence, calling Get(0) on the instance named B would return a Reference to C.

+A = {
   Class = AClass
}
+B = {
   Class = AClass
   +C = {
      Class = ALIB::CClass
   }
}

The ObjectRegistryDatabase is a ReferenceContainer which offers a database to hold and link all the Objects defined in a given configuration stream.

The Find method can be used to find any of the instantiated Objects in the tree.

A dot . is used as the path separator.

...
ObjectRegistryDatabase *ord = ObjectRegistryDatabase::Instance();
ReferenceT<CClass> obj = ord->Find("B.C");
if (obj.IsValid()) {
   ...

If the node name starts with a $, besides implementing the same behaviour described before for the +, it will also set the node as a search domain.

This means that when using the ObjectRegistryDatabase Find method, the : symbol will allow to perform searches related to a given root domain. For example:

+A = {
   Class = AClass
   $B = {
      Class = BClass
      +C = {
         Class = CClass
         +E = {
             Class = EClass
         }
      }
      +D = {
         Class = DClass
         +F = {
             Class = CClass
         }
      }
   }
}

Would allow to Find C, C.E, D and D.F, using B as the root domain (see the example below).

Note

Other characters can also be set as a identifiers for the new Object creation and for the setting of a given Object as the root domain. See the methods AddBuildToken, RemoveBuildToken, IsBuildToken, AddDomainToken, RemoveDomainToken and IsDomainToken in ReferenceContainer.

Reading C structures

If a C struct has been registered in the ClassRegistryDatabase it is possible to directly map the contents of a configuration node to the registered structure (see example below).

To read/write a registered structure an AnyType which describes the registered type must be created:

struct AStruct {
   float32 f1;
   float32 f2;
};
///Register the struct with the required macros.
AStruct aStruct1;
AStruct aStruct2;
ClassRegistryItem * registeredStructClassProperties = ClassRegistryDatabase::Instance()->Find("AStruct");
...
ClassUID registeredStructUID = registeredStructClassProperties->GetUniqueIdentifier();
TypeDescriptor registeredStructTypeDescriptor(false, registeredStructUID);
AnyType registeredStructAnyType1 = AnyType(registeredStructTypeDescriptor, 0u, &aStruct1);
AnyType registeredStructAnyType2 = AnyType(registeredStructTypeDescriptor, 0u, &aStruct2);
...
data.Read("AStruct1", registeredStructAnyType1);
data.Read("AStruct2", registeredStructAnyType2);
...
if (aStruct1.f1 == aStruct2.f1) {
...

Note

Only the types and structure of the configuration tree must match with the types and structure of the C struct, i.e. the names are ignored.

Reading data-driven C structures

The IntrospectionStructure class can also be used to dynamically create and register structures using a standard configuration file.

+Types = {
    Class = ReferenceContainer
    +GainFromIntroStructure = {
        Class = IntrospectionStructure
        gain1 = {
            Type = float32
            NumberOfElements = {1}
        }
        gain2 = {
            Type = float32
            NumberOfElements = {1}
        }
        gain3 = {
            Type = float32
            NumberOfElements = {6}
        }
    }
    +GainsFromIntroStructure = {
         Class = IntrospectionStructure
         lowGains = {
         Type = GainFromIntroStructure
    }
    ...

Preprocessing

The MARTe configuration files can be preprocessed using the C preprocessor directives (e.g. #include and #define).

This strategy can be used to write modular configuration settings (see example below). Note that the files must first be processed with a Makefile.inc and a Makefile.cfg, following the MARTe Makefile structure:

Makefile.inc
 #Named of the unit files to be compiled. It will generate files named *_Gen.cfg (e.g. RTApp-6_Gen.cfg)
 OBJSX=RTApp-6.x

 #Location of the Build directory where the configuration file will be written to
 BUILD_DIR?=.

 #Location of the MakeDefaults directory.
 #Note that the MARTe2_DIR environment variable
 #must have been exported before
 MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults

 include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)

 CFLAGS += -DENABLE_WEB_BROWSING

 all: $(OBJS)
     echo  $(OBJS)

 include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
Makefile.cfg
 export TARGET=cfg

 include Makefile.inc

Postprocessing

As of v1.7.0, the StandardParser also allows to post-process and assign simple mathematical expressions to nodes in the tree. The syntax is NODE=(OUTPUT_VAR_TYPE|EXPRESSION), where OUTPUT_VAR_TYPE is the output variable type (e.g. uint32) and EXPRESSION is the mathematical expression to be executed.

The variables in the expression can reference to other nodes in the configuration tree, noting that the expressions are executed in order (top to bottom) and that the names in the node path cannot include the + sign.

int a =3;
Parameters = {
    T1_FREQUENCY = (uint32)10000
    T2_FREQUENCY = (uint32)1
    SAMPLES = (uint32|"Parameters.T1_FREQUENCY / Parameters.T2_FREQUENCY")
}
+TestApp = {
    Class = RealTimeApplication
    +Functions = {
        Class = ReferenceContainer
        +GAMTimer = {
            Class = IOGAM
            InputSignals = {
                Time = {
                    Frequency = (uint32|"(uint32)2 * Parameters.T1_FREQUENCY")
                    ...

Examples

The following example shows how to load an application from a configuration file.

Note that Objects can be nested inside other Objects (provided that the container Object inherits from ReferenceContainer and that it calls ReferenceContainer::Initialise on its Initialise method).

Data driven application example (ConfigurationExample4)
  1/**
  2 * @file ConfigurationExample4.cpp
  3 * @brief Source file for class ConfigurationExample4
  4 * @date 14/03/2018
  5 * @author Andre' Neto
  6 *
  7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
  8 * the Development of Fusion Energy ('Fusion for Energy').
  9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 11 * You may not use this work except in compliance with the Licence.
 12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 13 *
 14 * @warning Unless required by applicable law or agreed to in writing, 
 15 * software distributed under the Licence is distributed on an "AS IS"
 16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 17 * or implied. See the Licence permissions and limitations under the Licence.
 18
 19 * @details This source file contains the definition of all the methods for
 20 * the class ConfigurationExample4 (public, protected, and private). Be aware that some
 21 * methods, such as those inline could be defined on the header file, instead.
 22 */
 23
 24#define DLL_API
 25
 26/*---------------------------------------------------------------------------*/
 27/*                         Standard header includes                          */
 28/*---------------------------------------------------------------------------*/
 29
 30/*---------------------------------------------------------------------------*/
 31/*                         Project header includes                           */
 32/*---------------------------------------------------------------------------*/
 33#include "AdvancedErrorManagement.h"
 34#include "ClassRegistryDatabase.h"
 35#include "ConfigurationDatabase.h"
 36#include "ErrorLoggerExample.h"
 37#include "Matrix.h"
 38#include "Object.h"
 39#include "ObjectRegistryDatabase.h"
 40#include "Reference.h"
 41#include "ReferenceT.h"
 42#include "StandardParser.h"
 43#include "StreamString.h"
 44#include "Vector.h"
 45
 46/*---------------------------------------------------------------------------*/
 47/*                           Static definitions                              */
 48/*---------------------------------------------------------------------------*/
 49
 50/*---------------------------------------------------------------------------*/
 51/*                           Method definitions                              */
 52/*---------------------------------------------------------------------------*/
 53namespace MARTe2Tutorial {
 54
 55/**
 56 * Configuration structures
 57 */
 58struct Gains {
 59    MARTe::float32 gain1;
 60    MARTe::float32 gain2;
 61};
 62
 63struct Waveforms {
 64    MARTe::float32 *times;
 65    MARTe::float32 *values;
 66};
 67
 68/**
 69 * @brief A MARTe::Object that will be inserted (data-driven) inside the ControllerEx1.
 70 */
 71class ReferenceEx1: public MARTe::Object {
 72public:
 73    CLASS_REGISTER_DECLARATION()
 74
 75ReferenceEx1    () {
 76        waveform.times = NULL;
 77        waveform.values = NULL;
 78    }
 79
 80    virtual ~ReferenceEx1 () {
 81        if (waveform.times != NULL) {
 82            delete [] waveform.times;
 83        }
 84        if (waveform.values != NULL) {
 85            delete [] waveform.values;
 86        }
 87        if (GetName() != NULL) {
 88            REPORT_ERROR_STATIC(MARTe::ErrorManagement::Information, "No more references pointing"
 89                    " at %s [%s]. The Object will be safely deleted.", GetName(), GetClassProperties()->GetName());
 90        }
 91    }
 92
 93    /**
 94     * Read the waveform properties
 95     * Times  = {0 0.1 0.2 1}
 96     * Values = {1 2   3   4}
 97     */
 98    virtual bool Initialise(MARTe::StructuredDataI &data) {
 99        using namespace MARTe;
100        bool ok = Object::Initialise(data);
101
102        if (ok) {
103            ok = ReadArray(data, "Times", waveform.times);
104        }
105        if (ok) {
106            ok = ReadArray(data, "Values", waveform.values);
107        }
108
109        return ok;
110    }
111
112private:
113    bool ReadArray(MARTe::StructuredDataI &data, const MARTe::char8 * const arrayName, MARTe::float32 *&dest) {
114        using namespace MARTe;
115        if (dest != NULL) {
116            delete [] dest;
117        }
118
119        AnyType arrayDescription = data.GetType(arrayName);
120        bool ok = arrayDescription.GetDataPointer() != NULL_PTR(void *);
121        uint32 numberOfElements = 0u;
122        if (ok) {
123            numberOfElements = arrayDescription.GetNumberOfElements(0u);
124            ok = (numberOfElements > 0u);
125            if (!ok) {
126                REPORT_ERROR(ErrorManagement::ParametersError, "No elements defined in the array with name %s", arrayName);
127            }
128        }
129        if (ok) {
130            dest = new float32[numberOfElements];
131            Vector<float32> readVector(dest, numberOfElements);
132            ok = data.Read(arrayName, readVector);
133            if (ok) {
134                REPORT_ERROR(ErrorManagement::Information, "Array set to %f", readVector);
135            }
136            else {
137                REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the array with name %s", arrayName);
138            }
139        }
140        return ok;
141    }
142
143    Waveforms waveform;
144};
145CLASS_REGISTER(ReferenceEx1, "")
146
147/**
148 * @brief A MARTe::Object class will be automatically registered into the ClassRegistryDatabase.
149 */
150class ControllerEx1: public MARTe::ReferenceContainer {
151public:
152    CLASS_REGISTER_DECLARATION()
153
154    /**
155     * @brief NOOP.
156     */
157ControllerEx1    () {
158
159    }
160
161    virtual ~ControllerEx1 () {
162        if (GetName() != NULL) {
163            REPORT_ERROR_STATIC(MARTe::ErrorManagement::Information, "No more references pointing at %s [%s]. "
164                    "The Object will be safely deleted.", GetName(), GetClassProperties()->GetName());
165        }
166    }
167
168    /**
169     * Read all the properties which are organised inside a tree
170     * Gains = {
171     *     Low = {
172     *         Gain1 = -1.0;
173     *         Gain2 = -3.0;
174     *     }
175     *     High = {
176     *         Gain1 = 7.0;
177     *         Gain2 = 9.0;
178     *     }
179     * }
180     * +SlowReference = {
181     *     Class = ReferenceEx1
182     *     Times  = {0 0.1 0.2 1}
183     *     Values = {1 2   3   4}
184     * }
185     * +FastReference = {
186     *     Class = ReferenceEx1
187     *     Times  = {0 0.1 0.2 1}
188     *     Values = {1 4   8   12}
189     * }
190     */
191    virtual bool Initialise(MARTe::StructuredDataI &data) {
192        using namespace MARTe;
193        bool ok = ReferenceContainer::Initialise(data);
194        if (ok) {
195            //Move in the tree
196            ok = data.MoveRelative("Gains");
197            if (!ok) {
198                REPORT_ERROR(ErrorManagement::ParametersError, "Could not move to the Gains section");
199            }
200        }
201        if (ok) {
202            ok = data.MoveRelative("Low");
203            if (!ok) {
204                REPORT_ERROR(ErrorManagement::ParametersError, "Could not move to the Gains.Low section");
205            }
206        }
207        if (ok) {
208            ok = data.Read("Gain1", lowGains.gain1);
209            if (ok) {
210                REPORT_ERROR(ErrorManagement::Information, "Gains.Low.Gain1 = %f", lowGains.gain1);
211            }
212            else {
213                REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gain1");
214            }
215        }
216        if (ok) {
217            ok = data.Read("Gain2", lowGains.gain2);
218            if (ok) {
219                REPORT_ERROR(ErrorManagement::Information, "Gains.Low.Gain1 = %f", lowGains.gain2);
220            }
221            else {
222            }
223        }
224        if (ok) {
225            ok = data.MoveToAncestor(1u);
226            if (!ok) {
227                REPORT_ERROR(ErrorManagement::ParametersError, "Could not move back to the Gains section");
228            }
229        }
230        if (ok) {
231            ok = data.MoveRelative("High");
232            if (!ok) {
233                REPORT_ERROR(ErrorManagement::ParametersError, "Could not move to the Gains.High section");
234            }
235        }
236        if (ok) {
237            ok = data.Read("Gain1", highGains.gain1);
238            if (ok) {
239                REPORT_ERROR(ErrorManagement::Information, "Gains.High.Gain1 = %f", highGains.gain1);
240            }
241            else {
242                REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gain1");
243            }
244        }
245        if (ok) {
246            ok = data.Read("Gain2", highGains.gain2);
247            if (ok) {
248                REPORT_ERROR(ErrorManagement::Information, "Gains.High.Gain1 = %f", highGains.gain2);
249            }
250            else {
251                REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gain2");
252            }
253        }
254
255        if (ok) {
256            //Check if the waveforms were declared
257            slowWaveform = Get(0);
258            ok = slowWaveform.IsValid();
259            if (!ok) {
260                REPORT_ERROR(ErrorManagement::ParametersError, "Could not find the SlowWaveform");
261            }
262        }
263
264        if (ok) {
265            //Check if the waveforms were declared
266            fastWaveform = Get(1);
267            ok = fastWaveform.IsValid();
268            if (!ok) {
269                REPORT_ERROR(ErrorManagement::ParametersError, "Could not find the FastWaveform");
270            }
271        }
272
273        return ok;
274    }
275
276    /**
277     * A list of properties.
278     */
279    Gains lowGains;
280    Gains highGains;
281    MARTe::ReferenceT<ReferenceEx1> slowWaveform;
282    MARTe::ReferenceT<ReferenceEx1> fastWaveform;
283};
284
285CLASS_REGISTER(ControllerEx1, "")
286
287}
288
289int main(int argc, char **argv) {
290    using namespace MARTe;
291    using namespace MARTe2Tutorial;
292    SetErrorProcessFunction(&ErrorProcessExampleFunction);
293
294    StreamString configurationCfg = ""
295            "+ControllerInstance1 = {\n"
296            "    Class = ControllerEx1\n"
297            "    Gains = {\n"
298            "        Low = {\n"
299            "            Gain1 = -1.0\n"
300            "            Gain2 = -3.0\n"
301            "        }\n"
302            "        High = {\n"
303            "            Gain1 = 7.0\n"
304            "            Gain2 = 9.0\n"
305            "        }\n"
306            "    }\n"
307            "    +SlowWaveform = {\n"
308            "        Class = ReferenceEx1\n"
309            "        Times  = {0 0.1 0.2 1}\n"
310            "        Values = {1 2   3   4}\n"
311            "    }\n"
312            "    +FastWaveform = {\n"
313            "        Class = ReferenceEx1\n"
314            "        Times  = {0 0.1 0.2 1}\n"
315            "        Values = {1 4   6   8}\n"
316            "    }\n"
317            "}";
318
319    REPORT_ERROR_STATIC(ErrorManagement::Information, "Loading CFG:\n%s",
320                        configurationCfg.Buffer());
321    ConfigurationDatabase cdb;
322    StreamString err;
323    //Force the string to be seeked to the beginning.
324    configurationCfg.Seek(0LLU);
325    StandardParser parser(configurationCfg, cdb, &err);
326    bool ok = parser.Parse();
327    if (ok) {
328        //After parsing the tree is pointing at the last leaf
329        cdb.MoveToRoot();
330        ok = ObjectRegistryDatabase::Instance()->Initialise(cdb);
331    }
332    else {
333        StreamString errPrint;
334        errPrint.Printf("Failed to parse %s", err.Buffer());
335        REPORT_ERROR_STATIC(ErrorManagement::ParametersError,
336                            errPrint.Buffer());
337    }
338
339    if (ok) {
340        REPORT_ERROR_STATIC(ErrorManagement::Information,
341                            "Successfully loaded the configuration file");
342    }
343
344    return 0;
345}

This example highlights how the Find method can be used to search for Objects in the ObjectRegistryDatabase. Note how the reference G.H is found with respect to B.

ObjectRegistryDatabase Find example (ConfigurationExample5)
  1/**
  2 * @file ConfigurationExample5.cpp
  3 * @brief Source file for class ConfigurationExample5
  4 * @date 14/03/2018
  5 * @author Andre' Neto
  6 *
  7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
  8 * the Development of Fusion Energy ('Fusion for Energy').
  9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 11 * You may not use this work except in compliance with the Licence.
 12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 13 *
 14 * @warning Unless required by applicable law or agreed to in writing, 
 15 * software distributed under the Licence is distributed on an "AS IS"
 16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 17 * or implied. See the Licence permissions and limitations under the Licence.
 18
 19 * @details This source file contains the definition of all the methods for
 20 * the class ConfigurationExample5 (public, protected, and private). Be aware that some
 21 * methods, such as those inline could be defined on the header file, instead.
 22 */
 23
 24#define DLL_API
 25
 26/*---------------------------------------------------------------------------*/
 27/*                         Standard header includes                          */
 28/*---------------------------------------------------------------------------*/
 29
 30/*---------------------------------------------------------------------------*/
 31/*                         Project header includes                           */
 32/*---------------------------------------------------------------------------*/
 33#include "AdvancedErrorManagement.h"
 34#include "ClassRegistryDatabase.h"
 35#include "ConfigurationDatabase.h"
 36#include "ErrorLoggerExample.h"
 37#include "JsonParser.h"
 38#include "Matrix.h"
 39#include "Object.h"
 40#include "ObjectRegistryDatabase.h"
 41#include "Reference.h"
 42#include "ReferenceT.h"
 43#include "StandardParser.h"
 44#include "StreamString.h"
 45#include "Vector.h"
 46
 47/*---------------------------------------------------------------------------*/
 48/*                           Static definitions                              */
 49/*---------------------------------------------------------------------------*/
 50
 51/*---------------------------------------------------------------------------*/
 52/*                           Method definitions                              */
 53/*---------------------------------------------------------------------------*/
 54
 55int main(int argc, char **argv) {
 56    using namespace MARTe;
 57    SetErrorProcessFunction(&ErrorProcessExampleFunction);
 58
 59    StreamString configurationCfg = ""
 60            "+A = {\n"
 61            "    Class = ReferenceContainer\n"
 62            "    $B = {\n"
 63            "        Class = ReferenceContainer\n"
 64            "        +C = {"
 65            "            Class = ReferenceContainer\n"
 66            "            +F = {"
 67            "                Class = ReferenceContainer\n"
 68            "            }\n"
 69            "        }\n"
 70            "        +G = {"
 71            "            Class = ReferenceContainer\n"
 72            "            +H = {"
 73            "                Class = ReferenceContainer\n"
 74            "            }\n"
 75            "        }\n"
 76            "    }\n"
 77            "    +D = {\n"
 78            "        Class = ReferenceContainer\n"
 79            "        +E = {\n"
 80            "            Class = ReferenceContainer\n"
 81            "        }\n"
 82            "    }\n"
 83            "}\n";
 84
 85    REPORT_ERROR_STATIC(ErrorManagement::Information, "Loading CFG:\n%s",
 86                        configurationCfg.Buffer());
 87    ConfigurationDatabase cdb;
 88    StreamString err;
 89    //Force the string to be seeked to the beginning.
 90    configurationCfg.Seek(0LLU);
 91    StandardParser parser(configurationCfg, cdb, &err);
 92    bool ok = parser.Parse();
 93    ObjectRegistryDatabase *ord = ObjectRegistryDatabase::Instance();
 94    if (ok) {
 95        //After parsing the tree is pointing at the last leaf
 96        cdb.MoveToRoot();
 97        ok = ord->Initialise(cdb);
 98    }
 99    else {
100        StreamString errPrint;
101        errPrint.Printf("Failed to parse %s", err.Buffer());
102        REPORT_ERROR_STATIC(ErrorManagement::ParametersError,
103                            errPrint.Buffer());
104    }
105
106    if (ok) {
107        //Find A.D.E
108        const char8 * const path = "A.D.E";
109        ReferenceT<ReferenceContainer> rc = ord->Find(path);
110        ok = rc.IsValid();
111        if (ok) {
112            REPORT_ERROR_STATIC(ErrorManagement::Information, "Found %s", path);
113        }
114        else {
115            REPORT_ERROR_STATIC(ErrorManagement::FatalError,
116                                "Could not find %s !", path);
117        }
118    }
119    if (ok) {
120        //Find A.B.E
121        const char8 * const path = "A.B.E";
122        ReferenceT<ReferenceContainer> rc = ord->Find(path);
123        ok = !rc.IsValid();
124        if (ok) {
125            REPORT_ERROR_STATIC(ErrorManagement::Information,
126                                "Could not find %s as expected", path);
127        }
128        else {
129            REPORT_ERROR_STATIC(ErrorManagement::FatalError,
130                                "Should not have found %s !", path);
131        }
132    }
133    if (ok) {
134        //Find D.E as relative path to F
135        const char8 * const path = "A.B.C.F";
136        ReferenceT<ReferenceContainer> rc = ord->Find(path);
137        ok = rc.IsValid();
138        if (ok) {
139            REPORT_ERROR_STATIC(ErrorManagement::Information, "Found %s", path);
140            //: Moves up to the next domain (which $B)
141            const char8 * const path = ":G.H";
142            //Note that the search is relative to rc (which is currently @ A.B.C.F)
143            rc = ord->Find(path, rc);
144            ok = rc.IsValid();
145            if (ok) {
146                REPORT_ERROR_STATIC(ErrorManagement::Information, "Found %s",
147                                    path);
148            }
149            else {
150                REPORT_ERROR_STATIC(ErrorManagement::FatalError,
151                                    "Could not find %s !", path);
152            }
153        }
154        else {
155            REPORT_ERROR_STATIC(ErrorManagement::FatalError,
156                                "Could not find %s !", path);
157        }
158    }
159
160    return 0;
161}

This example shows how to read and write directly from a registered C struct:

Reading registered structures (ConfigurationExample6)
  1/**
  2 * @file ConfigurationExample6.cpp
  3 * @brief Source file for class ConfigurationExample6
  4 * @date 08/04/2018
  5 * @author Andre' Neto
  6 *
  7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
  8 * the Development of Fusion Energy ('Fusion for Energy').
  9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 11 * You may not use this work except in compliance with the Licence.
 12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 13 *
 14 * @warning Unless required by applicable law or agreed to in writing, 
 15 * software distributed under the Licence is distributed on an "AS IS"
 16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 17 * or implied. See the Licence permissions and limitations under the Licence.
 18
 19 * @details This source file contains the definition of all the methods for
 20 * the class ConfigurationExample6 (public, protected, and private). Be aware that some
 21 * methods, such as those inline could be defined on the header file, instead.
 22 */
 23
 24#define DLL_API
 25
 26/*---------------------------------------------------------------------------*/
 27/*                         Standard header includes                          */
 28/*---------------------------------------------------------------------------*/
 29
 30/*---------------------------------------------------------------------------*/
 31/*                         Project header includes                           */
 32/*---------------------------------------------------------------------------*/
 33#include "AdvancedErrorManagement.h"
 34#include "ClassRegistryDatabase.h"
 35#include "ClassRegistryItemT.h"
 36#include "ConfigurationDatabase.h"
 37#include "ErrorLoggerExample.h"
 38#include "IntrospectionT.h"
 39#include "Matrix.h"
 40#include "Object.h"
 41#include "ObjectRegistryDatabase.h"
 42#include "Reference.h"
 43#include "ReferenceT.h"
 44#include "StandardParser.h"
 45#include "StreamString.h"
 46#include "Vector.h"
 47
 48/*---------------------------------------------------------------------------*/
 49/*                           Static definitions                              */
 50/*---------------------------------------------------------------------------*/
 51namespace MARTe2Tutorial {
 52
 53/**
 54 * Configuration structures
 55 */
 56struct Gain {
 57    MARTe::float32 gain1;
 58    MARTe::float32 gain2;
 59    MARTe::float32 gain3[6];
 60};
 61struct Gains {
 62    struct Gain lowGains;
 63    struct Gain highGains;
 64};
 65
 66DECLARE_CLASS_MEMBER(Gain, gain1, float32, "", "");
 67DECLARE_CLASS_MEMBER(Gain, gain2, float32, "", "");
 68DECLARE_CLASS_MEMBER(Gain, gain3, float32, "[6]", "");
 69
 70static const MARTe::IntrospectionEntry* GainStructEntries[] = { &Gain_gain1_introspectionEntry,
 71        &Gain_gain2_introspectionEntry, &Gain_gain3_introspectionEntry, 0 };
 72
 73DECLARE_STRUCT_INTROSPECTION(Gain, GainStructEntries)
 74
 75DECLARE_CLASS_MEMBER(Gains, lowGains, Gain, "", "");
 76DECLARE_CLASS_MEMBER(Gains, highGains, Gain, "", "");
 77static const MARTe::IntrospectionEntry* GainsStructEntries[] = { &Gains_lowGains_introspectionEntry,
 78        &Gains_highGains_introspectionEntry, 0 };
 79
 80DECLARE_STRUCT_INTROSPECTION(Gains, GainsStructEntries)
 81
 82/**
 83 * @brief A MARTe::Object class that will read directly read its configuration from a structure.
 84 */
 85class ControllerEx1: public MARTe::ReferenceContainer {
 86public:
 87    CLASS_REGISTER_DECLARATION()
 88
 89    /**
 90     * @brief NOOP.
 91     */
 92ControllerEx1    () {
 93
 94    }
 95
 96    virtual ~ControllerEx1 () {
 97        if (GetName() != NULL) {
 98            REPORT_ERROR_STATIC(MARTe::ErrorManagement::Information, "No more references pointing at %s [%s]. "
 99                    "The Object will be safely deleted.", GetName(), GetClassProperties()->GetName());
100        }
101    }
102
103    /**
104     * Read all the properties from the Gains struct (names must match the ones of the struct!
105     * Gains1 = {
106     *     lowGain = {
107     *         Gain1 = -1.0
108     *         Gain2 = -3.0
109     *         Gain3 = {-9.0, -8.0, -7.0, -6.0, -5.0, -4.0}
110     *     }
111     *     High = {
112     *         Gain1 = 7.0
113     *         Gain2 = 9.0
114     *     }
115     * }
116     * Gains2 = {
117     *     lowGain = {
118     *         Gain1 = -1.1
119     *         Gain2 = -3.1
120     *         Gain3 = {-9.1, -8.1, -7.1, -6.1, -5.1, -4.1}
121     *     }
122     *     High = {
123     *         Gain1 = 7.1
124     *         Gain2 = 9.1
125     *         Gain3 = {9.1, 8.1, 7.1, 6.1, 5.1, 4.1}"
126     *     }
127     * }
128     */
129    virtual bool Initialise(MARTe::StructuredDataI &data) {
130        using namespace MARTe;
131        bool ok = ReferenceContainer::Initialise(data);
132        ClassRegistryItem *gainsStructClassRegistryItem = NULL_PTR(ClassRegistryItem *);
133        if (ok) {
134            //Search for the registered structure
135            gainsStructClassRegistryItem = ClassRegistryDatabase::Instance()->Find("Gains");
136        }
137        const ClassProperties *gainsStructClassProperties = NULL_PTR(ClassProperties *);
138        if (ok) {
139            gainsStructClassProperties = gainsStructClassRegistryItem->GetClassProperties();
140        }
141        ClassUID gainsStructClassUID;
142        AnyType gainsAnyType;
143        if (ok) {
144            gainsStructClassUID = gainsStructClassProperties->GetUniqueIdentifier();
145            //Encapsulate the AnyType
146
147            TypeDescriptor gainsTypeDescriptor(false, gainsStructClassUID);
148            gainsAnyType = AnyType(gainsTypeDescriptor, 0u, &gains1);
149            ok = data.Read("Gains1", gainsAnyType);
150            if (ok) {
151                gainsAnyType = AnyType(gainsTypeDescriptor, 0u, &gains2);
152                ok = data.Read("Gains2", gainsAnyType);
153                if (!ok) {
154                    REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gains2 structure");
155                }
156            }
157            else {
158                REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gains1 structure");
159            }
160        }
161
162        if (ok) {
163            REPORT_ERROR(ErrorManagement::Information, "Gains 1 low gains");
164            PrintGains(&gains1.lowGains);
165            REPORT_ERROR(ErrorManagement::Information, "Gains 1 high gains");
166            PrintGains(&gains1.highGains);
167            REPORT_ERROR(ErrorManagement::Information, "Gains 2 low gains");
168            PrintGains(&gains2.lowGains);
169            REPORT_ERROR(ErrorManagement::Information, "Gains 2 high gains");
170            PrintGains(&gains2.highGains);
171        }
172
173        return ok;
174    }
175
176private:
177    void PrintGains(Gain *gainToPrint) {
178        using namespace MARTe;
179        REPORT_ERROR(ErrorManagement::Information, "Gain1 %f", gainToPrint->gain1);
180        REPORT_ERROR(ErrorManagement::Information, "Gain2 %f", gainToPrint->gain2);
181        REPORT_ERROR(ErrorManagement::Information, "Gain3 %f", gainToPrint->gain3);
182    }
183
184    /**
185     * A list of properties.
186     */
187    Gains gains1;
188    Gains gains2;
189};
190
191CLASS_REGISTER(ControllerEx1, "")
192
193}
194/*---------------------------------------------------------------------------*/
195/*                           Method definitions                              */
196/*---------------------------------------------------------------------------*/
197
198int main(int argc, char **argv) {
199    using namespace MARTe;
200    using namespace MARTe2Tutorial;
201    SetErrorProcessFunction(&ErrorProcessExampleFunction);
202
203    StreamString configurationCfg = ""
204            "+ControllerInstance1 = {\n"
205            "    Class = ControllerEx1\n"
206            "    Gains1 = {\n"
207            "        lowGains = {\n"
208            "            Gain1 = -1.0\n"
209            "            Gain2 = -3.0\n"
210            "            Gain3 = {-9.0, -8.0, -7.0, -6.0, -5.0, -4.0}\n"
211            "        }\n"
212            "        highGains = {\n"
213            "            Gain1 = 7.0\n"
214            "            Gain2 = 9.0\n"
215            "            Gain3 = {9.0, 8.0, 7.0, 6.0, 5.0, 4.0}\n"
216            "        }\n"
217            "    }\n"
218            "    Gains2 = {\n"
219            "        lowGains = {\n"
220            "            Gain1 = -1.0\n"
221            "            Gain2 = -3.0\n"
222            "            Gain3 = {-9.1, -8.1, -7.1, -6.1, -5.1, -4.1}\n"
223            "        }\n"
224            "        highGains = {\n"
225            "            Gain1 = 7.0\n"
226            "            Gain2 = 9.0\n"
227            "            Gain3 = {9.1, 8.1, 7.1, 6.1, 5.1, 4.1}\n"
228            "        }\n"
229            "    }\n"
230            "}";
231
232    REPORT_ERROR_STATIC(ErrorManagement::Information, "Loading CFG:\n%s", configurationCfg.Buffer());
233    ConfigurationDatabase cdb;
234    StreamString err;
235    //Force the string to be seeked to the beginning.
236    configurationCfg.Seek(0LLU);
237    StandardParser parser(configurationCfg, cdb, &err);
238    bool ok = parser.Parse();
239    if (ok) {
240        //After parsing the tree is pointing at the last leaf
241        cdb.MoveToRoot();
242        ok = ObjectRegistryDatabase::Instance()->Initialise(cdb);
243    }
244    else {
245        StreamString errPrint;
246        errPrint.Printf("Failed to parse %s", err.Buffer());
247        REPORT_ERROR_STATIC(ErrorManagement::ParametersError, errPrint.Buffer());
248    }
249
250    if (ok) {
251        REPORT_ERROR_STATIC(ErrorManagement::Information, "Successfully loaded the configuration file");
252    }
253
254    //Write a structure to a ConfigurationDatabase
255    ClassRegistryItem *gainsStructClassRegistryItem = NULL_PTR(ClassRegistryItem *);
256    if (ok) {
257        gainsStructClassRegistryItem = ClassRegistryDatabase::Instance()->Find("Gains");
258    }
259    AnyType gainsAnyType;
260    const ClassProperties *gainsStructClassProperties = NULL_PTR(ClassProperties *);
261    if (ok) {
262        gainsStructClassProperties = gainsStructClassRegistryItem->GetClassProperties();
263    }
264    if (ok) {
265        ConfigurationDatabase cdb;
266        Gains gainsExample;
267        gainsExample.lowGains.gain1 = 1;
268        gainsExample.lowGains.gain2 = 2;
269        gainsExample.lowGains.gain3[0] = -1;
270        gainsExample.lowGains.gain3[5] = 1;
271        gainsExample.highGains.gain1 = -1;
272        gainsExample.highGains.gain2 = -2;
273        gainsExample.highGains.gain3[0] = 1;
274        gainsExample.highGains.gain3[5] = -1;
275
276        ClassUID gainsStructClassUID = gainsStructClassProperties->GetUniqueIdentifier();
277        //Encapsulate the AnyType
278
279        TypeDescriptor gainsTypeDescriptor(false, gainsStructClassUID);
280        gainsAnyType = AnyType(gainsTypeDescriptor, 0u, &gainsExample);
281        ok = cdb.Write("DumpStruct", gainsAnyType);
282        if (ok) {
283            cdb.MoveToRoot();
284            REPORT_ERROR_STATIC(ErrorManagement::Information, "Wrote structure %!", cdb);
285        }
286    }
287    return 0;
288}

Similar to the example below but the structures are registered using the configuration file:

Reading registered structures (ConfigurationExample7)
  1/**
  2 * @file ConfigurationExample7.cpp
  3 * @brief Source file for class ConfigurationExample7
  4 * @date 08/04/2018
  5 * @author Andre' Neto
  6 *
  7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
  8 * the Development of Fusion Energy ('Fusion for Energy').
  9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
 10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
 11 * You may not use this work except in compliance with the Licence.
 12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
 13 *
 14 * @warning Unless required by applicable law or agreed to in writing, 
 15 * software distributed under the Licence is distributed on an "AS IS"
 16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 17 * or implied. See the Licence permissions and limitations under the Licence.
 18
 19 * @details This source file contains the definition of all the methods for
 20 * the class ConfigurationExample7 (public, protected, and private). Be aware that some
 21 * methods, such as those inline could be defined on the header file, instead.
 22 */
 23
 24#define DLL_API
 25
 26/*---------------------------------------------------------------------------*/
 27/*                         Standard header includes                          */
 28/*---------------------------------------------------------------------------*/
 29
 30/*---------------------------------------------------------------------------*/
 31/*                         Project header includes                           */
 32/*---------------------------------------------------------------------------*/
 33#include "AdvancedErrorManagement.h"
 34#include "ClassRegistryDatabase.h"
 35#include "ClassRegistryItemT.h"
 36#include "ConfigurationDatabase.h"
 37#include "ErrorLoggerExample.h"
 38#include "IntrospectionT.h"
 39#include "Matrix.h"
 40#include "Object.h"
 41#include "ObjectRegistryDatabase.h"
 42#include "Reference.h"
 43#include "ReferenceT.h"
 44#include "StandardParser.h"
 45#include "StreamString.h"
 46#include "Vector.h"
 47
 48/*---------------------------------------------------------------------------*/
 49/*                           Static definitions                              */
 50/*---------------------------------------------------------------------------*/
 51namespace MARTe2Tutorial {
 52
 53/**
 54 * Configuration structures
 55 */
 56#ifdef __GNUC__
 57struct __attribute__((__packed__)) GainFromIntroStructure {
 58    MARTe::float32 gain1;
 59    MARTe::float32 gain2;
 60    MARTe::float32 gain3[6];
 61};
 62struct __attribute__((__packed__)) GainsFromIntroStructure {
 63    struct GainFromIntroStructure lowGains[2];
 64    struct GainFromIntroStructure highGains;
 65};
 66#endif
 67
 68#ifdef _MSC_VER
 69#pragma pack(push,1)
 70struct GainFromIntroStructure {
 71    MARTe::float32 gain1;
 72    MARTe::float32 gain2;
 73    MARTe::float32 gain3[6];
 74};
 75struct GainsFromIntroStructure {
 76    struct GainFromIntroStructure lowGains[2];
 77    struct GainFromIntroStructure highGains;
 78};
 79#pragma pack(pop)
 80#endif
 81
 82/**
 83 * @brief A MARTe::Object class that will read directly read its configuration from a structure.
 84 */
 85class ControllerEx1: public MARTe::ReferenceContainer {
 86public:
 87    CLASS_REGISTER_DECLARATION()
 88
 89    /**
 90     * @brief NOOP.
 91     */
 92ControllerEx1    () {
 93
 94    }
 95
 96    virtual ~ControllerEx1 () {
 97        if (GetName() != NULL) {
 98            REPORT_ERROR_STATIC(MARTe::ErrorManagement::Information, "No more references pointing at %s [%s]. "
 99                    "The Object will be safely deleted.", GetName(), GetClassProperties()->GetName());
100        }
101    }
102
103    /**
104     * Read all the properties from the Gains struct (names must match the ones of the struct!
105     * Gains1 = {
106     *     lowGain[0] = {
107     *         Gain1 = -1.0
108     *         Gain2 = -3.0
109     *         Gain3 = {-9.0, -8.0, -7.0, -6.0, -5.0, -4.0}
110     *     }
111     *     lowGain[1] = {
112     *         Gain1 = -2.0
113     *         Gain2 = -6.0
114     *         Gain3 = {-18.0, -16.0, -14.0, -12.0, -10.0, -8.0}
115     *     }
116     *     High = {
117     *         Gain1 = 7.0
118     *         Gain2 = 9.0
119     *     }
120     * }
121     * Gains2 = {
122     *     lowGain = {
123     *         Gain1 = -1.1
124     *         Gain2 = -3.1
125     *         Gain3 = {-9.1, -8.1, -7.1, -6.1, -5.1, -4.1}
126     *     }
127     *     High = {
128     *         Gain1 = 7.1
129     *         Gain2 = 9.1
130     *         Gain3 = {9.1, 8.1, 7.1, 6.1, 5.1, 4.1}"
131     *     }
132     * }
133     */
134    virtual bool Initialise(MARTe::StructuredDataI &data) {
135        using namespace MARTe;
136        bool ok = ReferenceContainer::Initialise(data);
137        ClassRegistryItem *gainsStructClassRegistryItem = NULL_PTR(ClassRegistryItem *);
138        if (ok) {
139            //Search for the registered structure
140            gainsStructClassRegistryItem = ClassRegistryDatabase::Instance()->Find("GainsFromIntroStructure");
141        }
142        const ClassProperties *gainsStructClassProperties = NULL_PTR(ClassProperties *);
143        if (ok) {
144            gainsStructClassProperties = gainsStructClassRegistryItem->GetClassProperties();
145        }
146        ClassUID gainsStructClassUID;
147        AnyType gainsAnyType;
148        if (ok) {
149            gainsStructClassUID = gainsStructClassProperties->GetUniqueIdentifier();
150            //Encapsulate the AnyType
151
152            TypeDescriptor gainsTypeDescriptor(false, gainsStructClassUID);
153            gainsAnyType = AnyType(gainsTypeDescriptor, 0u, &gains1);
154            ok = data.Read("Gains1", gainsAnyType);
155            if (ok) {
156                gainsAnyType = AnyType(gainsTypeDescriptor, 0u, &gains2);
157                ok = data.Read("Gains2", gainsAnyType);
158                if (!ok) {
159                    REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gains2 structure");
160                }
161            }
162            else {
163                REPORT_ERROR(ErrorManagement::ParametersError, "Could not read the Gains1 structure");
164            }
165        }
166
167        if (ok) {
168            REPORT_ERROR(ErrorManagement::Information, "Gains 1 low[0] gains");
169            PrintGains(&gains1.lowGains[0]);
170            REPORT_ERROR(ErrorManagement::Information, "Gains 1 low[1] gains");
171            PrintGains(&gains1.lowGains[1]);
172            REPORT_ERROR(ErrorManagement::Information, "Gains 1 high gains");
173            PrintGains(&gains1.highGains);
174            REPORT_ERROR(ErrorManagement::Information, "Gains 2 low[0] gains");
175            PrintGains(&gains2.lowGains[0]);
176            REPORT_ERROR(ErrorManagement::Information, "Gains 2 low[1] gains");
177            PrintGains(&gains2.lowGains[1]);
178            REPORT_ERROR(ErrorManagement::Information, "Gains 2 high gains");
179            PrintGains(&gains2.highGains);
180        }
181
182        return ok;
183    }
184
185private:
186    void PrintGains(GainFromIntroStructure *gainToPrint) {
187        using namespace MARTe;
188        float32 gain1 = gainToPrint->gain1;
189        float32 gain2 = gainToPrint->gain2;
190        float32 gain3[6] = {gainToPrint->gain3[0], gainToPrint->gain3[1], gainToPrint->gain3[2], gainToPrint->gain3[3], gainToPrint->gain3[4], gainToPrint->gain3[5]};
191        REPORT_ERROR(ErrorManagement::Information, "Gain1 %f", gain1);
192        REPORT_ERROR(ErrorManagement::Information, "Gain2 %f", gain2);
193        REPORT_ERROR(ErrorManagement::Information, "Gain3 %f", gain3);
194    }
195
196    /**
197     * A list of properties.
198     */
199    GainsFromIntroStructure gains1;
200    GainsFromIntroStructure gains2;
201};
202
203CLASS_REGISTER(ControllerEx1, "")
204
205}
206/*---------------------------------------------------------------------------*/
207/*                           Method definitions                              */
208/*---------------------------------------------------------------------------*/
209
210int main(int argc, char **argv) {
211    using namespace MARTe;
212    using namespace MARTe2Tutorial;
213    SetErrorProcessFunction(&ErrorProcessExampleFunction);
214
215    StreamString configurationCfg = ""
216            "+Types = {\n"
217            "    Class = ReferenceContainer\n"
218            "    +GainFromIntroStructure = {\n"
219            "        Class = IntrospectionStructure\n"
220            "        gain1 = {\n"
221            "            Type = float32\n"
222            "            NumberOfElements = {1}\n"
223            "        }\n"
224            "        gain2 = {\n"
225            "            Type = float32\n"
226            "            NumberOfElements = {1}\n"
227            "        }\n"
228            "        gain3 = {\n"
229            "            Type = float32\n"
230            "            NumberOfElements = {6}\n"
231            "        }\n"
232            "    }\n"
233            "    +GainsFromIntroStructure = {\n"
234            "        Class = IntrospectionStructure\n"
235            "        lowGains = {\n"
236            "            Type = GainFromIntroStructure\n"
237            "            NumberOfElements = {2}\n"
238            "        }\n"
239            "        highGains = {\n"
240            "            Type = GainFromIntroStructure\n"
241            "        }\n"
242            "    }\n"
243            "}\n"
244            "+ControllerInstance1 = {\n"
245            "    Class = ControllerEx1\n"
246            "    Gains1 = {\n"
247            "        lowGains[0] = {\n"
248            "            Gain1 = -1.0\n"
249            "            Gain2 = -3.0\n"
250            "            Gain3 = {-9.0, -8.0, -7.0, -6.0, -5.0, -4.0}\n"
251            "        }\n"
252            "        lowGains[1] = {\n"
253            "            Gain1 = -2.0\n"
254            "            Gain2 = -6.0\n"
255            "            Gain3 = {-18.0, -16.0, -14.0, -12.0, -10.0, -8.0}\n"
256            "        }\n"
257            "        highGains = {\n"
258            "            Gain1 = 7.0\n"
259            "            Gain2 = 9.0\n"
260            "            Gain3 = {9.0, 8.0, 7.0, 6.0, 5.0, 4.0}\n"
261            "        }\n"
262            "    }\n"
263            "    Gains2 = {\n"
264            "        lowGains[0] = {\n"
265            "            Gain1 = -1.0\n"
266            "            Gain2 = -3.0\n"
267            "            Gain3 = {-9.1, -8.1, -7.1, -6.1, -5.1, -4.1}\n"
268            "        }\n"
269            "        lowGains[1] = {\n"
270            "            Gain1 = -2.0\n"
271            "            Gain2 = -6.0\n"
272            "            Gain3 = {-18.2, -16.2, -14.2, -12.2, -10.2, -8.2}\n"
273            "        }\n"
274            "        highGains = {\n"
275            "            Gain1 = 7.0\n"
276            "            Gain2 = 9.0\n"
277            "            Gain3 = {9.1, 8.1, 7.1, 6.1, 5.1, 4.1}\n"
278            "        }\n"
279            "    }\n"
280            "}";
281
282    REPORT_ERROR_STATIC(ErrorManagement::Information, "Loading CFG:\n%s", configurationCfg.Buffer());
283    ConfigurationDatabase cdb;
284    StreamString err;
285    //Force the string to be seeked to the beginning.
286    configurationCfg.Seek(0LLU);
287    StandardParser parser(configurationCfg, cdb, &err);
288    bool ok = parser.Parse();
289    if (ok) {
290        //After parsing the tree is pointing at the last leaf
291        cdb.MoveToRoot();
292        ok = ObjectRegistryDatabase::Instance()->Initialise(cdb);
293    }
294    else {
295        StreamString errPrint;
296        errPrint.Printf("Failed to parse %s", err.Buffer());
297        REPORT_ERROR_STATIC(ErrorManagement::ParametersError, errPrint.Buffer());
298    }
299
300    if (ok) {
301        REPORT_ERROR_STATIC(ErrorManagement::Information, "Successfully loaded the configuration file");
302    }
303
304    //Write a structure to a ConfigurationDatabase
305    ClassRegistryItem *gainsStructClassRegistryItem = NULL_PTR(ClassRegistryItem *);
306    if (ok) {
307        gainsStructClassRegistryItem = ClassRegistryDatabase::Instance()->Find("GainsFromIntroStructure");
308    }
309    AnyType gainsAnyType;
310    const ClassProperties *gainsStructClassProperties = NULL_PTR(ClassProperties *);
311    if (ok) {
312        gainsStructClassProperties = gainsStructClassRegistryItem->GetClassProperties();
313    }
314    if (ok) {
315        ConfigurationDatabase cdb;
316        GainsFromIntroStructure gainsExample;
317        gainsExample.lowGains[0].gain1 = 1;
318        gainsExample.lowGains[0].gain2 = 2;
319        gainsExample.lowGains[1].gain3[0] = -1;
320        gainsExample.lowGains[1].gain3[5] = 1;
321        gainsExample.highGains.gain1 = -1;
322        gainsExample.highGains.gain2 = -2;
323        gainsExample.highGains.gain3[0] = 1;
324        gainsExample.highGains.gain3[5] = -1;
325
326        ClassUID gainsStructClassUID = gainsStructClassProperties->GetUniqueIdentifier();
327        //Encapsulate the AnyType
328
329        TypeDescriptor gainsTypeDescriptor(false, gainsStructClassUID);
330        gainsAnyType = AnyType(gainsTypeDescriptor, 0u, &gainsExample);
331        ok = cdb.Write("DumpStruct", gainsAnyType);
332        if (ok) {
333            cdb.MoveToRoot();
334            REPORT_ERROR_STATIC(ErrorManagement::Information, "Wrote structure %!", cdb);
335        }
336    }
337    return 0;
338}

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

Example on how to preprocess complex configuration files:

Example of a configuration file that includes other configuration files.
1#ifdef ENABLE_WEB_BROWSING
2#include "RTApp-6-Web.cfg"
3#endif
4#include "RTApp-6-StateMachine.cfg"
5#include "RTApp-6-RTApp.cfg"
 1#############################################################
 2#
 3# Copyright 2015 F4E | European Joint Undertaking for ITER 
 4#  and the Development of Fusion Energy ('Fusion for Energy')
 5# 
 6# Licensed under the EUPL, Version 1.1 or - as soon they 
 7# will be approved by the European Commission - subsequent  
 8# versions of the EUPL (the "Licence"); 
 9# You may not use this work except in compliance with the 
10# Licence. 
11# You may obtain a copy of the Licence at: 
12#  
13# http://ec.europa.eu/idabc/eupl
14#
15# Unless required by applicable law or agreed to in 
16# writing, software distributed under the Licence is 
17# distributed on an "AS IS" basis, 
18# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
19# express or implied. 
20# See the Licence for the specific language governing 
21# permissions and limitations under the Licence. 
22#
23#############################################################
24
25#Named of the unit files to be compiled
26OBJSX=RTApp-6.x
27
28#Location of the Build directory where the configuration file will be written to
29BUILD_DIR?=.
30
31#Location of the MakeDefaults directory.
32#Note that the MARTe2_DIR environment variable
33#must have been exported before
34MARTe2_MAKEDEFAULT_DIR?=$(MARTe2_DIR)/MakeDefaults
35
36include $(MARTe2_MAKEDEFAULT_DIR)/MakeStdLibDefs.$(TARGET)
37
38CFLAGS += -DENABLE_WEB_BROWSING
39
40all: $(OBJS) 
41	echo  $(OBJS)
42
43include $(MARTe2_MAKEDEFAULT_DIR)/MakeStdLibRules.$(TARGET)

Example with post-processing of variables:

Example of a configuration file with variable post-processing.
  1Parameters = {
  2    T1_FREQUENCY = (uint32)10000
  3    T2_FREQUENCY = (uint32)1
  4    SAMPLES = (uint32|"Parameters.T1_FREQUENCY / Parameters.T2_FREQUENCY")
  5}
  6$TestApp = {
  7    Class = RealTimeApplication
  8    +Functions = {
  9        Class = ReferenceContainer
 10        +GAMTimer = {
 11            Class = IOGAM
 12            InputSignals = {
 13                Counter = {
 14                    DataSource = Timer
 15                    Type = uint32
 16                }
 17                Time = {
 18                    Frequency = (uint32|"Parameters.T1_FREQUENCY")
 19                    DataSource = Timer
 20                    Type = uint32
 21                }
 22            }
 23            OutputSignals = {
 24                Counter = {
 25                    DataSource = DDB1
 26                    Type = uint32
 27                }                
 28                Time = {
 29                    DataSource = DDB1
 30                    Type = uint32
 31                }            
 32            }
 33        }
 34        +GAMFixed1 = {
 35            Class = FixedGAMExample1
 36            Gain = 2 
 37            InputSignals = {
 38                Counter = {
 39                    DataSource = DDB1
 40                    Type = uint32
 41                }
 42            }
 43            OutputSignals = {
 44                GainCounter = {
 45                    DataSource = DDB1
 46                    Type = uint32
 47                }                
 48            }
 49        }
 50        +GAMT1ToT2 = {
 51            Class = IOGAM            
 52            InputSignals = {
 53                Counter = {
 54                    DataSource = DDB1
 55                    Type = uint32
 56                }
 57                GainCounter = {
 58                    DataSource = DDB1
 59                    Type = uint32
 60                }
 61                State1_Thread1_CycleTime = {
 62                    Alias = State1.Thread1_CycleTime
 63                    DataSource = Timings
 64                    Type = uint32
 65                }
 66                GAMTimer_ReadTime = {
 67                    DataSource = Timings
 68                    Type = uint32
 69                }
 70                GAMTimer_ExecTime = {
 71                    DataSource = Timings
 72                    Type = uint32
 73                }
 74                GAMTimer_WriteTime = {
 75                    DataSource = Timings
 76                    Type = uint32
 77                }
 78                GAMFixed1_ReadTime = {
 79                    DataSource = Timings
 80                    Type = uint32
 81                }
 82                GAMFixed1_ExecTime = {
 83                    DataSource = Timings
 84                    Type = uint32
 85                }
 86                GAMFixed1_WriteTime = {
 87                    DataSource = Timings
 88                    Type = uint32
 89                }
 90            } 
 91            OutputSignals = {
 92                Counter = {
 93                    DataSource = RTThreadSynch 
 94                    Type = uint32
 95                }
 96                GainCounter = {
 97                    DataSource = RTThreadSynch 
 98                    Type = uint32
 99                }
100                State1_Thread1_CycleTime = {
101                    DataSource = RTThreadSynch 
102                    Type = uint32
103                }
104                GAMTimer_ReadTime = {
105                    DataSource = RTThreadSynch 
106                    Type = uint32
107                }
108                GAMTimer_ExecTime = {
109                    DataSource = RTThreadSynch 
110                    Type = uint32
111                }
112                GAMTimer_WriteTime = {
113                    DataSource = RTThreadSynch 
114                    Type = uint32
115                }
116                GAMFixed1_ReadTime = {
117                    DataSource = RTThreadSynch 
118                    Type = uint32
119                }
120                GAMFixed1_ExecTime = {
121                    DataSource = RTThreadSynch 
122                    Type = uint32
123                }
124                GAMFixed1_WriteTime = {
125                    DataSource = RTThreadSynch 
126                    Type = uint32
127                }
128            }
129        }
130        +GAMT2FromT1 = {
131            Class = IOGAM            
132            InputSignals = {
133                Counter = {
134                    DataSource = RTThreadSynch
135                    Samples = (uint32|"Parameters.SAMPLES")
136                    Type = uint32
137                }
138                GainCounter = {
139                    DataSource = RTThreadSynch
140                    Samples = (uint32|"Parameters.SAMPLES")
141                    Type = uint32
142                }
143                State1_Thread1_CycleTime = {
144                    DataSource = RTThreadSynch
145                    Samples = (uint32|"Parameters.SAMPLES")
146                    Type = uint32
147                }
148                GAMTimer_ReadTime = {
149                    DataSource = RTThreadSynch
150                    Samples = (uint32|"Parameters.SAMPLES")
151                    Type = uint32
152                }
153                GAMTimer_ExecTime = {
154                    DataSource = RTThreadSynch
155                    Samples = (uint32|"Parameters.SAMPLES")
156                    Type = uint32
157                }
158                GAMTimer_WriteTime = {
159                    DataSource = RTThreadSynch
160                    Samples = (uint32|"Parameters.SAMPLES")
161                    Type = uint32
162                }
163                GAMFixed1_ReadTime = {
164                    DataSource = RTThreadSynch
165                    Samples = (uint32|"Parameters.SAMPLES")
166                    Type = uint32
167                }
168                GAMFixed1_ExecTime = {
169                    DataSource = RTThreadSynch
170                    Samples = (uint32|"Parameters.SAMPLES")
171                    Type = uint32
172                }
173                GAMFixed1_WriteTime = {
174                    DataSource = RTThreadSynch
175                    Samples = (uint32|"Parameters.SAMPLES")
176                    Type = uint32
177                }
178            } 
179            OutputSignals = {
180                Counter = {
181                    DataSource = DDB2
182                    NumberOfElements = 10000
183                    Type = uint32
184                }
185                GainCounter = {
186                    DataSource = DDB2
187                    NumberOfElements = 10000
188                    Type = uint32
189                }
190                State1_Thread1_CycleTime = {
191                    DataSource = DDB2
192                    NumberOfElements = 10000
193                    Type = uint32
194                }
195                GAMTimer_ReadTime = {
196                    DataSource = DDB2
197                    NumberOfElements = 10000
198                    Type = uint32
199                }
200                GAMTimer_ExecTime = {
201                    DataSource = DDB2
202                    NumberOfElements = 10000
203                    Type = uint32
204                }
205                GAMTimer_WriteTime = {
206                    DataSource = DDB2
207                    NumberOfElements = 10000
208                    Type = uint32
209                }
210                GAMFixed1_ReadTime = {
211                    DataSource = DDB2
212                    NumberOfElements = 10000
213                    Type = uint32
214                }
215                GAMFixed1_ExecTime = {
216                    DataSource = DDB2
217                    NumberOfElements = 10000
218                    Type = uint32
219                }
220                GAMFixed1_WriteTime = {
221                    DataSource = DDB2
222                    NumberOfElements = 10000
223                    Type = uint32
224                }
225            }
226        }
227        +GAMDisplay = {
228            Class = IOGAM            
229            InputSignals = {
230                Counter = {
231                    DataSource = DDB2
232                    Ranges = {{0, 10}}
233                    Type = uint32
234                }
235                GainCounter = {
236                    DataSource = DDB2
237                    Ranges = {{0, 10}}
238                    Type = uint32
239                }
240                State1_Thread1_CycleTime = {
241                    DataSource = DDB2 
242                    Ranges = {{0, 10}}
243                    Type = uint32
244                }
245                GAMTimer_ReadTime = {
246                    DataSource = DDB2 
247                    Ranges = {{0, 10}}
248                    Type = uint32
249                }
250                GAMTimer_ExecTime = {
251                    DataSource = DDB2 
252                    Ranges = {{0, 10}}
253                    Type = uint32
254                }
255                GAMTimer_WriteTime = {
256                    DataSource = DDB2 
257                    Ranges = {{0, 10}}
258                    Type = uint32
259                }
260                GAMFixed1_ReadTime = {
261                    DataSource = DDB2 
262                    Ranges = {{0, 10}}
263                    Type = uint32
264                }
265                GAMFixed1_ExecTime = {
266                    DataSource = DDB2 
267                    Ranges = {{0, 10}}
268                    Type = uint32
269                }
270                GAMFixed1_WriteTime = {
271                    DataSource = DDB2 
272                    Ranges = {{0, 10}}
273                    Type = uint32
274                }
275            } 
276            OutputSignals = {
277                Counter = {
278                    DataSource = LoggerDataSource
279                    NumberOfElements = 11
280                    Type = uint32
281                }
282                GainCounter = {
283                    DataSource = LoggerDataSource
284                    NumberOfElements = 11
285                    Type = uint32
286                }
287                State1_Thread1_CycleTime = {
288                    DataSource = LoggerDataSource
289                    NumberOfElements = 11
290                    Type = uint32
291                }
292                GAMTimer_ReadTime = {
293                    DataSource = LoggerDataSource
294                    NumberOfElements = 11
295                    Type = uint32
296                }
297                GAMTimer_ExecTime = {
298                    DataSource = LoggerDataSource
299                    NumberOfElements = 11
300                    Type = uint32
301                }
302                GAMTimer_WriteTime = {
303                    DataSource = LoggerDataSource
304                    NumberOfElements = 11
305                    Type = uint32
306                }
307                GAMFixed1_ReadTime = {
308                    DataSource = LoggerDataSource
309                    NumberOfElements = 11
310                    Type = uint32
311                }
312                GAMFixed1_ExecTime = {
313                    DataSource = LoggerDataSource
314                    NumberOfElements = 11
315                    Type = uint32
316                }
317                GAMFixed1_WriteTime = {
318                    DataSource = LoggerDataSource
319                    NumberOfElements = 11
320                    Type = uint32
321                }
322            }
323        }
324    }
325    +Data = {
326        Class = ReferenceContainer
327        DefaultDataSource = DDB2
328        +DDB1 = {
329            Class = GAMDataSource
330       	}        
331        +DDB2 = {
332            Class = GAMDataSource
333       	}        
334        +LoggerDataSource = {
335            Class = LoggerDataSource
336        }
337        +RTThreadSynch = {
338            Class = RealTimeThreadSynchronisation
339            Timeout = 10000 //Timeout in ms to wait for the thread to cycle.
340        }
341        +Timings = {
342            Class = TimingDataSource
343        }
344        +Timer = {
345            Class = LinuxTimer
346            SleepNature = "Default"
347            Signals = {
348                Counter = {
349                    Type = uint32
350                }
351                Time = {
352                    Type = uint32
353                }
354            }
355        }        
356    }
357    +States = {
358        Class = ReferenceContainer
359        +State1 = {
360            Class = RealTimeState
361            +Threads = {
362                Class = ReferenceContainer
363                +Thread1 = {
364                    Class = RealTimeThread
365                    CPUs = 0x2
366                    Functions = {GAMTimer GAMFixed1 GAMT1ToT2}
367                }
368                +Thread2 = {
369                    Class = RealTimeThread
370                    CPUs = 0x1
371                    Functions = {GAMT2FromT1 GAMDisplay}
372                }
373
374            }
375        }        
376    }
377    +Scheduler = {
378        Class = GAMScheduler
379        TimingDataSource = Timings
380    }
381}