2.5 HelloWorld for C

2.5.1 Scope

In this tutorial you will build your first very simple eTrice model. The goal is to learn the work flow of eTrice and to understand a few basic features of ROOM. There are some more steps to do in C compared to Java. You will perform the following steps:

You will perform the following steps:

  1. create a new model from scratch
  2. add a very simple state machine to an actor
  3. create a launch configuration for the C code generator
  4. setup the C environment
  5. generate the source code
  6. run the model
  7. open the message sequence chart

Make sure that you have set up the workspace as described in Setting up the Workspace for C.

2.5.2 Create a new model from scratch

Before you can create a new C-model, you have to create a new C project as described in Setting up the Workspace for C Projects.

  1. select the C/C++ perspective
  2. select File->New->C Project from the main menue
  3. name the project HelloWorldC
  4. the project type is Executable / Empty C Project
  5. select the Toolchain for your platform (e.g. MinGW GCC)

Your project explorer should look like this:

PIC

The next step is to add the model folder: Right click on the new project. Select New->Folder and name it model.

PIC

Add the model file to the folder. Right click on the new folder. Select New->file and name it HelloWorldC.room.

PIC

Since the file extension .room is recognised as an Xtext based format, the tool will ask you to add the Xtext nature. Answer with Yes.

PIC

Open the HelloWorld.room file and delete the contents of the file. Open the content assist with <Ctrl>+<Space> and select RoomModel - model skeleton.

PIC

Edit the template variables by typing the new names and jumping with <Tab> from name to name.

The resulting model code should look like this:

1RoomModel HelloWorld_Model { 
2 
3 LogicalSystem LogSys1 { 
4   SubSystemRef subSysRef1: SubSysClass1 
5 } 
6 
7 SubSystemClass SubSysClass1 { 
8   ActorRef actorRef1: HelloWorldTop 
9   LogicalThread defaultThread 
10 } 
11 
12 ActorClass HelloWorldTop { } 
13 
14}

Now create the file model/HelloWorldC.etphys for the physical model and insert (<Ctrl>+<Space>) the code template PhysicalModel - model skeleton without changes.

Listing for HelloWorldC.etphys :

1PhysicalModel PhysicalModel1 { 
2 
3 PhysicalSystem PhysSys1 { 
4   NodeRef nodeRef1 : NodeClass1 
5 } 
6 
7 NodeClass NodeClass1 { 
8   runtime = RuntimeClass1 
9   priomin = -10 
10   priomax = 10 
11   DefaultThread PhysicalThread1 { 
12    execmode = mixed 
13    interval = 100 ms 
14    prio = 0 
15    stacksize = 1024 
16    msgblocksize = 32 
17    msgpoolsize = 10 
18   } 
19 } 
20 
21 RuntimeClass RuntimeClass1 { 
22   model = multiThreaded 
23 } 
24}

The physical model defines the setup of your nodes with their attributes like threads and mode of execution. In this case we define one node with one thread.

The mapping model we will create now defines the mapping (deployment) of the logical elements in the .room model to the physical elements int the .etphys model. Now create the file model/HelloWorldC.etmap for the mapping model and insert (Ctrl+Space) the code template MappingModel - model skeleton with some changes (jump with <Tab> between the template variables):

1MappingModel MappingModel1 { 
2 import HelloWorld_Model.* from "HelloWorld.room" 
3 import PhysicalModel1.* from "HelloWorld.etphys" 
4 Mapping LogSys1 -> PhysSys1 { 
5   SubSystemMapping subSysRef1 -> nodeRef1 { 
6    ThreadMapping defaultThread -> PhysicalThread1 
7   } 
8 } 
9}

Now the workspace should look like this:

PIC

The goal of eTrice is to describe distributed systems on a logical level. In the current version not all elements will be used. But as prerequisite for further versions the following elements can be defined:

The LogicalSystem represents the complete distributed system and contains at least one SubSystemRef. The SubSystemClass represents an address space (e.g. a linux process or an image for a microcontroller) and contains at least one ActorRef. The ActorClass is the building block for building the hierachical structure of an application. A good point to start is to define a top level actor that can be used as structural root within the subsystem.

The outline view of the textual ROOM editor shows the main modeling elements in a navigation tree. You can jump to an element in the textual editor by double clicking the element in the outline view.

PIC

2.5.3 Create a state machine

We will implement the Hello World code on the initial transition of the HelloWorldTop actor. Therefore open the state machine editor by right clicking the HelloWorldTop actor in the outline view and select Edit Behavior.

PIC

