먼저 우리가 구현해야 할 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 |