Einfachste Zustandsmaschine
Minimale Zustandsmaschine bestehend aus einem Zustand, initialer Transition und getriggerter Transition.
Zustandsdiagramm

Modell

Beschreibung
Eine Zustandsmaschine (Statemachine) wird immer als Bestandteil einer Unit generiert. Unter einer Unit versteht man eine zusammengehörende Einheit von einer *.h und einer *.c Datei. Alle Sourcecode Konstrukte einer Unit (wie z. B. Funktionen, Typen, Variablen, …) werden mit einem Pseudo-Namespace versehen, der sich aus dem Namen der Unit ableitet.
In diesem Beispiel lautet der Unitname „DemoSm“. Im generierten Code beginnen daher alle Identifier mit dem Pseudo-Namespace DemoSm_
.
Initial Transition
Jede Zustandsmaschine muss vor der Verwendung einmalig initialisiert werden. Hierfür wird eine init()
Funktion generiert. Beim Ausführen der init()
Funktion wird die initiale Transition durchlaufen. In diesem Beispiel befindet sich die Zustandsmaschine danach im Zustand „Alpha“.
Trigger Events
Die Ausführung einer Zustandsmaschine basiert auf der Einspeisung von Events, die dazu dienen, Zustandsübergänge auszulösen.
Events werden im generierten Code als Aufzählung abgebildet und für die Einspeisung von Events wird jeweils eine Funktion executeWith( event )
Funktion generiert.
Getriggerte Transitionen
Die Zustände einer Zustandsmaschine werden über Transitionen verbunden, deren Durchlaufen durch unterschiedliche Mechanismen ausgelöst werden kann.
Getriggerte Transitionen werden durch das Einspeisen von einem passenden Trigger Event ausgelöst. Im Code erfolgt dies durch das Ausführen der executeWith( event )
Funktion.
Dabei wird der Ausgangszustand verlassen, die Transition durchlaufen und dann der neue Zielzustand betreten.
In unserem Beispiel wird durch das Einspeisen des „TICK“ Events der Zustand „Alpha“ verlassen und am Ende der Transition wieder neu betreten.
Generierte Datei: demo_sm.h
#ifndef DEMO_SM_H
#define DEMO_SM_H
/*###########################################################################################################################################################*/
// Type declarations
/*###########################################################################################################################################################*/
typedef enum DemoSm_StatesTag DemoSm_States;
enum DemoSm_StatesTag
{
DemoSm_States_INVALID,
DemoSm_States_IN_TRANSITION,
DemoSm_States_ALPHA
};
typedef enum DemoSm_EventTag DemoSm_Event;
enum DemoSm_EventTag
{
DemoSm_Event_INVALID,
DemoSm_Event_TICK
};
/*###########################################################################################################################################################*/
// Function declarations
/*###########################################################################################################################################################*/
/*===========================================================================================================================================================*/
extern void DemoSm_init(void);
/*===========================================================================================================================================================*/
extern void DemoSm_executeWithDemoSmEvent( const DemoSm_Event demoSmEvent );
/*===========================================================================================================================================================*/
extern void DemoSm_raiseFatalError(void);
#endif // DEMO_SM_H
Generierte Datei: demo_sm.c
/*###########################################################################################################################################################*/
// Includes
/*###########################################################################################################################################################*/
#include "demo_sm.h"
#include <stdbool.h>
#include <stddef.h>
/*###########################################################################################################################################################*/
// Type declarations
/*###########################################################################################################################################################*/
typedef enum DemoSm_EvTypeTag DemoSm_EvType;
enum DemoSm_EvTypeTag
{
DemoSm_EvType_DEMO_SM_EVENT
};
typedef struct DemoSm_EvObjTag DemoSm_EvObj;
struct DemoSm_EvObjTag
{
DemoSm_EvType evType;
DemoSm_Event demoSmEvent;
};
/*###########################################################################################################################################################*/
// Variables
/*###########################################################################################################################################################*/
static DemoSm_States DemoSm_currentState = DemoSm_States_INVALID;
static bool DemoSm_executionInProgress = false;
/*###########################################################################################################################################################*/
// Internal function declarations
/*###########################################################################################################################################################*/
/*===========================================================================================================================================================*/
static void DemoSm_setState( const DemoSm_States newState );
/*===========================================================================================================================================================*/
static void DemoSm_execute( DemoSm_EvObj* const evObj );
/*===========================================================================================================================================================*/
static void DemoSm_executeStatemachine( DemoSm_EvObj* const evObj );
/*===========================================================================================================================================================*/
static void DemoSm_enterAlpha(void);
/*===========================================================================================================================================================*/
static void DemoSm_executeAlpha( DemoSm_EvObj* const evObj );
/*===========================================================================================================================================================*/
static void DemoSm_leaveAlpha(void);
/*###########################################################################################################################################################*/
// Internal function implementations
/*###########################################################################################################################################################*/
/*===========================================================================================================================================================*/
static void DemoSm_setState( const DemoSm_States newState )
/*===========================================================================================================================================================*/
{
DemoSm_currentState = newState;
}
/*===========================================================================================================================================================*/
static void DemoSm_execute( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
if ( !DemoSm_executionInProgress )
{
DemoSm_executeStatemachine( evObj );
}
else
{
// recursion error
DemoSm_raiseFatalError();
}
}
/*===========================================================================================================================================================*/
static void DemoSm_executeStatemachine( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
DemoSm_executionInProgress = true;
switch ( DemoSm_currentState )
{
case DemoSm_States_ALPHA:
DemoSm_executeAlpha( evObj );
break;
default:
DemoSm_raiseFatalError();
break;
}
DemoSm_executionInProgress = false;
}
/*===========================================================================================================================================================*/
static void DemoSm_enterAlpha(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_ALPHA );
}
/*===========================================================================================================================================================*/
static void DemoSm_executeAlpha( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
if ( evObj != NULL )
{
if ( evObj->evType == DemoSm_EvType_DEMO_SM_EVENT )
{
switch ( evObj->demoSmEvent )
{
case DemoSm_Event_TICK:
DemoSm_leaveAlpha();
DemoSm_enterAlpha();
break;
default:
break;
}
}
}
else
{
// no untriggered transitions available
}
}
/*===========================================================================================================================================================*/
static void DemoSm_leaveAlpha(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_IN_TRANSITION );
}
/*###########################################################################################################################################################*/
// External function implementations
/*###########################################################################################################################################################*/
/*===========================================================================================================================================================*/
extern void DemoSm_init(void)
/*===========================================================================================================================================================*/
{
DemoSm_enterAlpha();
}
/*===========================================================================================================================================================*/
extern void DemoSm_executeWithDemoSmEvent( const DemoSm_Event demoSmEvent )
/*===========================================================================================================================================================*/
{
DemoSm_EvObj evObj;
evObj.evType = DemoSm_EvType_DEMO_SM_EVENT;
evObj.demoSmEvent = demoSmEvent;
DemoSm_execute( &evObj );
}
/*===========================================================================================================================================================*/
extern void DemoSm_raiseFatalError(void)
/*===========================================================================================================================================================*/
{
// add your action implementation code here
}