The state machine editor will be opened. Drag and drop an Initial Point from the tool box to the diagram into the top level state. Drag and drop a State from the tool box to the diagram. Confirm the dialogue with ok. Select the Transition in the tool box and draw the transition from the Initial Point to the State. Open the transition dialogue by double clicking the transition arrow and fill in the action code. Be aware of the different action code in Java and C.


_________________________________________ _________________________________________         

action code for Java

System.out.println("Hello World !");

 
_________________________________________________________________         

action code for C

printf("Hello World\n");


The result should look like this:

PIC

Save the diagram and inspect the model (HelloWorld.room) file. Note that the textual representation was changed after saving the diagram.


______________________________________________ ______________________________________________         

room model for Java

1RoomModel HelloWorld_Model { 
2 LogicalSystem LogSys1 { 
3   SubSystemRef subSysRef1:SubSysClass1 
4 } 
5 SubSystemClass SubSysClass1 { 
6   ActorRef actorRef1:HelloWorldTop 
7   LogicalThread defaultThread 
8 } 
9 ActorClass HelloWorldTop { 
10   Structure { } 
11   Behavior { 
12    StateMachine { 
13      Transition init: initial -> state0 { 
14       action { 
15         "System.out.println(\"Hello World\");" 
16       } 
17      } 
18      State state0 
19    } 
20   } 
21 } 
22}
___________________________________________________         

room model for C

1RoomModel HelloWorld_Model { 
2 LogicalSystem LogSys1 { 
3   SubSystemRef subSysRef1: SubSysClass1 
4 } 
5 SubSystemClass SubSysClass1 { 
6   ActorRef actorRef1: HelloWorldTop 
7   LogicalThread defaultThread 
8 } 
9 ActorClass HelloWorldTop { 
10   Structure { } 
11   Behavior { 
12    StateMachine { 
13      Transition init: initial -> state0 { 
14       action { 
15         "printf(\"Hello World\\n\");" 
16       } 
17      } 
18      State state0 
19    } 
20   } 
21 } 
22}

2.5.4 Create a launch configuration to start the C code generator

Unlike in Java a launch configuration for the C code generator must be created.

From the main menu Run or the context menu Run As in the Project Explorer select Run Configurations .

PIC

Within the dialog select eTrice C Generator and click the New button to create a new launch configuration.

PIC

A new configuration should be created. Name it gen_HelloWorld and add the mapping model HelloWorld.etmap model via one of the add buttons.

PIC

The mapping model is the root model for the code generator.

To save your launch configuration, select Shared file in the tab Common and add the HelloWorldC project via the Browse button.

PIC

Apply your changes. The new configuration should now exist in your workspace.

PIC

2.5.5 Generate the code

Now you can generate the code. Right click on the launch configuration and run it as gen_HelloWorldC.

PIC

The code should be generated and placed in the src-gen folder.

PIC

2.5.6 Setup the C build

Before you can build the application you must setup the include and library pathes for the runtime system.

Right click the project and select Properties -> C/C++ Build -> Settings -> Includes. Add the include path for the current project src-gen and the runtime source folders common, config and the chosen platform ( MT_WIN_MinGW or MT_POSIX_GENERIC_GCC ).

PIC

Add the runtime library: Properties -> C/C++ Build -> Settings -> Libraries.

PIC

The name of the library is org.eclipse.etrice.runtime.c but the actual filename for the library is liborg.eclipse.etrice.runtime.c.a .

Exclude the folder src-gen-info from the build path. This folder is used to store temporary files for the incremetal code generation and must not be compiled in order to avoid multiple definition of symbols.

PIC

2.5.7 Build and run the model

Now you can build the application. Click the build button (hammer symbol) to build the application. Run the application in the folder Binary as Local C/C++ Application. The output in the Console View should contain the message Hello World.

PIC

2.5.8 Open the Message Sequence Chart

For debugging and learning purposes, the application produced a Message Sequence Chart and wrote it to a file. Open the file subSysRef1_Async.seq or msc.seq in the folder HelloWorld/tmp/log/ using the tool Trace2UML. Create the path if not already there.

Trace2UML is an open source MSC viewer and can be obtained here:

After opening the file, you should see something like this:

PIC

The Actor with the instance path /LogSys1/subSysRef1/actorRef1 is in the state state0. This is the simplest possible MSC. The MSCs for further tutorials will contain more information.

2.5.9 Summary

You are now familiar with all necessary steps to create, build and run an eTrice C model from scratch. You are able to create a launch configuration to start the code generator and to perform all necessary settings to compile and link the application.

The next tutorial provides an exercise to get more familiar with these working steps.