고장이 나더라도 안전한 상태로 떨어지도록 설계하는 원칙(fail-safe).
핵심 발상
- "고장나지 않게 만든다"는 불가능하다
- "고장났을 때 무엇이 되는가"를 설계한다
모든 시스템은 언젠가 고장난다는 전제에서 출발한다.
무엇이 "안전한 상태"인가 — 도메인마다 다르다
- 전기 히터 — → 꺼짐 (계속 켜지면 화재)
- 엘리베이터 — → 정지 + 브레이크 (추락 방지)
- 열차 신호 — → 정지 신호 (진행 신호는 위험)
- 의료 인공호흡기 → 계속 동작 ★ (멈추면 사망)
- 자동차 조향 — → 수동 조향 유지
★ 인공호흡기처럼 "멈추는 것이 더 위험한" 경우도 있다. 이때는 fail-safe가 아니라 fail-operational(고장나도 계속 동작)로 설계한다. 이중화·삼중화가 필요해 훨씬 비싸다.
"안전한 상태를 정의하는 것"이 설계의 첫 단계다.
하드웨어 차원
-
① 리셋 중 GPIO는 하이임피던스
- 외부 풀다운으로 MOSFET·릴레이가 꺼진 상태를 보장
- 내부 풀업/풀다운은 이 구간에 없다 ★
-
② 노멀리 오픈 릴레이
- 전원이 없으면 자동으로 차단
-
③ 전류 제한 회로, 퓨즈, 서멀 컷오프
- 소프트웨어와 무관하게 물리적으로 차단
-
④ 워치독 IC (외부)
- MCU가 죽어도 동작
★ ①이 소프트웨어 엔지니어도 알아야 할 부분이다. 부팅 중 수백 밀리초 동안 GPIO가 불확정 상태인데, 그 사이에 모터가 돌거나 히터가 켜지면 사고가 된다.
소프트웨어 차원
① 워치독 — 기본 중의 기본
폭주하면 리셋되고, 리셋되면 안전 상태에서 다시 시작한다
② 안전 상태로의 진입
void enter_safe_state(void) {
motor_stop();
heater_off();
valve_close();
led_error_on();
// 통신은 유지해 상태를 보고할 수 있게
}
폴트 핸들러, 워치독 복구 직후, 센서 이상 감지 시 호출한다.
③ 입력 검증 — 센서를 믿지 않는다
if (temp < -40 || temp > 150) {
sensor_error_count++;
if (sensor_error_count > 3) enter_safe_state();
return last_valid_temp; // 또는 오류 처리
}
센서 고장 유형
- 단선 — → ADC 값이 0 또는 최대
- 단락 — → 고정된 값
- 드리프트 → 서서히 벗어남 (가장 감지하기 어렵다)
변화율 검사도 유용하다 — 온도가 1초에 50도 오를 수는 없다.
④ 타임아웃 — 모든 대기에
❌ while (!(SPI->SR & RXNE)) { } // 영원히 멈출 수 있다
✅ uint32_t t = timeout;
while (!(SPI->SR & RXNE) && --t) { }
if (!t) return ERROR_TIMEOUT;
블로킹 대기에 타임아웃이 없는 것이 현장 멈춤의 최다 원인이다.
⑤ 이중화와 검증
// 중요 변수를 반전값과 함께 저장
typedef struct { uint32_t value; uint32_t inverted; } SafeVar;
bool check(SafeVar *v) { return v->value == ~v->inverted; }
메모리 손상(ESD, 비트 반전)을 감지한다.
⑥ 상태 머신 방어
switch (state) {
case IDLE: … break;
case RUN: … break;
default: // ★ 정의되지 않은 상태
log_error("잘못된 상태: %d", state);
state = IDLE;
enter_safe_state();
break;
}
정의되지 않은 값으로 넘어가는 것 자체가 이상 신호다.
페일세이프 vs 페일오퍼레이셔널
| fail-safe | fail-operational | |
|---|---|---|
| 고장 시 | 안전 상태로 정지 | 계속 동작 |
| 비용 | 낮다 | 높다(이중화 필요) |
| 예 | 산업 로봇, 히터 | 항공기 조종, 자율주행, 인공호흡기 |
자율주행이 어려운 이유 중 하나가 이것이다 — 고속도로에서 "안전하게 정지"가 오히려 위험할 수 있어 fail-operational이 요구된다.
위험 분석 — 무엇을 보호할지 정하는 절차
- FMEA (Failure Mode and Effects Analysis)
- 각 부품·기능이 고장나는 방식을 나열하고
- 발생 빈도 × 심각도 × 검출 난이도 = 위험 우선순위(RPN)
- 높은 것부터 대책을 세운다
모든 것을 보호할 수는 없다. 위험이 큰 것에 자원을 집중하는 것이 공학적 판단이다.
관련 표준
- IEC 61508 — — 기능 안전 일반 (SIL 1~4)
- ISO 26262 — — 자동차 (ASIL A~D)
- IEC 62304 — — 의료기기 소프트웨어
- IEC 60730 — — 가전 자동 제어 (클래스 A/B/C)
IEC 60730 Class B는 가전제품에도 적용되어, RAM 검사, 플래시 CRC, CPU 레지스터 검사, 클럭 감시를 소프트웨어로 구현할 것을 요구한다. 벤더가 이를 위한 라이브러리를 제공한다.