상태 기 구현 의 세 가지 방법 - C 언어

10841 단어 clinux
1. 참고:http://www.eefocus.com/tagner/blog/15-06/313286_07eac.html
2. 전재:http://kb.cnblogs.com/page/528972/
유한 상태 기 FSM 사상 은 하드웨어 제어 회로 디자인 에 광범 위 하 게 응용 되 고 소프트웨어 에서 자주 사용 하 는 처리 방법 (소프트웨어 상 FMM 유한 정보 기 라 고 함) 이다.이 는 복잡 한 통제 논 리 를 유한 한 안정 상태 로 분해 하여 모든 상태 에서 사건 을 판단 하고 연속 적 으로 분 산 된 디지털 처리 로 처리 하여 컴퓨터 의 작업 특징 에 부합된다.또한 유한 상태 기 는 유한 한 상 태 를 가지 기 때문에 실제 공사 에서 실현 할 수 있다.그러나 이것 은 유한 한 처리 만 할 수 있다 는 것 을 의미 하지 않 는 다. 반면에 유한 상태 기 는 폐쇄 시스템 이 고 유한 한 상태 로 무한 한 사 무 를 처리 할 수 있다.
유한 상태 기의 작업 원 리 는 그림 1 에서 보 듯 이 사건 (이벤트) 이 발생 한 후 현재 상태 (cur state) 에 따라 ,실행 할 동작 (action) 을 결정 하고 다음 상태 번호 (nxt state) 를 설정 합 니 다.


그림 2 는 상태 기 인 스 턴 스 의 상태 전이 그림 으로 그 의 미 는 다음 과 같다.
s0 상태 에서 e0 이벤트 가 발생 하면 a0 동작 을 실행 하고 상태 가 변 하지 않 습 니 다
e1 이벤트 가 발생 하면 a1 동작 을 실행 하고 상 태 를 s1 상태 로 옮 깁 니 다
e2 이벤트 가 발생 하면 a2 동작 을 실행 하고 상 태 를 s2 상태 로 옮 깁 니 다
s1 상태 에서 e2 사건 이 발생 하면 a2 동작 을 실행 하고 상 태 를 s2 상태 로 옮 깁 니 다
s2 상태 에서 e0 이벤트 가 발생 하면 a0 동작 을 실행 하고 상 태 를 s0 상태 로 옮 깁 니 다
유한 상태 기 는 상태 전이 도 를 사용 할 수 있 을 뿐만 아니 라 2 차원 표 로 도 대표 할 수 있다.일반적으로 현재 상태 번 호 를 가로 줄 에 쓰 고 이 벤트 를 세로 줄 에 쓴다. 표 1 과 같다.그 중에서 '-' 는 빈 (동작 을 실행 하지 않 고 상태 이동 도 하지 않 음) 을 나타 내 고 'an / sn' 은 동작 an 을 실행 하 는 동시에 다음 상 태 를 sn 으로 설정 합 니 다.표 1 과 그림 2 가 나타 내 는 의 미 는 완전히 같다.
관찰 표 1 에서 알 수 있 듯 이 상태 기 는 두 가지 방법 으로 실현 할 수 있다. 세로 쓰기 (상태 에서 사건 을 판단) 와 가로 쓰기 (사건 에서 상 태 를 판단) 이다.이 두 가지 실현 은 본질 적 으로 완전히 같은 효 과 를 가지 지만 실제 조작 에서 효 과 는 전혀 다르다.
세로 쓰기 (상태 에서 이벤트 판단) C 코드 세 션:
cur_state = nxt_state;   
switch(cur_state) //          
{            
    case s0: // s0     
        if(e0_event) //    e0  ,     a0  ,       ;
        {   
        //  a0  ;               
        //nxt_state = s0;  //        ,        ,       。
        } 
        else if(e1_event) //    e1  ,     a1  ,       s1 ;
        {   
            //  a1  ;
            nxt_state = s1;
        }           
        else if(e2_event) //    e2  ,     a2  ,       s2 ;
        {  
            //  a2  ;
            nxt_state = s2;
        }
        else
        {
            break;    
        }   

    case s1: // s1  
        if(e2_event) //    e2  ,     a2  ,       s2 ; 
        {                
            //  a2  ;
         nxt_state = s2;
        }           
        else
        {
      break;
        }

    case s2: // s2  
        if(e0_event)  //    e0  ,     a0  ,       s0 ;
        {
            //  a0  ;               
            nxt_state = s0;
        }
}

가로로 쓰기 (이벤트 에서 상태 판단) C 코드 세 션:
//e0     ,     
void e0_event_function(int * nxt_state)
{   
    int cur_state;   
    cur_state = *nxt_state;   
    switch(cur_state)
    {       
        case s0: //   1, e0     ,s1      
        case s2: //  a0  ;           
        *nxt_state = s0;
    }
}

//e1     ,     
void e1_event_function(int * nxt_state)
{   
    int cur_state;   
    cur_state = *nxt_state;   
    switch(cur_state)
    {       
        case s0: //   1, e1     ,s1 s2              
            //  a1  ;           
            *nxt_state = s1;
    }
}

//e2     ,     
void e2_event_function(int * nxt_state)
{   
    int cur_state;   
    cur_state = *nxt_state;   
    switch(cur_state)
    {       
        case s0: //   1, e2     ,s2          
        case s1:           
            //  a2  ;           
            *nxt_state = s2; 
    }
}

