SinelaboreRT Header Logo


It's better when it's simple!

User Tools

Site Tools


UML-Tool specific Intro

Language Backends



Designers Toolbox

Integrated state-chart editor with auto-layout

Focus on modeling and not on moving states around to create a nice looking diagram! Syntax aware text fields offer a comfortable way to specify actions, guards etc. When the diagram passed the model checker it can be directly simulated. Connect the diagram to the real hardware to monitor the state machine in action.

There are better ways to model state machines than using spread sheets!

In the past different μC manufacturers have published application notes about the benefit of using state machines for the design of embedded software. An example is the application note SLAA402 from Texas Instruments (TI). It suggests to generate source code based on a spread sheet table. Nowadays several affordable UML modeling tools are available supporting the efficient design of state machines in a graphical way. SinelaboreRT generates production quality source code from state diagrams created with many different UML tools. Give it a try!

Latest Changes

Model-based testing of state machines 2020/02/23 19:32 Peter Mueller  
DCF77 Radio Clock 2020/02/23 19:27 Peter Mueller ,
Getting started with a Traffic Lights example on MSP430 - part 1 2020/02/23 19:26 Peter Mueller , , , ,
Astah SysML 2020/02/23 19:22 Peter Mueller  
Generate production quality code from state diagrams created with Enterprise Architect 2020/02/23 19:20 Peter Mueller  
Features 2020/02/23 19:18 Peter Mueller  
Generate efficient source code from UML state diagrams and activity diagrams! 2020/02/22 20:00 Peter Mueller  

Generate efficient source code from UML state diagrams and activity diagrams!

Build robust event-driven embedded real-time software based on hierarchical state machines.

SinelaboreRT is specially for embedded software developers. It focuses on just one task: Generation of readable and maintainable source code from hierarchical UML state diagrams - and activity diagrams. With its unique features the tool covers perfectly the requirements of embedded real-time and low-power application developers. With its C/C++/Python/C# and Swift language generators is also a perfect tool for developers of server or desktop applications. A Payback is usually already given within a few hours.

How does it work?

Use your favorite modeling tool and generate code from it with an easy-to-use command line tool. Automatic model checks warn from design flaws. Configure the generation process according to your needs. Simulate your model. Generate trace code automatically if needed. All major state diagram features like hierarchical states, regions, history, sub-machines … are supported.

Key Features

  • Generated code has production-quality. It is based on nested switch/case and if/then/else statements. It is easy to read and understand. There will be no problems when using static code analyzers.
  • Can be used with any 8-, 16- or 32-bit CPUs, with or without OS/RTOS. There is no run-time environment needed.
  • Fits well in different system designs. The code-generator does not dictate how you design your system. Therefore it is no problem to use the generated code in the context of a real-time operating system or within an interrupt service routine or in a foreground / background system.
  • No gap between design and code
  • Use the UML tool of your choice:
    • Cadifra UML Editor
    • UModel
    • Magic Draw
    • Enterprise Architect
    • SSC (built in editor)
    • Metamill

  • ArgoUML
  • astah* / astah SysML
  • Visual Paradigm
  • Modelio
  • Use the code generator only for those parts of your software that benefit from state machine modeling and code generation. Use your existing development environment for all the other code. The code-generator does not dictate an “all or nothing” approach as many other commercial tools.
  • Automatic robustness tests, test-case generation, tracing and simulation
  • Extensive manual with getting started section

How to get started?

Download the demo version and install it on you computer. Scan the manual starting with the the “Getting Started” section to get a basic understanding of what the tool can do for you. There is also a basic introduction into state-machines in case you need a refresh.

Then you have basically two options.

  • Run the examples on your PC. The example folder contains examples for all supported modelling tools and various languages (C, C++, …). The examples realizes a microwave oven and can be executed and tested. Play with the model and enhance it. Regenerate the code and learn from the warning and error messages.
  • Run examples on a Micro-Controller e.g. a MSP430 evaluation board using Energia. An example with all details is available on github.

What customers say

