Bedingte Verzweigungen
Bedingungen sind wichtige Konstrukte einer Zustandsmaschine, um damit den logischen Kontrollfluss zu spezifizieren. In diesem Beispiel werden bedingte Verzweigungen näher betrachtet.
Zustandsdiagramm
Modell
Beschreibung
Im Beispiel der bedingten Transitionen wurden bereits getriggerte Transitionen beschrieben, die nur dann durchlaufen werden, wenn bestimmte Bedingungen erfüllt sind.
Eine bedingte Verzweigung (Choice) sieht auf den ersten Blick sehr ähnlich aus, unterscheidet sich aber doch in entscheidenden Details.
Bei bedingten Transitionen wird beim Eintreffen eines passenden Events zuerst die Bedingung geprüft und nur dann der Zustand verlassen, wenn die Bedingung tatsächlich erfüllt ist.
Im Gegensatz dazu wird bei bedingten Verzweigungen beim Eintreffen eines passenden Events der Zustand sofort verlassen und dann erst die Bedingung zur Verzweigung geprüft.
Zustandsmaschinen müssen nach jeder Verarbeitung eines Events einen stabilen Zustand angenommen haben. Ohne Else-Pfad würde die Zustandsmaschine in unserem Beispiel in dem Choice Knoten „steckenbleiben“, falls die Bedingung isTempTooHigh()
nicht erfüllt wäre. Aus diesem Grund ist bei jeder bedingten Verzweigungen grundsätzlich immer ein Else-Pfad zwingend erforderlich.
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_ALPHA,
DemoSm_States_HOT,
DemoSm_States_COLD
};
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 void DemoSm_enterHot(void);
/*===========================================================================================================================================================*/
static void DemoSm_executeHot( DemoSm_EvObj* const evObj );
/*===========================================================================================================================================================*/
static void DemoSm_enterCold(void);
/*===========================================================================================================================================================*/
static void DemoSm_executeCold( DemoSm_EvObj* const evObj );
/*===========================================================================================================================================================*/
static bool DemoSm_isTempTooHigh(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;
case DemoSm_States_HOT:
DemoSm_executeHot( evObj );
break;
case DemoSm_States_COLD:
DemoSm_executeCold( 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();
if ( DemoSm_isTempTooHigh() )
{
DemoSm_enterHot();
}
else
{
DemoSm_enterCold();
}
break;
default:
break;
}
}
}
else
{
// no untriggered transitions available
}
}
/*===========================================================================================================================================================*/
static void DemoSm_leaveAlpha(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_IN_TRANSITION );
}
/*===========================================================================================================================================================*/
static void DemoSm_enterHot(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_HOT );
}
/*===========================================================================================================================================================*/
static void DemoSm_executeHot( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
if ( evObj != NULL )
{
// no triggered transitions available
}
else
{
// no untriggered transitions available
}
}
/*===========================================================================================================================================================*/
static void DemoSm_enterCold(void)
/*===========================================================================================================================================================*/
{
DemoSm_setState( DemoSm_States_COLD );
}
/*===========================================================================================================================================================*/
static void DemoSm_executeCold( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
if ( evObj != NULL )
{
// no triggered transitions available
}
else
{
// no untriggered transitions available
}
}
/*===========================================================================================================================================================*/
static bool DemoSm_isTempTooHigh(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
}