Technical topic: Use of timers in user code with TASTE

From TASTE
Jump to: navigation, search

Introduction

This section explains how to use timers with TASTE. Timers are used when you want to implement requirements such as:

 Ring the bell
 Wait 10 seconds
 Ring Again
 Wait 10 Seconds
 Go back home

Those kind of requirements are very frequent in embedded systems such as satellites, where complex scenarii occur at runtime to maintain the state of the system, or to discover it after a reboot.

However, if timers seem "obvious" to end users, in critical real-time systems they are not easily implemented. TASTE runtime is based on the Ravenscar profile, which is a set of rules that dictates what constructs can be used for a real-time system to be analysable and feasible.

Among the Ravenscar rules, an important constraints is that when executing, a thread must run to completion, i.e. must run until its next activation condition, without blocking in the middle of the user code. In other words, making a system call that suspends the thread is forbidden, as it would mess up the overall system scheduling: the entry point of a thread must be set at one place only (i.e. at the reception of a message or at the next cycle in case of a periodic thread).

Keeping those restrictions in mind, TASTE is providing, through model transformations and code generation, a practical and transparent mechanism to define and use timers that can be triggered in the user code without violating the Ravenscar computational model.

We will see how to use timers using the SDL language. This language has a built-in timer construct, which makes the use of timer natural and elegant.

You may look at the following demo to see how timers can also be used with C and Ada:

~/tool-src/testSuites/Regression_AADLv2/Demo_Timers/

Declare Timers in the TASTE interface view

Create a new TASTE system:

$ mkdir demo
$ cd demo
$ taste-create-interface-view

When the interface view editor opens, create two functions (right-click and select New Function). Name your functions, e.g. test_timers and my_gui.

Timers(1)

Double click on each function to set the impplementation language. Use SDL for "test_timers" and GUI for "my_gui"

Add a provided interface to the test_timers function (Rick-click on the function and select New PI). Name your provided interface (e.g. hello) and set it to Sporadic. Add a parameter (choose any type from the list, e.g. T-Uint32). Add a corresponding Required interface of the other function, and click on it to draw a connection between the Required and the Provided interface.

Now double-click again to edit the properties of the test_timers functions. Click on the Context Parameters tab, and add a timer there, as on the following picture:

Timers(2)

You may declare multiple timers. As you can see the "Timer" type is proposed in the list.

Now exit the property menu, and right-click on the function to edit the functional code (in that case open the SDL editor):

Timers(3)

Write the user code

Here is what you get. A timer has been declared in the model for you, together with explanations on how to use the timer.

Timers(4)

This is how we can fill the SDL model to make a simple use of the timer, based on the reception of the "hello" message from the GUI. The scenario is the following:

Wait for hello
On reception of hello set a 5 seconds timer
If hello is received again before timer expiration, reset (disable) the timer
Otherwise, after 5 seconds, display a message

SDL is well suited for this kind of scenarii, as it is a state machine:

Timers(5)

When you are done editing, save your model and exit the tool.

Create a deployment view and build your system

The last thing you have to do before being able to test your system is to select your target processor/OS on which you want to run your system. Back in the interface view, click on the Tools menu and open the Deployment View editor.

Timers(6)

Mimic the picture above - make a simple deployment by dragging and dropping a Linux32 processor on the canvas, and right click to bind your two functions on it. You may rename the partition (e.g. call it demo): this will be the name of the binary application that will be generated for this system.

When you are done, save and quit the deployment view editor. You get back to the Interface view editor.

Build the system and try it

Click on the Tools menu and select Build system (in C or in Ada). A terminal will open showing the progress of the build ; after a while you will see the completion result:

Timers(7)

We can now go to the pointed directory and try to run the generated binaries (one for the GUI and one for the main system, that comprises the test_timers function).

Exit the interface view
$ cd binary/binaries
$ xterm -e ./GUI-mygui &
$ ./demo

The GUI will open, offering the possibility to send the hello message to the main binary.

Timers(8)

Click on Send and look at the console where you ran the demo binary

./demo
Timer set!
Timer expired!     # It should appear after 5 seconds

And you send the hello message twice:

Timer set!
Timer reset!

Icing on the cake

You can use the MSC recorder to observe the internal behaviour of the system. Instead of running

$ xterm -e ./GUI-mygui &
$ ./demo

Run:

$ xterm -e ./GUI-mygui &
$ taste-run-and-trace ./demo

Perform the scenario of your choice when the GUI run, and hit Ctrl-C when you are done. You will get a file called trace.msc. Open it with the MSC Editor:

$ msce.py -o trace.msc

And you will see a trace of the system execution, showing when the timer has been set and reset (and showing all messages exchanged in the system):

Timers(9)

Additional information

Timer value has to be a multiple of 100 ms, that is the time quantum used by the timer manager. The timer manager is a function that is generated during the vertical transformation of your system and that has a periodic interface triggered every 100ms. It holds all the timers states of a node and is responsible for invoking the interface of the user code that corresponds to timer expiration. It has SET and RESET interfaces that are immediate interfaces the user code can invoke whenever the timer must be activated or disabled.

Credits

Timer management designed and implemented by Maxime Perrotin/ESA

MSC tracing function by Thanassis Tsiodras (updated by MP for the timer symbols and interface to TASTE MSC Editor)

MSC Editor written by Angel Esquinas Fernandez