“Sinelabore has helped me implement the behavior of a complex, asynchronous system. All the UML 2 elements I needed are available. I like that I don’t have to draw the state machine, then separately implement it and keep these two synchronized; this saves me time and reduces the potential of bugs. The error checking to make sure the state machine is valid is also useful. —- Daniel Bedrenko / Software Developer @ BPS…tec GmbH”

“Thank you again for providing such great tool!”

“We like Your Tool, infact we will give intro for another local company next week.”

Using State-Machines in (Low-Power) Embedded Systems

There are different ways how to integrate state machines in a specific system design. Some design principles are more applicable for developers of deeply embedded systems. Others more relevant for developers having not so tight resource constraints.

Using state machines in a main-loop

In this design an endless loop — typically the main function — calls one or more state machines after each other. Using state machines in a main-loop It is still one of the most common ways of designing small embedded systems. The event information processed from the state machines might come from global or local variables fed from other code or IRQ handlers. The benefits of this design are no need for a runtime framework and only little RAM requirements.

The consequences are:

  • All housekeeping code has to be provided by the designer
  • Main loop must be fast enough for the overall required response time
  • In case of extensions the timing must be carefully rechecked again


void main(void){

Using state machines in a main loop with event queue

This design is like the one presented above. But the state machine receives its events from an event queue. The queue is filled from timer events, other state machines (cooperating machines) or interrupt handlers. Using state machines in a main loop with event queue Benefits:

  • Events are not lost (queuing)
  • Event order is preserved
  • Decoupling of event processing from event generation.


  • A minimal runtime framework is required: Timers and Queues
  • Main loop must be fast enough for the overall required response time

A minimal runtime framework for C is available here:

It offers timers and queues. The intended usage is as follows:

  • Each state machine has an own event queue
  • Eventually a state machine requires one or more timers (single shot or cyclically).
  • A state machine can create as many timers as needed. When creating a timer the event queue of the state machine and the timeout event has to be provided. For different timers it makes sense to provide different timeout events.
  • To make the timer work, a tick counter variable has to be incremented cyclically from a timer interrupt (e.g., every 10 ms). The tick frequency should be selected based on the minimal required resolution of the timeout times.
  • A tick() function must be called in the main loop to check if any timer has expired. In case a timeout has happened the provided event is stored in the event queue of the state machine.
  • The main loop has to check if events are stored for a state machine in its queue. If there are new events they are pulled from the queue and the state machine is called with the event.

Example code with two state machines shows the general principle:

// tick irq
void tick(void){
void main(void){
  // create two queues for two state machines and init the timer subsystem
  fifoInit(&fifo2VendingMachine, fifo2VendingMachineRawMem, 8);
  fifoInit(&fifo2ProductStoreMachine, fifo2ProductStoreMachineRawMem, 8);
  while (1) {
    uint8_t evt;
    // Check if there are new events for the state machine. If yes,
    // call state machine with event.
    bool fifoEmpty = fifoIsEmpty(&fifo2VendingMachine);
    if (!fifoEmpty) {
      fifoGet(&fifo2VendingMachine, &evt);
      vending_machine(&vendingMachine, evt);
    fifoEmpty = fifoIsEmpty(&fifo2ProductStoreMachine);
    if (!fifoEmpty) {
      fifoGet(&fifo2ProductStoreMachine, &evt);
      product_store_sm(&productStoreMachine, evt);
   // any new timeouts?

As indicated in the figure above also other state machines or interrupt handlers might push events to the queue of a state machine. An example how to do this is shown below.

// add event evErr to a state machine queue.
void ISR_Btn1() {
  fifoPut(&fifo2VendingMachine, evErr);

Using state machines in a main loop with event queue, optimized for low power consumption

In low power system designs a key design goal is to keep the processor as long as possible in low power mode and only wake it up if something needs to be processed. The design is very similar to the one described above. The main difference is that the main loop runs not all time but only in case an event has happened. The timer service for the small runtime framework is handled in the timer interrupt.

A skeleton for the MSP430 looks as follows:

void main(void){
  // init system
  while(1) {
    // check event queues and run the state machine as shown above
     __bis_SR_register(LPM3_bits + GIE);  // Enter low power mode once
     __no_operation();                    // no more events to process
// Timer A0 interrupt service routine. If the timer 
// function tick() returns true there
// is a timeout and we wakeup the main loop.
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void)
  bool retVal=false;
  P1OUT |= BIT0; // toggle for debugging
  retVal = tick();
    // at least one timeout timer fired.
    // wake up main loop
  P1OUT &= ~BIT0; // toggle for debugging
  // no more events must be processed

Using state machines in interrupts

Sometimes state dependent interrupt handling is required. Then it is useful to embed the state machine directly into the interrupt handler to save every us. Typical usage might be the pre-processing of characters received by a serial interface. Or state dependent filtering of an analog signal before further processing takes place. Using state machines in interrupts Using state machines in an interrupt handler can be useful in any system design.

For code generation some considerations are necessary. Usually it is necessary to decorate interrupt handlers with compiler specific keywords or vector information , etc. Furthermore interrupt service handlers have no parameters and no return value. To meet these requirements the Sinelabore code generator offers the parameters StateMachineFunctionPrefixHeader, StateMachineFunctionPrefixCFile and HsmFunctionWithInstanceParameters.

The example below shows an interrupt service routine with the compiler specific extensions as required by mspgcc.

// generated state machine code for an irq
interrupt (INTERRUPT_VECTOR) IntServiceRoutine(void)
   /* generated statemachine code goes here */

To generate this code, set the key/value pairs in your configuration file the following way:

StateMachineFunctionPrefixCFile=interrupt (INTERRUPT_VECTOR)

If the prefix of the interrupt service routine requires to span more than one line the line break ’\n’ character can be inserted as shown below:

StateMachineFunctionPrefixCFile=#pragma vector=UART0TX_VECTOR\n__interrupt void

Prefixes for the header and the C file can be specified separately.

Using state machines with a real-time operating system

In this design each state machine usually runs in the context of an own task. The principle design is shown in the following figure.

Using state machines with a real-time operating system

Each task executes a state machine (often called active object) in an endless while loop. The tasks wait for new events to be processed from the state machine. In case no event is present the task is set in idle mode from the RTOS. In case one or more new events are available the RTOS wakes up the task. The used RTOS mechanism for event signaling can be different. But often a message queue is used. Events might be stored in the event queue from various sources. E.g. from within another task or from inside an interrupt service routine. This design can be realized with every real-time operating system. Only the event transport mechanisms might differ.


  • Efficient and well tested runtime environment provided from the real-time operating system
  • Prioritization of tasks, scheduling available
  • State machine processing times decoupled from each other.


  • Need of a real-time operating system (complexity, ram usage, cost …)

The evaluation version shows an RTOS example in “other_examples/rtems_rtos”. A microwave oven state machine is embedded into the RTEMS real-time operating system. To compile the example you have to install a full RTEMS build environment. The example was created for the PC386 target.

// rtems specific task body
rtems_task oven_task(rtems_task_argument unused)
  for ( ; ; ) {
    // returns if one event was processed
// generated state machine code
extern rtems_id Queue_id;
uint8_t msg=NO_MSG;
size_t received;
rtems_status_code status;
void   oven(OVEN_INSTANCEDATA_T *instanceVar) {
  OVEN_EV_CONSUMED_FLAG_T evConsumed = 0U;
  /*execute entry code of default state once to init machine */
  if (instanceVar->superEntry == 1U) {
    instanceVar->superEntry = 0U;
  /* action code */
  /* wait for message */
  status = rtems_message_queue_receive(
             (void *) &msg,
  if ( status != RTEMS_SUCCESSFUL )
    switch (instanceVar->stateVar) {
      // generated state handling code}

Here is a similar example for the embOS RTOS available from Segger.

// state machine instance
// Task and queue objects.
static OS_STACKPTR int Stack_TASK_1[128];   /* Task stacks */
static OS_TASK         TCB_TASK_1;         /* Task-control-blocks */
static OS_Q            MyQueue;
static char            MyQBuffer[100];
char txbuf[32] ;
// Routine called from the embOS RTOS to signal 
// a timeout. A timeout event is sent to the state
// machine. Multiple timer callback functions might be created if
// several timers are needed at the same time. Each one then fires an own
// event. E.g. ev50ms or ev100ms
static void MyTimerCallback(void) {
    uint8_t msg=evtTimeout;
    OS_Q_Put(&MyQueue, &msg, 1);
// Task blocked until a new event is present. The new event is 
// then sent to the state machine.
static void TaskRunningStateMachine(void) {
    char* pData;
    while (1) {
        // waiting for new event
        volatile int Len = OS_Q_GetPtr(&MyQueue, (void**)&pData);
        volatile char msg = *pData;
        sm(&instanceVar, (SM_EVENT_T)msg); // call generated state machine with event

Latest News

15.02.2020 | New version 4.1

This new version provides a backend for Lua. It is the first state machine code generator from UML state diagrams/machines to Lua. Lua is a lightweight, embeddable scripting language. It follows the approach described by Roberto Ierusalimschy in his book. More information is available here.

17.6.2019 | New version 3.7.4

This is a bug-fix version and recommended for all users. For users of the Cadifra tool connection points were added to keep oversight in complex diagrams more easy. Connection points are a well known concept in circuit diagram drawing tools. More details can be found in the sinelabore manual (Cadifra part).

2.5.2019 | New example for PIC users

This tutorial explains the use of state machines with the PIC16F18446 Curiosity Nano board. Go on reading ...

1.1.2019 | Info for Java 11 users

So that Java found the codegenerator and other jar files one suggested option was so far to to use the -Djava.ext.dirs command line option. With the latest version of Java this option seems not to exist anymore. In future the classpath must be used e.g. java -cp “sinelaboreRT3.7.3/bin/*” codegen.Main … Please note that using -cp in combination with jar files is not possible. We will change the examples and documentation soon.

9.9.2018 | New version 3.7.3

General improvements of the built-in editor. Better usage of wide screen displays - properties are now located on the right side. Bug fixes in undo/redo code.

29.12.2017 | Sparx new EA Version

Tests of new EA version 13 were successful. If you find any flaws using the codegen with the new version send a bug report please.

5.11.2017 | New version 3.7.2

This is a version with minor bug fixes recommended especially for C++ users.

20.9.2017 | QuickStart tutorial on how to use the code generator with Energia on GitHub

Energia is based on the Arduino IDE and is a great IDE for processors form Texas Instruments. The new example on GitHub shows the integration of code generated from the sinelabore code generator into the Energia IDE. What does the demo do: The flash frequency of the green LED on the MSP430FR5969 LaunchPad can be controlled. A minimal timer and queueing lib is used as basis to be prepared for much more challenging tasks. You will see the benefit of state machine modeling over direct coding. Take a look at the state diagrams and the generated code here! Or download the example and try it out yourself.

9.4.2017 | New version 3.7.1 with some small improvements

Recommended for all C# users and those who use the built in editor/simulator.

6.11.2016 | Code Generator Features for High-Availability and Safety Systems

There is a new article in the “Designers Toolbox” explaining the special features for for High-Availability and Safety Systems offered from the C-backend.

16.10.2016 | Generate Python Code from State Diagrams

With version 3.7 is is now possible to generate Python code. The state machine code is generated as a Python class. All relevant state machine features are available. Look into the manual for details. The fully working microwave oven code is available in the examples folder. It contains a TKinter GUI wich makes simulation and testing of the generated state machine even simpler.

24.6.2016 | Windows Executable

To make the entry barrier lower for users new to Java there is a windows exe file now. You can directly start with the code generator without setting any class path etc. There are two examples in the examples folder (ending with win32) for your reference. This feature is still experimental. The exe file is available with the latest download. Any feedback is welcome!

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
start.txt · Last modified: 2020/02/22 20:00 by pmueller