Generating C Code#
Sinelabore creates compact and clearly readable C code from hierarchical UML state charts. There are a number of different ways in which the generated code can be fine-tuned through the setting of configuration parameters. This allows generation to follow known patterns, which are illustrated with examples below.
-
Object pattern: Instance related data is always grouped in a struct. All state machine related functions operate on this data struct. The advantage is that the data flow is easy to follow, the code is re-entrant because there is no global manipulated state, and multiple instances are easy to realise.
-
Opaque object pattern: This is similar to the object pattern, but hides the implementation from the outside of the generating state machine code. This further reduces dependencies between the state machine implementation and other code. See also https://en.wikipedia.org/wiki/Opaque_pointer
-
Single instance pattern: Typically there is only one instance and no instance pointer is needed. For example, implementing an IRQ handler as a state machine, or using a hardware module in the state machine that exists only once.
Used C-Language Constructs#
In the generated code, state hierarchies are mapped to nested switch/case code. Event handling code is mapped to if/else-if/else structures. The various configuration parameters allow you to generate code that is optimal for your system. See the PDF manual for a list of all available options. To generate C code call the code generator with the command line flag -l cx. To generate a configuration file with all parameters related to the C code generation call the code generator as follows once:
java -cp path_to_bin_folder/* codegen.Main -l cx -gencfg > codegen.cfgThere are various configuration options to adjust the generated code usage e.g.
- As interrupt handler without any parameterss:
#pragma vector=UART0TX_VECTOR
__interrupt void irq_handler(void) {
/* generated state machine call */
testcase(EVENT_TIMEOUT);
}- Having only the event as parameter of the handler
- Having an instance pointer and event as parameter (for running multiple instances of the same machine e.g.
void testcase(TESTCASE_INSTANCEDATA_T *instanceVar, TESTCASE_EVENT_T msg ))- Having an own defined parameter containing the event which allow to easily send data with the event
void testcase(TESTCASE_INSTANCEDATA_T *instanceVar, USER_EVENT_T *userData)-
Support for externally defined events (i.e. outside the UML diagram) to better support reuse of legacy code
-
Support for conditional events (i.e. boolean expressions)
-
The C backend has features for high-availability applications where it is desirable to detect serious errors happening outside the state machine code but effecting the correct execution of the state machine. Such errors might come from a runaway pointer overwriting key variables, power brownout corrupting a bit or a bad ram cell losing a bit to name a few. To detect and handle such situations is an overall system design task. But the code generator can help you to detect inconsistencies of the state machine offering different mechanisms described in the manual.
-
The code generator supports code generation from models with regions. A region is an orthogonal part of a state. Regions allow to express parallelism within a state. A state can have two or more regions. Region contains states and transitions.
Showcasing the Generation of C-Code from a hierarchical State Chart#
This example was created with EA and is available on Github (examples/LinuxMacBSD/microwave_ea_hierachical_c). On top level a class diagram is required with a class that owns a state machine diagram.
. The diagram showcases also how additional include files and local variables can be defined that are added to the generated code.
An example state diagram modeling a hierarchical microwave oven is shown below. Imagine the effort to manually write the code for this machine. And even worse how difficult it would be to maintain it over time when new states/events are added.

At startup of the machine it is decided whether the error state is entered or not using a choice pseudostate that takes its decision based on a self test function. This function was modeled as activity. Also this code can be fully generated by the code generator.

How to generate the code for the state – and the activity diagram is to run the following commands:
Generated Files#
This results in the following files:
- C-file with the state machine implementation
- H-file of the state machine
- H-file with the events that can be sent to the machine
- Main and hlp files with some code that supports debugging i.e. sending events to the machine and realizing the timeout events.
Example code generated from the oven example in the handbook: