コンパクトな状態遷移プログラム

この投稿では、コンパクトな状態遷移プログラムについて紹介致します。

組込み製品は、機能安全などの規格対応で異常検知およびフェイルセーフの機能が増加しています。製品によっては、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
}
OSS-ECAL Japanese
error: コンテンツは保護されている