WDT로 멈춘 임베디드 시스템을 복구하는 설계
WDT(Watchdog Timer)의 타임아웃·Kick·리셋 구조와 유형별 특성, 임베디드 시스템에서의 안전한 설계 기준을 정리한다.
2026-08-14 · 최초 발행 2026-01-16
Kick이 멈추면 복구를 시작하는 타이머
WDT(Watchdog Timer)는 임베디드 시스템과 컴퓨터 시스템에서 소프트웨어 오동작이나 시스템 행(Hang) 상태를 감지해 복구하는 하드웨어 타이머다. 정상 동작 중인 소프트웨어는 주기적으로 타이머를 리셋해야 하며, 이 동작을 수행하지 못하면 시스템 리셋이 발생한다. 산업용 기기, 자동차, 의료기기처럼 높은 신뢰성이 필요한 환경에서 안전 메커니즘으로 사용된다.
WDT는 시스템의 정상 동작을 감시하는 하드웨어 카운터다. 설정된 시간 안에 소프트웨어가 타이머를 갱신(Kick, Feed)하지 않으면 리셋 신호를 발생시켜 비정상 상태에서 복구한다. 이름은 시스템을 지키는 감시견(Watchdog)에서 유래했다.
이 동작에는 다음 조건이 결합된다.
- 다운 카운터 또는 업 카운터로 시간 경과를 측정한다.
- 소프트웨어는 정상 상태에서 타이머를 주기적으로 리셋한다.
- 갱신이 실패하면 타임아웃에 따라 시스템 리셋 또는 인터럽트가 발생한다.
- 하드웨어 모듈은 소프트웨어 오동작과 분리되어 동작한다.
메인 루프나 태스크가 계속 실행되는 동안에는 WDT가 갱신되어 타임아웃이 일어나지 않는다. 무한 루프, 데드락, 예외 상황으로 정상 흐름이 끊기면 갱신도 멈추고, WDT가 리셋을 수행한다.
하드웨어 모듈이 시간과 리셋을 다루는 방식
WDT는 대체로 마이크로컨트롤러나 SoC 안의 독립 하드웨어 모듈로 구현된다.
| 구성 요소 | 역할 | 특징 |
|---|---|---|
| 클록 소스 | 카운터 동작의 기준 클록 | 독립 RC 오실레이터 사용 |
| 프리스케일러 | 클록 분주로 타임아웃 범위 조절 | 다양한 분주비 설정 |
| 카운터 레지스터 | 경과 시간 카운트 | 다운/업 카운터 방식 |
| 비교 레지스터 | 타임아웃 값 설정 | 사용자 설정 가능 |
| 제어 레지스터 | WDT 활성화, 모드, 인터럽트 설정 | 한번 활성화 시 비활성화 제한 |
| 리셋 출력 | 타임아웃 시 시스템 리셋 신호 | CPU 및 주변장치 리셋 |
감시 범위에 따라 달라지는 WDT 유형
기본 WDT는 가장 단순한 형태다. 타임아웃이 발생하면 즉시 시스템을 리셋하며, 단일 타임아웃 설정과 리셋만 지원하는 구조라 구현이 단순하고 저비용 시스템에 적합하다.
윈도우 WDT(Windowed Watchdog)는 정해진 시간 창(Window)에서만 갱신을 허용한다.
이 방식은 일정 시간이 지난 뒤에만 갱신을 허용하고, 타임아웃 전에는 반드시 갱신하도록 만든다. 따라서 멈춘 상태뿐 아니라 루프가 비정상적으로 빠르게 도는 경우도 감시할 수 있다.
독립 WDT(IWDG)는 메인 시스템 클록과 별도의 독립 클록 소스를 사용한다. 독립 RC 오실레이터를 사용하며 보통 40kHz 내외로 동작한다. 메인 클록 장애에도 동작을 보장하고 저전력 모드에서도 사용할 수 있어 신뢰성이 높다.
시스템 윈도우 WDT(WWDG)는 메인 시스템 클록을 사용하면서 윈도우 기능을 제공한다. APB 클록 기반으로 동작하고, 프로그래밍 가능한 윈도우와 얼리 웨이크업 인터럽트를 통해 타임아웃 전 경고를 제공한다.
태스크 상태를 확인한 뒤 Kick 보내기
싱글 태스크 시스템에서는 메인 루프에서 WDT를 주기적으로 갱신할 수 있다.
void main(void) {
system_init();
wdt_init(TIMEOUT_1S);
wdt_start();
while(1) {
// 메인 처리 로직
process_sensors();
update_outputs();
check_communications();
// WDT 갱신
wdt_kick();
}
}
멀티 태스크 환경에서는 각 태스크의 실행 상태를 모으고, 모든 태스크가 정상일 때만 WDT를 갱신하는 구조가 필요하다.
타임아웃은 최악의 정상 실행 시간보다 충분히 길게 잡아야 한다. 시스템 초기화가 완료되기 전에 WDT를 활성화하고, 런타임에서는 비활성화할 수 없도록 설정하며, 리셋 원인을 분석해 적절한 복구 처리를 연결하는 방식도 고려 대상이다.
void system_init(void) {
uint32_t reset_cause = get_reset_cause();
if (reset_cause & RESET_WDT) {
// WDT 리셋 발생
log_error("WDT Reset occurred");
increment_wdt_counter();
if (wdt_counter > MAX_WDT_RESETS) {
enter_safe_mode();
}
}
clear_reset_flags();
}
산업 제어와 ECU에서의 감시 체계
PLC(Programmable Logic Controller) 같은 산업용 제어 시스템에서 WDT는 필수 요소다. 외부 하드웨어 WDT 칩을 추가하거나, MCU 내장 WDT와 외부 WDT를 함께 두는 다중 WDT 계층을 구성할 수 있다. 이 구성은 안전 무결성 수준(SIL) 요구사항을 충족하는 데 사용된다.
자동차 ECU에서는 ISO 26262 기능안전 표준 준수를 위해 WDT를 사용한다.
| ECU 유형 | WDT 요구 사항 |
|---|---|
| 엔진 제어 | 이중화 WDT, 윈도우 방식 |
| 브레이크 시스템 | 독립 WDT, 외부 모니터링 |
| 조향 시스템 | 다중 채널 감시, 안전 상태 전환 |
| 인포테인먼트 | 기본 WDT, 소프트 리셋 허용 |
통신 장비에서는 WDT 리셋 이후 빠른 복구가 서비스 연속성과 연결된다.
타임아웃과 갱신 위치에서 놓치기 쉬운 문제
타임아웃이 너무 짧으면 정상 동작 중에도 리셋이 발생하며, 너무 길면 오동작 감지가 늦어진다. 최대 루프 시간의 2~3배를 기준으로 설정하고, 인터럽트 지연·캐시 미스 같은 최악 조건을 고려해 테스트로 검증한다.
WDT 갱신은 모든 주요 처리가 끝난 뒤에 이뤄져야 한다. 무한 루프 안에서 무조건 실행하는 위치, 인터럽트 핸들러, 정상 여부를 확인하지 않는 분기는 감시 기능을 무력화할 수 있다.
// 잘못된 예: 무조건적 갱신
while(1) {
wdt_kick(); // 항상 실행되어 오류 감지 불가
if (condition) {
// 이 부분에서 행이 발생해도 감지 못함
blocking_operation();
}
}
인터럽트에서만 WDT를 갱신하면 메인 루프의 행을 감지하지 못한다. 인터럽트는 플래그 설정만 맡기고, 메인 루프가 플래그를 확인한 뒤 WDT를 갱신하는 구조가 적절하다.