Reconfiguration

As discussed in the application kick-starting section, the Loader component (or any component inheriting from it) is responsible for configuring and starting a standard MARTe applicaton (i.e. one that relies on the MARTeApp.cpp).

The Loader component also offers a reconfiguration interface (see Loader::Reconfigure) that can be used in runtime to modify the configuration of an application that is already in execution.

Any component inheriting from the Loader class can implement the PostInit method in order to receive runtime configuration parameters (e.g. a TCP port where to listen for new configurations).

The Loader also offers a set of pre-defined message triggers that are sent: before the configuration is modified; after the configuration is (successfully) applied; in case a configuration error occurs; and if a configuration occurs and the user has configured the option to reload the last valid configuration.

Finally, the Loader components also allows to query the currently loaded configuration (see Loader::GetLastValidConfiguration).

The ConfigurationLoaderTCP in an implementation that allows changing the runtime configuration over a TCP connection.

Examples

Valid reconfiguration

This is an example of a MARTeApp that uses a ConfigurationLoaderTCP.

Start the application with the -m parameter.

To modify a configuration, start the application and, on another console, type nc localhost 24680 < RTApp-9-reload.cfg.

The new configuration has a higher cycle time so that the frequency at which the signals are printed into console should significantly increase.

To return to a configuration running at a lower frequency, on another console, type nc localhost 24680 < RTApp-9-reload-2.cfg.

