Bedingte Transitionen
Bedingungen sind wichtige Konstrukte einer Zustandsmaschine, um damit den logischen Kontrollfluss zu spezifizieren. In diesem Beispiel werden bedingte getriggerte Transitionen näher betrachtet.
Zustandsdiagramm
Modell
Beschreibung
Im Beispiel der einfachsten Zustandsmaschine wurden bereits getriggerte Transitionen im Allgemeinen beschrieben.
An eine getriggerte Transition kann auch eine Bedingung (Condition) geknüpft werden, die beim Eintreten des Trigger Events geprüft wird und das Durchlaufen der Transition nur dann zulässt, wenn die Bedingung erfüllt ist.
Bedingungen werden als Funktionen ohne Implementierung generiert, welche einen bool
Rückgabewert liefern müssen. Es ist vorgesehen, dass deren Implementierung nachträglich manuell hinzugefügt wird.
Bei Bedingungen kann im Modell deren Sichtbarkeit durch die Eigenschaft Linkage festgelegt werden. Der Wert External führt zu „öffentlichen“ Funktionen mit Deklarationen in der *.h Datei. Der Wert Internal führt zu „privaten“ Funktionen mit Deklarationen in der *.c Datei.
Wie bereits im Beispiel der einfachsten Zustandsmaschine beschrieben, werden auch Aktionen als Bestandteil einer Unit generiert und erhalten daher auch deren Pseudo-Namespace, in diesem Fall DemoSm_
.
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);
/*===========================================================================================================================================================*/
static bool DemoSm_isAllowed(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:
if ( DemoSm_isAllowed() )
{
DemoSm_leaveAlpha();
DemoSm_enterAlpha();
}
break;
default:
break;
}
}
}
else
{
// no untriggered transitions available
}
}
/*===========================================================================================================================================================*/
static void DemoSm_leaveAlpha(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_IN_TRANSITION );
}
/*===========================================================================================================================================================*/
static bool DemoSm_isAllowed(void)
/*===========================================================================================================================================================*/
{
// add your action implementation code here
}
/*###########################################################################################################################################################*/
// 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
}