먼저 우리가 구현해야 할 app controller의 extern 함수들을 확인하겠습니다.
extern int app_init_app(app_t *app); extern void app_process(void); extern int app_set_msg(msg_t msg, uint32_t param1, uint32_t param2); extern int app_start_app(app_id_t id); extern int app_switch_app(app_id_t id); extern app_t *app_get_current_app(void);
각각의 역할은 지난 포스트에서 기록한 대로입니다.
- app_init_app - app 등록
- app_process - 현재 active app의 loop 실행, 메시지 큐에서 빼내어온 메시지 전달
- app_set_msg - 현재 active app 메시지 전달
- app_start_app - active app start
- app_switch_app - app state 전환
- app_get_current_app - 현재 active app id 전달
static app_id_t current_app_id = APP_NONE; static app_t *apps[APP_COUNT]={0, }; static int app_loop_current_app(void); static void app_on_msg_app(void);
각 app들의 포인터를 담을 apps 배열과 몇 개의 static 함수들이 있습니다. current_app_id 는 현재 active 상태의 app id 입니다.
아래는 app을 등록하는 함수 인데 중요한 점은 등록과 동시에 그 app의 init을 해준다는 것입니다.
int app_init_app(app_t *app) { if(app == NULL) return -1; apps[app->id] = app; apps[app->id]->init(); return 0; }
아래 app_process는 main.c의 main infinite loop 에서 호출합니다. 계속해서 메세지 큐에서 쌓인 메시지를 현재 active 상태의 app에 전달(app_on_msg_app)하는 것과 app의 loop 함수를 실행(app_loop_current_app) 시키는 역할을 합니다.
void app_process(void) { app_on_msg_app(); app_loop_current_app(); }
app_set_msg는 메시지 큐에 메시지를 송신하는 함수로 msg와 두개의 파라메터로 이루어져 있습니다.
int app_set_msg(msg_t msg, uint32_t param1, uint32_t param2) { msgs_set_msg(msg, param1, param2); return 0; }
아래 함수는 app을 active 상태로 만드는 기능을 합니다. app의 id를 넘겨주면 해당 app은 active 상태가 되어 메시지 수신, loop 수행을 할 수 있습니다.
int app_start_app(app_id_t id) { if((id >= APP_COUNT) || (apps[id]->start == NULL)) return -1; current_app_id = id; apps[id]->start(); return 0; }
app_switch_app 는 현재 active 된 app을 바꾸는 기능을 합니다. 그 와중에 이전의 app은 stop 함수를 호출해주어 안전하게 app이 스위칭 될 수 있도록 해줍니다.
int app_switch_app(app_id_t id) { if((id >= APP_COUNT) || (apps[id] == NULL)) return -1; if(current_app_id == id) return -1; apps[current_app_id]->stop(); apps[id]->prev_id = current_app_id; current_app_id = id; apps[id]->start(); return 0; }
아래 함수는 현재 app의 포인터를 반환하는 함수입니다.
app_t *app_get_current_app(void) { return apps[current_app_id]; }
app_on_msg_app는 현재 active 상태의 app에 메시지를 전달하는 함수이며 app_loop_current_app 함수는 현재 active 상태의 app의 loop를 실행시켜주는 역할을 합니다.
static void app_on_msg_app(void) { msg_t msg; uint32_t param1; uint32_t param2; if(apps[current_app_id]->on_msg == NULL) return; while(msgs_get_msg(&msg, ¶m1, ¶m2) != -1) { apps[current_app_id]->on_msg(msg, param1, param2); } } static int app_loop_current_app(void) { if(apps[current_app_id]->loop == NULL) return -1; apps[current_app_id]->loop(); return 0; }
이렇게 전반적인 app controller에 대해 알아보았습니다. app controller는 중재자 역할을 하며 app에 실제적인 동작을 실행시켜줍니다. 따라서 구체적인 기능 구현은 각각의 app state에 있습니다. 다음에는 이런 app state를 구현해 보도록 하겠습니다.
'▶ C Application > App 만들기' 카테고리의 다른 글
App state machine 만들기 #5 app states switching (0) | 2023.11.15 |
---|---|
App state machine 만들기 #4 main.c (0) | 2023.11.15 |
App state machine 만들기 #3 app_first.c (0) | 2023.11.15 |
App state machine 만들기 #1 app.h (0) | 2023.11.15 |
App state machine 개요 (0) | 2023.11.14 |