위 에 가로로 두 가지 쓰기 코드 세 션 을 세 워 서 실현 하 는 기능 은 완전히 같 지만 가로로 쓰 는 효 과 는 세로 로 쓰 는 효과 보다 현저히 좋다.이 유 는 다음 과 같다.
1. 세로 쓰기 에는 우선 순위 정렬 (사실 각 사건 은 같은 우선 순위) 이 포함 되 어 있 고 앞 에 있 는 사건 판단 은 의심 할 여지없이 뒤에 있 는 사건 판단 보다 우선 합 니 다.이러한 if / else if 쓰기 상의 제한 은 사건 간 의 원래 관 계 를 파괴 할 것 이다.가로 쓰 기 는 문제 가 없다.
2. 모든 상태 에 있 을 때 사건 의 수량 이 일치 하지 않 고 사건 이 발생 하 는 시간 이 무 작위 이기 때문에 미리 확정 할 수 없 기 때문에 세로 쓰기 가 순서 조회 방식 으로 전락 하고 구조 적 인 결함 으로 인해 많은 시간 이 낭비 된다.가로 쓰기 에 있어 서 특정한 시간 에 상 태 는 유일 하 게 확 정 된 것 입 니 다. 사건 에서 상 태 를 찾 으 려 면 switch 문 구 를 사용 하면 해당 하 는 상 태 를 한 걸음 에 찾 을 수 있 고 지연 시간 은 미리 정확하게 계산 할 수 있 습 니 다.그리고 사건 이 발생 할 때 사건 함 수 를 호출 하여 함수 에서 유일 하 게 확 정 된 상 태 를 찾 고 그 집행 동작 과 상태 에 따라 이동 하 는 사고방식 이 뚜렷 하고 간결 하 며 효율 이 높 고 미감 이 풍부 하 다.
한 마디 로 하면 저 는 개인 적 으로 소프트웨어 에 상태 기 를 쓰 고 가로로 쓰 는 방법 이 적당 하 다 고 생각 합 니 다.
세로 로 쓰 는 방법 도 완전히 사용 할 수 없 는 것 이 아니다. 일부 작은 항목 에서 논리 가 복잡 하지 않 고 기능 이 간소화 되 며 메모리 소 모 를 절약 하기 위해 세로 로 쓰 는 방법 도 적당 한 선택 이 라 고 할 수 있다.
FPGA 류 하드웨어 디자인 에서 상 태 를 중심 으로 제어 회로 상태 기 (세로 쓰기) 를 실현 하 는 것 이 유일한 선택 인 것 같다. 하드웨어 가 이벤트 구동 (가로 쓰기) 에 의존 할 수 없 기 때문이다.그러나 FPGA 에는 전역 시계 가 있 는데 상승 할 때마다 상태 전환 을 해서 세로 로 쓰 는 효율 이 낮 지 않다.하드웨어 에 세로 로 써 도 IF / ELSIF 와 같은 검색 어 (VHDL 로 개발) 를 사용 해 야 하지만 하드웨어 에 비 친 것 은 조합 논리 이 고 조 회 는 도 어 급 지연 (ns 급) 만 일 으 킬 뿐 하드웨어 는 진정 으로 병행 작업 을 하기 때문에 세로 로 써 하드웨어 에 부정적인 영향 을 주지 않 는 다.따라서 하드웨어 디자인 에서 세로 로 쓰 는 방식 을 사용 하 는 것 은 필연 적 인 선택 이 된다.하드웨어 를 하 는 많은 엔지니어 들 이 소프트웨어 상태 기 를 디자인 할 때 의식 적 으로 세로 쓰기 방식 만 사용 하 는 이유 이기 도 하 다.
TCP 와 PPP 프레임 워 크 프로 토 콜 에는 모두 유한 상태 기 를 사 용 했 는데 이런 소프트웨어 상태 기 는 가로로 쓰 는 방식 으로 실현 하 는 것 이 가장 좋다.특정한 TCP 프로 토 콜 을 예 로 들 면 그림 3 을 보면 세 가지 유형의 사건 이 있다. 상부 에서 내 린 명령 사건 이다.하층부 에 도착 한 표지 와 데이터 의 패키지 이벤트;시간 초과 타이머 시간 초과 이벤트.
   状态机的两种写法 - loving you - 天道酬勤
그림 3 에서 알 수 있 듯 이 이 TCP 프로 토 콜 스 택 은 가로 쓰기 방식 으로 이 루어 집 니 다. 3 가지 이벤트 처리 함수, 상부 명령 처리 함수 (예 를 들 어 tcp close) 가 있 습 니 다.시간 초과 이벤트 처리 함수 (tmr slow);하위 패키지 이벤트 처리 함수 (tcp process).특히 하 도 급 사건 함수 에서 각 상태 에서 RST / SYN / FIN / ACK / DATA 등 표지 (이 표지 들 은 사건 과 유사) 를 판단 하여 세로 로 쓰 는 방식 처럼 보이 지만 사실은 가방 머리 와 데 이 터 를 하나의 전체 로 본다 면 RST / SYN / FIN / ACK / DATA 등 표 지 는 독립 된 사건 으로 볼 필요 가 없 이 같은 하 도 급 사건 의 세부 사항 에 속한다. 이렇게 하면상태 에서 사건 을 찾 는 것 이 아니 라 전체적으로 볼 때 하 도 급 사건 에서 상 태 를 찾 는 것 이 라 고 생각 하지 않 습 니 다 (가로 쓰기).
PPP 에 서 는 가로 쓰 기 를 곳곳에서 볼 수 있 으 니 시간 이 있 으 면 다시 자세하게 말 하 자.저 는 개인 적 으로 PPP 프레임 워 크 프로 토 콜 을 실현 하기 전에 가로 와 세로 두 가지 쓰 기 를 알 아야 하고 가로 쓰 기 를 사용 해 야 PPP 를 완벽 하 게 실현 할 수 있다 고 생각 합 니 다.

좋은 웹페이지 즐겨찾기