안녕하세요 ..C에서 함수 포인터를 사용하여 FSM을 구현하는 방법의 예가 필요합니다.FSM의 함수 포인터
답변
에 유한 상태 기계를 구현하는 방법에 대한 this simple example 참조 : 는 여기에 내가 state machine c "function pointer"
에 대한 인터넷 검색에 의해 발견 기존의 예입니다. 따라서 배열의 각 요소는 열거 형의 특정 이벤트에 대한 함수 포인터입니다. foo
이 이벤트로 초기화 된 함수 포인터의 배열이면 이벤트가 발생할 때 foo[event]()
을 호출하십시오.
함수 포인터를 먼저 호출하기 위해 코딩을 시도해보십시오. 다음으로 배열로 이동하여 더 많은 의문점이있는 경우 다시 돌아올 수 있습니다.
처음에는 기능 포인터 here에 대해 읽을 수 있습니다.
답변을 주셔서 감사합니다. – priya
다음은 ARDUINO에서 함수 포인터를 사용하는 데 대한 간단한 데모입니다. 이 예제에서는 동시성을 허용하지 않습니다. main() 내부에서 설정과 루프를 작성하면 정상 C로 완벽하게 전송 가능
각 상태는 void() 함수입니다. 각 상태 함수는 입력을 읽고 출력을 설정합니다. 이 작업이 완료되면 함수가 즉시 반환됩니다. 그것은 다시 직접 호출됩니다. 이 함수는 반환 직전에 leave 함수를 호출하여 상태 전이를 담당합니다. 각 상태 함수에는 시간 기록을위한 정적 long 변수가 있어야합니다.
글로벌 변수 상태는 설정 루틴의 초기 상태를 가리 키도록 설정됩니다. 여러 상태에서 계시를하고 싶었 기 때문에 2 가지 함수로 상태 천이를 구현했습니다 :
void enter (long * stateTime) 상태 함수를 입력 할 때 가장 먼저 호출해야합니다. 비활성 끝이 시간을 유지하는 경우 상태를 활성화합니다.
void leave (void (* next)(), long * statetime), 전역 상태 포인터를 변경하고 현재 상태를 비활성화합니다.
void (*state)();//function pointer for state machine
long prevMillis = 0;//timekeeper
const int LEDPIN = 13;
int counter1 = 0;
void enter(long *statetime){
if(*statetime==-1){//check for passive state
prevMillis = millis();//set timemark when entering state
}//if(statetime==0)
*statetime = millis()-prevMillis;//keep time
}//enter()
void leave(void (*next)(), long *statetime){
*statetime=-1;//set state to passive
state=next;//point to next state
}//leave()
void off500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>499){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off500ms()
void off2s(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>1999){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off2s()
void on500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, HIGH);
if(stateMillis >499){//time is up
if(++counter1==6){//number of blinks
leave(off2s, &stateMillis);
counter1=0;//reset counter
}else{//if(++counter1==6)
leave(off500ms, &stateMillis);
}//if(++counter1==6)
}//if(stateMills>499)
}//on500ms
void setup(){
pinMode(LEDPIN, OUTPUT);
state = on500ms;//set initial state
}/setup()
void loop(){
state();//start FSM
}//loop
주 트란 지션 코드는 배열 또는 스위치 케이스로 하나 활용 될 수있다. else 지시문에 따라 작성됩니다.
#include <stdio.h>
#include <stdlib.h>
int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);
enum state_codes lookup_transitions(enum state_codes, enum ret_codes);
/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};
enum ret_codes { ok, fail, repeat};
struct transition {
enum state_codes src_state;
enum ret_codes ret_code;
enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
{entry, ok, foo},
{entry, fail, end},
{foo, ok, bar},
{foo, fail, end},
{foo, repeat, foo},
{bar, ok, end},
{bar, fail, end},
{bar, repeat, foo}};
int main(int argc, char *argv[]) {
enum state_codes cur_state = entry;
enum ret_codes rc;
int (* state_fun)(void);
for (;;) {
state_fun = state[cur_state];
rc = state_fun();
if (end == cur_state)
break;
cur_state = lookup_transitions(cur_state, rc);
}
return EXIT_SUCCESS;
}
/*
* lookup_transition() function has time complexity of class O(n).
* We can optimize it.
* */
enum state_codes
lookup_transitions(enum state_codes cur_state, enum ret_codes rc)
{
#if 0
switch (cur_state) {
case entry:
cur_state = ((rc == ok) ? (foo) : (end));
break;
case foo:
cur_state = ((rc == ok) ? (bar) : ((rc == fail) ? (end) : (foo)));
break;
default:
cur_state = ((rc == ok) ? (end) : ((rc == fail) ? (end) : (foo)));
break;
}
return cur_state;
#else
char arr_size = (sizeof(state_transitions)/sizeof(state_transitions[0])); /* This can be shifted to main function to avoid redundant job. */
char count;
for (count = 0; count < arr_size; count++) {
if ((state_transitions[count].src_state == cur_state) && (state_transitions[count].ret_code == rc)) {
return (state_transitions[count].dst_state);
}
}
#endif
}
int entry_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN ENTRY STATE.\nEnter 0/1: ");
scanf("%d", &st);
rc = ((st == 1) ? (fail) : (ok));
return rc;
}
int foo_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN FOO STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int bar_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN BAR STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int exit_state(void)
{
printf("YOU ARE IN EXIT STATE.\n");
exit(EXIT_SUCCESS);
}
아니 github 웹 사이트에서 복사됩니다 .. 그리고 난 lookup_transtion 코드에 썼습니다. 거의 모든 사람들이 github에서 복사된다는 것을 알고 있습니다. 그것이 Google의 첫 번째 검색 결과입니다. https://gist.github.com/nmandery/1717405 git hub에서 복사 한 내용을 유의하십시오. 그 stackoverflow 대답도 거기에서 복사됩니다. lookup_transition functiom보세요 ... 여기에 붙여 넣었습니다. –
loopup_transtion 함수와 함께 테스트 용 작은 UT 코드를 작성했으며 너무 빨리 결론을 내리지 않습니다. 그리고 당신은 자신의 아테네와 같은 toper .. 느낌이 학생을 위해 필요합니다 ... –
나는 차이를 볼 수없는 이유는 shino을 몰라요. 복사됩니다. 열려있어. 하지만 누락 된 조회 기능과 UT 코드를 찾으십시오. –
- 1. 함수 포인터
- 2. 함수 포인터 및 가상 함수
- 3. 함수 포인터 및 일반 함수
- 4. 함수 포인터 문제
- 5. 함수 포인터 정의
- 6. C++ 함수 포인터 구문
- 7. 함수 포인터 Java에서
- 8. LLVM에서 함수 포인터 생성
- 9. 함수 포인터 간 변환
- 10. C#의 함수 포인터
- 11. 매개 변수의 함수 포인터
- 12. C++ 함수 포인터
- 13. 함수 포인터 사용
- 14. 파이썬 함수 포인터
- 15. Char * (포인터) 함수
- 16. 함수 포인터 증분
- 17. 함수 포인터 기본 질문
- 18. C++ 멤버 함수 포인터
- 19. Inno Setup의 함수 포인터
- 20. 목표 - C 함수 포인터
- 21. 다형 멤버 함수 포인터
- 22. Objective C의 함수 포인터
- 23. c 함수 포인터
- 24. C의 일반 함수 포인터
- 25. C++ 함수 포인터 인라인
- 26. 함수 포인터 쿼리
- 27. 구조체 멤버의 void 포인터 및 함수 포인터
- 28. const 대 포인터 포인터 (함수 용)
- 29. 함수 또는 펑터에 대한 포인터? 함수 생성기
- 30. 클래스의 멤버로서 함수 포인터 배열
FSM은 Finite State Machine을 의미한다고 가정합니다. 함수 포인터가 필요한 것은 무엇입니까? 목표가 무엇인지에 대한 좀 더 자세한 정보는 유용한 예제를 얻는 데 도움이 될 것입니다. – rubenvb
(1) 매우 까다 롭습니다. (2) FSM은 무엇을 의미합니까? (3) 우리에게 보여줄 수있는 코드와 함께 현재 붙어있는 포인터가 있습니까? (4)이 숙제가 있습니까? (그렇다면 질문을 편집하여'숙제 '라는 태그를 붙이십시오.) – stakx
@stakx : 틀림없이 전제가없는 가정을하고 싶습니다. ... – leppie