Ungetriggerte Transitionen
Bedingungen sind wichtige Konstrukte einer Zustandsmaschine, um damit den logischen Kontrollfluss zu spezifizieren. In diesem Beispiel werden bedingte Transitionen ohne Trigger näher betrachtet.
Zustandsdiagramm

Modell

Beschreibung
In Zustandsmaschinen wird das Durchlaufen von Transitionen im Regelfall durch das Einspeisen eines Trigger Events ausgelöst (siehe einfachste Zustandsmaschine). Es gibt jedoch auch die Möglichkeit, einen Zustand unter gewissen Umständen sofort nach dem Betreten wieder zu verlassen und eine weitere Transition zu durchlaufen.
In unserem Beispiel wird beim Betreten des Zustands „Off“ geprüft, ob die Bedingung autoPowerOn()
erfüllt ist und gegebenenfalls sofort weiter in den Zustand „On“ gewechselt. Falls autoPowerOn()
nicht erfüllt ist, bleibt die Zustandsmaschine im Zustand „Off“ und kann von dort erst wieder durch das Einspeisen eines SWITCH_ON
Events in den Zustand „On“ geführt werden.
Weitere Informationen zu Conditions und deren Generierung sind im Beispiel der bedingten Transitionen zu finden.
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_OFF,
DemoSm_States_ON
};
typedef enum DemoSm_EventTag DemoSm_Event;
enum DemoSm_EventTag
{
DemoSm_Event_INVALID,
DemoSm_Event_SWITCH_ON
};
/*###########################################################################################################################################################*/
// 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_enterOff(void);
/*===========================================================================================================================================================*/
static void DemoSm_executeOff( DemoSm_EvObj* const evObj );
/*===========================================================================================================================================================*/
static void DemoSm_leaveOff(void);
/*===========================================================================================================================================================*/
static void DemoSm_enterOn(void);
/*===========================================================================================================================================================*/
static void DemoSm_executeOn( DemoSm_EvObj* const evObj );
/*===========================================================================================================================================================*/
static bool DemoSm_autoPowerOn(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_OFF:
DemoSm_executeOff( evObj );
break;
case DemoSm_States_ON:
DemoSm_executeOn( evObj );
break;
default:
DemoSm_raiseFatalError();
break;
}
DemoSm_executionInProgress = false;
}
/*===========================================================================================================================================================*/
static void DemoSm_enterOff(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_OFF );
DemoSm_executeOff( NULL );
}
/*===========================================================================================================================================================*/
static void DemoSm_executeOff( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
if ( evObj != NULL )
{
if ( evObj->evType == DemoSm_EvType_DEMO_SM_EVENT )
{
switch ( evObj->demoSmEvent )
{
case DemoSm_Event_SWITCH_ON:
DemoSm_leaveOff();
DemoSm_enterOn();
break;
default:
break;
}
}
}
else
{
bool transitionTaken = false;
if ( !transitionTaken )
{
if ( DemoSm_autoPowerOn() )
{
DemoSm_leaveOff();
DemoSm_enterOn();
transitionTaken = true;
}
}
}
}
/*===========================================================================================================================================================*/
static void DemoSm_leaveOff(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_IN_TRANSITION );
}
/*===========================================================================================================================================================*/
static void DemoSm_enterOn(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_ON );
}
/*===========================================================================================================================================================*/
static void DemoSm_executeOn( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
if ( evObj != NULL )
{
// no triggered transitions available
}
else
{
// no untriggered transitions available
}
}
/*===========================================================================================================================================================*/
static bool DemoSm_autoPowerOn(void)
/*===========================================================================================================================================================*/
{
// add your action implementation code here
}
/*###########################################################################################################################################################*/
// External function implementations
/*###########################################################################################################################################################*/
/*===========================================================================================================================================================*/
extern void DemoSm_init(void)
/*===========================================================================================================================================================*/
{
DemoSm_enterOff();
}
/*===========================================================================================================================================================*/
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
}