ConfigurationLoaderTCP application (Run with NAME_OF_THE_MESSAGE=StateMachine:START and NAME_OF_THE_CONFIGURATION_FILE=RTApp-9.cfg)
  1+LoaderPostInit = {
  2    Class = ReferenceContainer
  3    +Parameters = {
  4        Class = ConfigurationDatabase
  5        Port = 24680//The port where to listen for the TCP messages.
  6        ReloadLast = true //Reload old configuration in case of (re)configuration failure? Default = true. If true the FailedConfiguration message will not to be sent.
  7    }
  8    +Messages = {
  9       Class = ReferenceContainer
 10       +PreConfiguration = { //Optional message to send before the configuration is applied.
 11           Class = Message
 12           Destination = StateMachine 
 13           Function = STOP
 14           Mode = ExpectsReply
 15       }
 16       +PostConfiguration = { //Optional message to send if the configuration was successfully applied.
 17           Class = Message
 18           Destination = StateMachine 
 19           Function = START
 20           Mode = ExpectsReply
 21       }
 22    }
 23}
 24+StateMachine = {
 25    Class = StateMachine
 26    +INITIAL = {
 27        Class = ReferenceContainer
 28        +START = {
 29            Class = StateMachineEvent
 30            NextState = "STATE1"
 31            NextStateError = "ERROR"
 32            Timeout = 0
 33            +ChangeToState1Msg = {
 34                Class = Message
 35                Destination = TestApp
 36                Mode = ExpectsReply
 37                Function = PrepareNextState
 38                +Parameters = {
 39                    Class = ConfigurationDatabase
 40                    param1 = State1
 41                }
 42            }
 43            +StartNextStateExecutionMsg = {
 44                Class = Message
 45                Destination = TestApp
 46                Function = StartNextStateExecution
 47                Mode = ExpectsReply
 48            }
 49        }
 50    }
 51    +STATE1 = {
 52        Class = ReferenceContainer
 53        +GOTOSTATE2 = {
 54            Class = StateMachineEvent
 55            NextState = "STATE2"
 56            NextStateError = "ERROR"
 57            Timeout = 0
 58            +PrepareChangeToState2Msg = {
 59                Class = Message
 60                Destination = TestApp
 61                Mode = ExpectsReply
 62                Function = PrepareNextState
 63                +Parameters = {
 64                    Class = ConfigurationDatabase
 65                    param1 = State2
 66                }
 67            }
 68            +StopCurrentStateExecutionMsg = {
 69                Class = Message
 70                Destination = TestApp
 71                Function = StopCurrentStateExecution
 72                Mode = ExpectsReply
 73            }
 74            +StartNextStateExecutionMsg = {
 75                Class = Message
 76                Destination = TestApp
 77                Function = StartNextStateExecution
 78                Mode = ExpectsReply
 79            }
 80        }
 81        +STOP = {
 82            Class = StateMachineEvent
 83            NextState = "STOPPED"
 84            NextStateError = "ERROR"
 85            Timeout = 0
 86            +StopCurrentStateExecutionMsg = {
 87                Class = Message
 88                Destination = TestApp
 89                Function = StopCurrentStateExecution
 90                Mode = ExpectsReply
 91            }
 92        }
 93        +ERROR = {
 94            Class = StateMachineEvent
 95            NextState = "ERROR"
 96            NextStateError = "ERROR"
 97        }
 98    }
 99    +STATE2 = {
100        Class = ReferenceContainer
101        +GOTOSTATE1 = {
102            Class = StateMachineEvent
103            NextState = "STATE1"
104            NextStateError = "ERROR"
105            Timeout = 0
106            +PrepareChangeToState1Msg = {
107                Class = Message
108                Destination = TestApp
109                Mode = ExpectsReply
110                Function = PrepareNextState
111                +Parameters = {
112                    Class = ConfigurationDatabase
113                    param1 = State1
114                }
115            }
116            +StopCurrentStateExecutionMsg = {
117                Class = Message
118                Destination = TestApp
119                Function = StopCurrentStateExecution
120                Mode = ExpectsReply
121            }
122            +StartNextStateExecutionMsg = {
123                Class = Message
124                Destination = TestApp
125                Function = StartNextStateExecution
126                Mode = ExpectsReply
127            }
128        }
129        +STOP = {
130            Class = StateMachineEvent
131            NextState = "STOPPED"
132            NextStateError = "ERROR"
133            Timeout = 0
134            +StopCurrentStateExecutionMsg = {
135                Class = Message
136                Destination = TestApp
137                Function = StopCurrentStateExecution
138                Mode = ExpectsReply
139            }
140        }
141        +ERROR = {
142            Class = StateMachineEvent
143            NextState = "ERROR"
144            NextStateError = "ERROR"
145        }
146    }
147    +STOPPED = {
148        Class = ReferenceContainer
149        +START = {
150            Class = StateMachineEvent
151            NextState = "STATE1"
152            NextStateError = "ERROR"
153            Timeout = 0
154            +ChangeToState1Msg = {
155                Class = Message
156                Destination = TestApp
157                Mode = ExpectsReply
158                Function = PrepareNextState
159                +Parameters = {
160                    Class = ConfigurationDatabase
161                    param1 = State1
162                }
163            }
164            +StartNextStateExecutionMsg = {
165                Class = Message
166                Destination = TestApp
167                Function = StartNextStateExecution
168                Mode = ExpectsReply
169            }
170
171        }
172    }
173    +ERROR = {
174        Class = ReferenceContainer
175        +ENTER = {
176            Class = ReferenceContainer
177            +StopCurrentStateExecutionMsg = {
178                Class = Message
179                Destination = TestApp
180                Function = StopCurrentStateExecution
181                Mode = ExpectsReply
182            }
183            +PrepareChangeToErrorMsg = {
184                Class = Message
185                Destination = TestApp
186                Mode = ExpectsReply
187                Function = PrepareNextState
188                +Parameters = {
189                    Class = ConfigurationDatabase
190                    param1 = StateError
191                }
192            }
193            +StartNextStateExecutionMsg = {
194                Class = Message
195                Destination = TestApp
196                Function = StartNextStateExecution
197                Mode = ExpectsReply
198            }
199        }
200        +RESET = {
201            Class = StateMachineEvent
202            NextState = "STATE1"
203            NextStateError = "STATE1"
204            Timeout = 0
205            +StopCurrentStateExecutionMsg = {
206                Class = Message
207                Destination = TestApp
208                Function = StopCurrentStateExecution
209                Mode = ExpectsReply
210            }
211            +PrepareChangeToState1Msg = {
212                Class = Message
213                Destination = TestApp
214                Mode = ExpectsReply
215                Function = PrepareNextState
216                +Parameters = {
217                    Class = ConfigurationDatabase
218                    param1 = State1
219                }
220            }
221            +StartNextStateExecutionMsg = {
222                Class = Message
223                Destination = TestApp
224                Function = StartNextStateExecution
225                Mode = ExpectsReply
226            }
227        }
228    }
229}
230$TestApp = {
231    Class = RealTimeApplication
232    +Functions = {
233        Class = ReferenceContainer
234        +GAMTimer = {
235            Class = IOGAM
236            InputSignals = {
237                Counter = {
238                    DataSource = Timer
239                    Type = uint32
240                }
241                Time = {
242                    Frequency = 1
243                    DataSource = Timer
244                    Type = uint32
245                }
246            }
247            OutputSignals = {
248                Counter = {
249                    DataSource = DDB1
250                    Type = uint32
251                }
252                Time = {
253                    DataSource = DDB1
254                    Type = uint32
255                }
256            }
257        }
258        +GAMVariable1 = {
259            Class = VariableGAMExample1
260            Gains = {2, 3, 4}
261            InputSignals = {
262                Counter = {
263                    DataSource = DDB1
264                    Type = uint32
265                }                
266            }
267            OutputSignals = {
268                GainCounter1Thread1 = {
269                    DataSource = DDB1
270                    Type = uint32
271                }
272                GainCounter2Thread1 = {
273                    DataSource = DDB1
274                    Type = uint32
275                }
276                GainCounter3Thread1 = {
277                    DataSource = DDB1
278                    Type = uint32
279                }                
280            }
281        }
282        +GAMT1TSynchOut = {
283            Class = IOGAM
284            InputSignals = {
285                GainCounter1Thread1 = {
286                    DataSource = DDB1
287                    Type = uint32
288                }
289                GainCounter2Thread1 = {
290                    DataSource = DDB1
291                    Type = uint32
292                }
293                GainCounter3Thread1 = {
294                    DataSource = DDB1
295                    Type = uint32
296                }
297            }
298            OutputSignals = {
299                GainCounter1Thread1 = {
300                    DataSource = RTThreadSynch
301                    Type = uint32
302                }
303                GainCounter2Thread1 = {
304                    DataSource = RTThreadSynch
305                    Type = uint32
306                }
307                GainCounter3Thread1 = {
308                    DataSource = RTThreadSynch
309                    Type = uint32
310                }
311            }
312        }
313        +GAMT1T2Interface = {
314            Class = IOGAM
315            InputSignals = {
316                GainCounter1Thread1 = {
317                    DataSource = RTThreadSynch
318                    Type = uint32
319                    Samples = 2 //Run at half the frequency of thread 1
320                }
321                GainCounter2Thread1 = {
322                    DataSource = RTThreadSynch
323                    Type = uint32
324                    Samples = 2 //Run at half the frequency of thread 1
325                }
326                GainCounter3Thread1 = {
327                    DataSource = RTThreadSynch
328                    Type = uint32
329                    Samples = 2 //Run at half the frequency of thread 1
330                }
331            }
332            OutputSignals = {
333                GainCounter1Thread2 = {
334                    DataSource = DDB1
335                    Type = uint32
336                    Samples = 1
337                    NumberOfDimensions = 1
338                    NumberOfElements = 2 //2 elements for each cycle (as it waits for 2 samples)
339                }
340                GainCounter2Thread2 = {
341                    DataSource = DDB1
342                    Type = uint32
343                    Samples = 1
344                    NumberOfDimensions = 1
345                    NumberOfElements = 2 //2 elements for each cycle (as it waits for 2 samples)
346                }
347                GainCounter3Thread2 = {
348                    DataSource = DDB1
349                    Type = uint32
350                    Samples = 1
351                    NumberOfDimensions = 1
352                    NumberOfElements = 2 //2 elements for each cycle (as it waits for 2 samples)
353                }
354            }
355        }
356        +GAMT1T3Interface = {
357            Class = IOGAM
358            InputSignals = {
359                GainCounter1Thread1 = {
360                    DataSource = RTThreadSynch
361                    Type = uint32
362                    Samples = 4 //Run at one quarter of the frequency of thread 1
363                }
364                GainCounter2Thread1 = {
365                    DataSource = RTThreadSynch
366                    Type = uint32
367                    Samples = 4 //Run at one quarter  the frequency of thread 1
368                }
369                GainCounter3Thread1 = {
370                    DataSource = RTThreadSynch
371                    Type = uint32
372                    Samples = 4 //Run at one quarter  the frequency of thread 1
373                }
374            }
375            OutputSignals = {
376                GainCounter1Thread3 = {
377                    DataSource = DDB1
378                    Type = uint32
379                    Samples = 1
380                    NumberOfDimensions = 1
381                    NumberOfElements = 4 //4 elements for each cycle (as it waits for 4 samples)
382                }
383                GainCounter2Thread3 = {
384                    DataSource = DDB1
385                    Type = uint32
386                    Samples = 1
387                    NumberOfDimensions = 1
388                    NumberOfElements = 4 //4 elements for each cycle (as it waits for 4 samples)
389                }
390                GainCounter3Thread3 = {
391                    DataSource = DDB1
392                    Type = uint32
393                    Samples = 1
394                    NumberOfDimensions = 1
395                    NumberOfElements = 4 //4 elements for each cycle (as it waits for 4 samples)
396                }
397            }
398        }
399        +GAMDisplayThread1 = {
400            Class = IOGAM            
401            InputSignals = {
402                Counter = {
403                    DataSource = DDB1
404                    Type = uint32
405                }
406                GainCounter1Thread1 = {
407                    DataSource = DDB1
408                    Type = uint32
409                }
410                GainCounter2Thread1 = {
411                    DataSource = DDB1
412                    Type = uint32
413                }
414                GainCounter3Thread1 = {
415                    DataSource = DDB1
416                    Type = uint32
417                }            
418            }
419            OutputSignals = {
420                Counter = {
421                    DataSource = LoggerDataSource
422                    Type = uint32
423                }
424                GainCounter1Thread1 = {
425                    DataSource = LoggerDataSource
426                    Type = uint32
427                }
428                GainCounter2Thread1 = {
429                    DataSource = LoggerDataSource
430                    Type = uint32
431                }
432                GainCounter3Thread1 = {
433                    DataSource = LoggerDataSource
434                    Type = uint32
435                }
436            }
437        }
438        +GAMDisplayThread2 = {
439            Class = IOGAM            
440            InputSignals = {
441                GainCounter1Thread2 = {
442                    DataSource = DDB1
443                    Type = uint32
444                }
445                GainCounter2Thread2 = {
446                    DataSource = DDB1
447                    Type = uint32
448                }
449                GainCounter3Thread2 = {
450                    DataSource = DDB1
451                    Type = uint32
452                }            
453            }
454            OutputSignals = {
455                GainCounter1Thread2 = {
456                    DataSource = LoggerDataSource
457                    Type = uint32
458                    NumberOfDimensions = 1
459                    NumberOfElements = 2
460                }
461                GainCounter2Thread2 = {
462                    DataSource = LoggerDataSource
463                    Type = uint32
464                    NumberOfDimensions = 1
465                    NumberOfElements = 2
466                }
467                GainCounter3Thread2 = {
468                    DataSource = LoggerDataSource
469                    Type = uint32
470                    NumberOfDimensions = 1
471                    NumberOfElements = 2
472                }
473            }
474        }
475        +GAMDisplayThread3 = {
476            Class = IOGAM            
477            InputSignals = {
478                GainCounter1Thread3 = {
479                    DataSource = DDB1
480                    Type = uint32
481                }
482                GainCounter2Thread3 = {
483                    DataSource = DDB1
484                    Type = uint32
485                }
486                GainCounter3Thread3 = {
487                    DataSource = DDB1
488                    Type = uint32
489                }            
490            }
491            OutputSignals = {
492                GainCounter1Thread3 = {
493                    DataSource = LoggerDataSource
494                    Type = uint32
495                    NumberOfDimensions = 1
496                    NumberOfElements = 4
497                }
498                GainCounter2Thread3 = {
499                    DataSource = LoggerDataSource
500                    Type = uint32
501                    NumberOfDimensions = 1
502                    NumberOfElements = 4
503                }
504                GainCounter3Thread3 = {
505                    DataSource = LoggerDataSource
506                    Type = uint32
507                    NumberOfDimensions = 1
508                    NumberOfElements = 4
509                }
510            }
511        }
512    }
513    +Data = {
514        Class = ReferenceContainer
515        DefaultDataSource = DDB1
516        +DDB1 = {
517            Class = GAMDataSource
518        }
519        +LoggerDataSource = {
520            Class = LoggerDataSource
521        }
522        +Timings = {
523            Class = TimingDataSource
524        }
525        +RTThreadSynch = {
526            Class = RealTimeThreadSynchronisation
527            Timeout = 5000 //Timeout in ms to wait for the thread to cycle.
528        }
529        +Timer = {
530            Class = LinuxTimer
531            SleepNature = "Default"
532            Signals = {
533                Counter = {
534                    Type = uint32
535                }
536                Time = {
537                    Type = uint32
538                }
539            }
540        }
541    }
542    +States = {
543        Class = ReferenceContainer
544        +State1 = {
545            Class = RealTimeState
546            +Threads = {
547                Class = ReferenceContainer
548                +Thread1 = {
549                    Class = RealTimeThread
550                    CPUs = 0x1
551                    Functions = {GAMTimer GAMVariable1 GAMT1TSynchOut GAMDisplayThread1}
552                }
553            }
554        }
555        +State2 = {
556            Class = RealTimeState
557            +Threads = {
558                Class = ReferenceContainer
559                +Thread1 = {
560                    Class = RealTimeThread
561                    CPUs = 0x1
562                    Functions = {GAMTimer GAMVariable1 GAMT1TSynchOut GAMDisplayThread1}
563                }
564                +Thread2 = {
565                    Class = RealTimeThread
566                    CPUs = 0x2
567                    Functions = {GAMT1T2Interface GAMDisplayThread2}
568                }
569                +Thread3 = {
570                    Class = RealTimeThread
571                    CPUs = 0x4
572                    Functions = {GAMT1T3Interface GAMDisplayThread3}
573                }
574            }
575        }
576        +StateError = {
577            Class = RealTimeState
578            +Threads = {
579                Class = ReferenceContainer
580                +Thread1 = {
581                    Class = RealTimeThread
582                    CPUs = 0x1
583                    Functions = {GAMTimer}
584                }
585            }
586        }
587    }
588    +Scheduler = {
589        Class = GAMScheduler
590        TimingDataSource = Timings
591    }
592}

Invalid reconfiguration

Given that the application was launched with the parameter ReloadLast=true, a failed reconfiguration attempt will trigger the reloading of the last valid configuration.

To load an invalid configuration, start the application and, on another console, type nc localhost 24680 < RTApp-9-reload-fail.cfg. Notice that the application will continue to run at the original frequency.