Embedded Engineer can emit plain C-code which you can use with any toolchain that supports C89 or higher. This has many benefits, one being a small footprint of the resulting executable, another the availability of C-compilers for nearly every platform imaginable.
However, this comes with a trade-off: While C was not built with object orientation support in mind, object orientation is a fundamental concept in UML2.
Therefore, the code generator has to translate the object oriented model into C-code which does not support many of the object oriented concepts natively.
The following chapters explain how the code generator performs this translation for the elements typically found in a class, and how this transformation can be adjusted.
The class itself is translated to a struct which contains every attribute in the class, and also instance variables for the state machines of the class.
- The current instance is always available through the variable me.
- Attributes in UML classes correspond to fields in C-structures.
- Static attributes are not part of any structure.
- Access control modifiers do not get translated in general, except with private static attributes, which will be generated as static variables.
- External variables are specified by the extern stereotype on attributes.
You can skip code generation for a class and all its members by specifying the NoCodeGen tagged value or the no code generation Stereotype, and set the value to True. The NoCodeGen tagged value can be set on packages or class elements.
The NoCodeGen tagged value can be set on packages or class elements.
If you want to define an Entry Point to your application, for example if you want to generate all of your code, you can define a class as entry point for the application.
To do so, give the class the stereotype executable entry point. You can do this by using the Toolbox, or you can add it manually.
Now you have to define which behavior you'd like as entry to the application. You can do so by adding the tagged value ClassifierBehavior (if you have the MDG technology for LieberLieber Embedded Engineer enabled, this will automatically be done for you when you apply the stereotype), and selecting the operation/functionbehavior as value for the tag:
Now this method or behavior will be treated specially. Its name will never be changed, so you can rely on this name, for example for defining a main function.
The code generator supports the singleton pattern. If you mark a class with the stereotype singleton (for example by using the Toolbox), the generated operations and behaviors of that class will access a statically allocated structure, and therefore have no explicit parameter for the class.
You can still access the class in your operations and behaviors with me – the necessary code is automatically added to the generated functions – but you never have to pass the parameter around explicitely.
Please use the singleton pattern wisely, it's probably the pattern which is misused the most, and it's hard to use it correctly.While it makes modeling easier because you don't have to care about the instance variable, only use it if you really have to.
With Embedded Engineer you have the possibility to mark classes as static. Just give them the stereotype static (for example by using the Toolbox).
This has the following effects:
- No structure will be generated for the class, therefore you cannot have behavioral models which depend on a structure in a static class.
Effectively this means that you can have activities in a static class, but no state machines.
- Private attributes will be generated as static variables in the .c file of the class, effectively hiding them from other modules.
- Public attributes will be generated as variables in the .c file of the class, with the corresponding extern declaration in the public .h file.
- If an initial value is defined for an attribute, the corresponding variable in C will be set to this value.
- All operations of this class will be static automatically. You don't have to mark them as static explicitely.
Attributes & Operations
Attributes are a vital part of every class in UML2. For the most part, the translation to C-code is straightforward. For example, type respectively name will be equivalent in the generated code and the model.
However, there are a few specialities to enable features of C which are not part of UML2:
- Toolbox). If you specify the stereotype extern, the attribute will be extern (also available in the
- Static attributes will be generated as top level variables. Private static attributes will be hidden from other compilation units, public static attributes will be available by including the .h file of the class.
- Private/Public affects only top level attributes (for example attributes of static classes, see static classes for more information).
- For non-static attributes, the attribute will be set to the initial value when calling the constructor-method. For static attributes, the attribute will be declared and defined at once.
- Readonly attributes can be created with the readonly stereotype.
Operations in UML2 are usually part of classes, as such the code generation works as follows.
For methods, a parameter is inserted which should point to an instance of the generated C structure. The default name of this parameter is me (in C++, the object orientation support of the language is used, so this reference is called this). For method calls in activity or state machine diagrams, this parameter is automatically assigned to me. For details how the name of an operation is generated, see the Naming chapter.
For static operations (functions), there is no such automatic parameter introduction. Find out more about Static Operations!For singletons, the situation is similar. Find out more about Singletons!