この投稿では、コンパクトな状態遷移プログラムについて紹介致します。
組込み製品は、機能安全などの規格対応で異常検知およびフェイルセーフの機能が増加しています。製品によっては、100を超える異常検知があり、その多くの異常検知情報(状態遷移条件:イベント)で状態遷移プログラムが大きくなっている場合があります。そこでコンパクトな状態遷移プログラムを紹介いたします。
特徴
- イベントを状態(ステート)変数のビットフィールに配置
- イベントからステート判定せずにステート変数の値からステートのアプリケーションをコール
- 仕様に合わせたラベル名に置き換えるので、仕様との一致性確保
他にも色んなやり方はあると思いますが、ご参考になればうれしいです。
typedef struct{
union{
unsigned char state;
struct{
unsigned char b7 : 1;
unsigned char b6 : 1;
unsigned char b5 : 1;
unsigned char b4 : 1;
unsigned char b3 : 1;
unsigned char b2 : 1;
unsigned char b1 : 1;
unsigned char b0 : 1;
}event;
};
}state_event;
static state_event STATE[3] = { { .state = 0x80 }, { .state = 0U }, { .state = 0U } };
// Re Lable name
#define State1 STATE[0].state
#define State2 STATE[1].state
#define State3 STATE[2].state
#define E1 State2.event.b7
#define E2 State2.event.b6
#define E3 State1.event.b7
#define E4 State3.event.b7
#define E5 State3.event.b6
#define E6 State3.event.b5
#define E7 State3.event.b4
#define E8 State1.event.b6
void Func_State1( void );
void Func_State2( void );
void Func_State3( void );
void Func_state_flow( void )
{
if( State1 !=0 ){
Func_State1();
}else if( State2 != 0 ){
Func_State2();
}else if( State3 != 0 ){
Func_State3();
}else{
// State flow Error
}
}
void Func_State1( void )
{
// State1 Application
// E1, E2, E6, E7 Judgment
}
void Func_State2( void )
{
// State2 Application
// E3, E4, E5 Judgment
}
void Func_State3( void )
{
// State3 Application
// E8 Judgment
}