Exercises
Ex. 1: Modify the thread frequency
Edit the file
../Configurations/HelloWorld/RTApp-HelloWorld-2.cfgand modify the frequency of the real-time thread to10 Hz.Check that the counter increases at the new rate.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-2.cfg -l RealTimeLoader -s State1
Solution
The solution is to modify the Frequency property of the signal that is used to pace the thread. A modified configuration file with the correct frequency is shown below.
1 +GAMTimer = {
2 Class = IOGAM
3 InputSignals = {
4 Counter = {
5 DataSource = Timer
6 Type = uint32
7 }
8 Time = {
9 Frequency = 10
10 DataSource = Timer
11 Type = uint32
Ex. 2: Find the typo
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-3.cfg -l RealTimeLoader -s State1
Identify the typo in the configuration file that prevents the application from running.
Solution
The State name is misspelled as Idle instead of State1 in the configuration file.
$ [InitialisationEr - RealTimeLoader.cpp:118]: Failed to PrepareNextState for state State1
1 +States = {
2 Class = ReferenceContainer
3 +Idle = {
4 Class = RealTimeState
5 +Threads = {
6 Class = ReferenceContainer
7 +Thread1 = {
8 Class = RealTimeThread
9 CPUs = 0x1
10 Functions = {GAMTimer GAMDisplay}
11 }
12 }
13 }
14 }
Is there a way to launch the application without modifying the configuration file to fix the typo?
Solution
Yes, the state name can be overridden at launch time by using the -s option of the MARTeApp.sh script. For example, the following command will launch the application with the correct state name:
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-3.cfg -l RealTimeLoader -s Idle
Ex. 3: Modify the logged signal
Edit the file
../Configurations/HelloWorld/RTApp-HelloWorld-4.cfgand modify the configuration to log theTimesignal instead of theCountersignal.
Solution
The solution is to modify the signals in the configuration file.
1 +GAMDisplay = {
2 Class = IOGAM
3 InputSignals = {
4 Time = {
5 DataSource = DDB1
6 Type = uint32
7 }
8 }
9 OutputSignals = {
10 Time = {
11 DataSource = Display
12 Type = uint32
13 }
14 }
15 }
Ex. 4: Signal names
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-5.cfg -l RealTimeLoader -s State1
Identify the typo in the configuration file that prevents the application from running.
Solution
MARTe signal names are case-sensitive. The signal name counter is misspelled as Counter in the configuration file.
The GAMDataSource complains that the GAMDisplay GAM is requesting a signal named Counter, which does not exist, and the application fails to start.
$ [FatalError - GAMDataSource.cpp:400]: In GAMDataSource DDB1, state State1, signal Counter has an invalid number of producers. Should be > 0 but is 0
1 OutputSignals = {
2 counter = {
3 DataSource = DDB1
4 Type = uint32
5 }
6 Time = {
7 DataSource = DDB1
8 Type = uint32
9 }
10 }
Ex. 5: Signal alias
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-6.cfg -l RealTimeLoader -s State1
The application will fail to start with the following error message:
$ [FatalError - GAMDataSource.cpp:400]: In GAMDataSource DDB1, state State1, signal CounterIn has an invalid number of producers. Should be > 0 but is 0
Modify the configuration file to fix the issue by using the signal Alias property and make the application run.
Solution
MARTe allows GAMs to rename signals with different names than the ones provided by the DataSources.
The scope of these signal names is private to the GAM.
This is useful when the same signal is provided by different DataSources or when the signal name in the DataSource is not suitable for the GAM.
The solution is to use the Alias property to create an alias for the signal name. In this case, the signal Counter is aliased as CounterIn in the configuration file.
1 +GAMDisplay = {
2 Class = IOGAM
3 InputSignals = {
4 CounterIn = {
5 Alias = Counter
6 DataSource = DDB1
7 Type = uint32
8 }
9 }
10 OutputSignals = {
11 CounterOut = {
12 DataSource = Display
13 Type = uint32
14 }
15 }
16 }
Note that the OutputSignal name was also modified to
CounterOutto keep the same naming convention. Why is this not an issue?
Answer
Some DataSources, such as the LoggerDataSource, allow signals to be added at runtime. In this case, the LoggerDataSource will create a new signal named CounterOut and log its value.
Ex. 6: Signal types
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-7.cfg -l RealTimeLoader -s State1
Identify the typo in the configuration file that prevents the application from running.
Solution
A typo in the Time signal type is preventing the application from running. The signal type is misspelled as uint22 instead of uint32 in the configuration file.
$ [InitialisationEr - RealTimeLoader.cpp:118]: Failed to PrepareNextState for state State1
1 +GAMTimer = {
2 Class = IOGAM
3 InputSignals = {
4 Counter = {
5 DataSource = Timer
6 Type = uint22
7 }
8 Time = {
9 Frequency = 1
10 DataSource = Timer
11 Type = uint32
12 }
13 }
14 OutputSignals = {
15 Counter = {
16 DataSource = DDB1
17 Type = uint32
18 }
19 Time = {
20 DataSource = DDB1
21 Type = uint32
22 }
23 }
24 }
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-8.cfg -l RealTimeLoader -s State1
Identify the typo in the configuration file that prevents the application from running.
Solution
A typo in the Counter signal type in the Display GAM is preventing the application from running. The signal is produced and offered to the GAMDataSource as a uint32 and is being consumed as a uint16 by the DisplayGAM.
$ [InitialisationError - RealTimeApplicationConfigurationBuilder.cpp:1160]: The data source assigned to the signal Counter in GAMDisplay is incompatible
$ [FatalError - RealTimeApplicationConfigurationBuilder.cpp:1037]: Failed to resolve for data source DDB1 and function GAMDisplay
1 +GAMTimer = {
2 Class = IOGAM
3 InputSignals = {
4 Counter = {
5 DataSource = Timer
6 Type = uint32
7 }
8 Time = {
9 Frequency = 1
10 DataSource = Timer
11 Type = uint32
12 }
13 }
14 OutputSignals = {
15 Counter = {
16 DataSource = DDB1
17 Type = uint32
18 }
19 Time = {
20 DataSource = DDB1
21 Type = uint32
22 }
23 }
24 }
25 +GAMDisplay = {
26 Class = IOGAM
27 InputSignals = {
28 Counter = {
29 DataSource = DDB1
30 Type = uint16
31 }
32 }
33 OutputSignals = {
34 Counter = {
35 DataSource = Display
36 Type = uint32
37 }
38 }
39 }
Ex. 7: Component instantiation 1
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-9.cfg -l RealTimeLoader -s State1
Identify and correct the typo in the configuration file that prevents the application from running.
Solution
A typo in the Class name of the GAMTimer does not allow MARTe to find the class to be automatically instantiated.
$ [Warning - LoadableLibrary.cpp:78]: LoadableLibrary: Failed dlopen(): iogam.so: cannot open shared object file: No such file or directory
$ [Warning - LoadableLibrary.cpp:78]: LoadableLibrary: Failed dlopen(): iogam.gam: cannot open shared object file: No such file or directory
$ [Warning - LoadableLibrary.cpp:78]: LoadableLibrary: Failed dlopen(): iogam.drv: cannot open shared object file: No such file or directory
$ [FatalError - Reference.cpp:129]: Reference: Failed CreateByName() in constructor
$ [FatalError - ReferenceContainer.cpp:421]: Failed to Initialise object with name +GAMTimer
All MARTe components are automatically instantiated by the framework based on the configuration file. The Class property of each component specifies the type of the component to be instantiated.
If there is a typo in the class name, MARTe will not be able to find the class and will fail to instantiate the component.
1 +GAMTimer = {
2 Class = iogam
3 InputSignals = {
4 Counter = {
5 DataSource = Timer
6 Type = uint32
7 }
8 Time = {
9 Frequency = 1
10 DataSource = Timer
11 Type = uint32
12 }
13 }
14 OutputSignals = {
15 Counter = {
16 DataSource = DDB1
17 Type = uint32
18 }
19 Time = {
20 DataSource = DDB1
21 Type = uint32
22 }
23 }
24 }
25 +GAMDisplay = {
Ex. 8: Component instantiation 2
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-10.cfg -l RealTimeLoader -s State1
Identify the typo in the configuration file that prevents the application from running.
Solution
The name of the component to be instantiated does not start with a + character, which is required for components that are to be instantiated by the framework at runtime. In this case the name of the component is GAMTimer instead of +GAMTimer.
$ [FatalError - RealTimeThread.cpp:156]: Undefined GAMTimer
$ [ParametersError - RealTimeApplicationConfigurationBuilder.cpp:104]: Failed to ResolveStates
1 GAMTimer = {
2 Class = IOGAM
3 InputSignals = {
4 Counter = {
5 DataSource = Timer
6 Type = uint32
7 }
8 Time = {
9 Frequency = 1
10 DataSource = Timer
11 Type = uint32
12 }
13 }
14 OutputSignals = {
15 Counter = {
16 DataSource = DDB1
17 Type = uint32
18 }
19 Time = {
20 DataSource = DDB1
21 Type = uint32
22 }
23 }
24 }
25 +GAMDisplay = {
Ex. 9: Multiple writers
Run the following application.
./MARTeApp.sh -f ../Configurations/HelloWorld/RTApp-HelloWorld-12.cfg -l RealTimeLoader -s State1
Identify and correct the typo in the configuration file that prevents the application from running.
Solution
The same signal is written by two different GAMs into the same DataSource. This is not allowed in MARTe and the application will fail to start with the following error message:
$ [FatalError - RealTimeApplicationConfigurationBuilder.cpp:2280]: Producers of Counter in DDB1 overlap write operations on the same memory area
$ [ParametersError - RealTimeApplicationConfigurationBuilder.cpp:125]: Failed to VerifyConsumersAndProducers
1 +GAMTimer = {
2 OutputSignals = {
3 Counter = {
4 DataSource = DDB1
5 Type = uint32
6 }
7 Time = {
8 DataSource = DDB1
9 Type = uint32
10 }
11 }
12 +GAMDisplay = {
13 OutputSignals = {
14 Counter = {
15 DataSource = DDB1
16 Type = uint32
17 }
18 }