노트 / 자료구조와 알고리즘
상태 머신: 펌웨어 설계의 기본 도구
복잡한 동작 순서를 상태와 전이로 정리합니다. 플래그가 늘어나 if문이 얽히기 시작하면 상태 머신으로 바꿀 때입니다.
전기밥솥은 대기, 취사, 뜸 들이기, 보온 중 하나의 상태에 있습니다. 버튼이나 온도 같은 이벤트가 오면 다음 상태로 넘어갑니다. 펌웨어의 대부분은 이렇게 표현할 수 있습니다.
switch로 만드는 기본형
typedef enum { IDLE, RUN, FAULT } state_t;
static state_t st = IDLE;
void motor_task(void) {
switch (st) {
case IDLE: if (start_pressed()) { pwm_on(); st = RUN; } break;
case RUN: if (overcurrent()) { pwm_off(); st = FAULT; }
else if (stop_pressed()) { pwm_off(); st = IDLE; } break;
case FAULT: if (reset_pressed()) st = IDLE; break;
}
}
좋은 상태 머신의 조건
- 상태 그림을 먼저 그립니다. 동그라미는 상태, 화살표는 이벤트와 동작입니다.
- 모든 상태에서 모든 이벤트에 대해 "무엇을 하는가"가 정해져 있어야 합니다. 정의되지 않은 조합이 버그가 됩니다.
- 상태에 들어갈 때 한 번 하는 일(entry)과 머무는 동안 하는 일을 구분합니다.
- 고장 상태에서 빠져나오는 길을 반드시 만듭니다.
상태가 많아지면 상태별 처리 함수를 함수 포인터 표로 관리하거나, 상위 상태를 두는 계층형 상태 머신으로 확장합니다.