Generating C code

Sinelabore creates compact and clearly readable C code from 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.

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 section 2.2 of 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.cfg

There are various configuration options to adjust the generated code:

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.

An example state diagram with regions is shown below. Imagine how much effort it would be 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.

All this allows to generate code that is optimal for your system. See the manual for a list of all available options. To generate C code call the code generator with the command line flag -l cx.

This results in the following files:

Example code generated from the oven example in the handbook:

#include "oven_ext.h"
#include "oven_hlp.h"
#include "oven.h"
#include <stdio.h>
 
extern unsigned char msg;
extern T_PWR pwr;
 
void  oven(OVEN_INSTANCEDATA_T *instanceVar){
 
	OVEN_EV_CONSUMED_FLAG_T evConsumed = 0U;
 
	/* Create a copy of the instance data.
	   Changes during the machine execution are done on the copy 
	   while tests (e.g. isIn) must use the unmodified instance data */
	OVEN_INSTANCEDATA_T instanceVarCopy = *instanceVar;
 
 
	switch (instanceVar->stateVar) {
 
		case Active:
			/* calling region code */
			evConsumed |= ovenLight(instanceVar, &instanceVarCopy, msg);
			evConsumed |= ovenPower(instanceVar, &instanceVarCopy, msg);
			evConsumed |= ovenRadioator(instanceVar, &instanceVarCopy, msg);
 
			/* Check if event was already processed  */
			if(evConsumed==0U){
 
				if(msg==(OVEN_EVENT_T)evDec){
					/* Transition from Active to Active */
 
					/* Exit code for regions in state Active */
 
					/* Action code for transition  */
					timer_dec();
 
 
 
					/* Entry code for regions in state Active */
					/* entry chain  */
					/* entry chain  */
					/* entry chain  */
 
 
					/* adjust state variables  */
					(&instanceVarCopy)->stateVar = Active;
				}else if(msg==(OVEN_EVENT_T)evInc){
					/* Transition from Active to Active */
 
					/* Exit code for regions in state Active */
 
					/* Action code for transition  */
					timer_inc();
 
 
 
					/* Entry code for regions in state Active */
					/* entry chain  */
					/* entry chain  */
					/* entry chain  */
 
 
					/* adjust state variables  */
					(&instanceVarCopy)->stateVar = Active;
				}else{
					/* Intentionally left blank */
				} /*end of event selection */
			}
		break; /* end of case Active  */
 
		case Inactive:
			if(1){
				/* Transition from Inactive to Active */
 
 
				/* Entry code for regions in state Active */
				/* entry chain  */
				/* entry chain  */
				/* entry chain  */
 
 
				/* adjust state variables  */
				(&instanceVarCopy)->stateVar = Active;
			}else{
				/* Intentionally left blank */
			} /*end of event selection */
		break; /* end of case Inactive  */
 
		default:
			/* Intentionally left blank */
		break;
	} /* end switch stateVar_root */
 
	/* Save the modified instance data */
	*instanceVar = instanceVarCopy;
}

Beside the state machine a UML class can also contain additional attributes and operations. Attributes are mapped as member variables of the state machine instance data. Operations are mapped to C-functions. The following example shows a class with an attribute and operation. Operations can be used beneficially to model entry/exit code or other helper functions. Attributes might represent internal variables of the stateful class. Class with an attribute and operation

For more details read section “Generating C Code” of the manual.