워치독 타이머 설정: 멈춘 펌웨어를 되살리는 구조와 피드 요령
산업용 제어기나 미션 크리티컬 임베디드 장비를 현장에 배치한 후, 원인을 알 수 없는 데드락(Deadlock)이나 예외 루프에 빠져 시스템이 완전히 정지하는 사고는 펌웨어 엔지니어를 끊임없이 위협하는 시스템 병목입니다. 고전압 서지나 전자기 노이즈(EMI), 예기치 못한 메모리 누수로 인해 CPU 프로그램 카운터(PC)가 엉뚱한 번지수를 가리킬 때 하드웨어를 스스로 복구할 수 있는 최후의 방어선이 바로 워치독 타이머 설정입니다. 그러나 내부 클록 분주비와 타임아웃 윈도우를 정밀하게 연산하지 않고 설계하면, 정상적인 연산 도중 허위 리셋이 발생하거나 반대로 시스템이 정지했음에도 리셋을 걸지 못하는 치명적인 아키텍처 딜레마에 빠지게 됩니다.
특히 워치독 카운터를 초기화하는 이른바 ‘킥(Kick)’ 또는 ‘피드(Feed)’ 루틴을 무분별하게 타이머 인터럽트 서비스 루틴(ISR) 내부에 배치하는 관행은 워치독 타이머 본연의 감시 기능을 무력화시키는 주원인입니다. 메인 스레드가 락(Lock)에 걸려 정지했음에도 하드웨어 인터럽트만 정상 동작하면 워치독은 시스템이 정상이라고 오판하므로, 각 스레드의 실행 상태를 검증하는 정교한 갱신 아키텍처가 요구됩니다.

페이지내용
워치독 타이머 설정: IWDG와 WWDG의 하드웨어 감시 메커니즘
현대 마이크로컨트롤러(MCU)는 일반적으로 두 가지 독립된 워치독 하드웨어를 제공합니다. 첫 번째는 독립 워치독(IWDG)으로, 메인 시스템 클록(HSE/HSI)이 완전히 정지하거나 PLL이 붕괴하더라도 독자적으로 동작하는 저속 내부 전용 RC 발진기(LSI, 약 32kHz~40kHz)에 직결되어 있습니다. 이는 메인 클록 장애나 깊은 하드웨어 결함 시 CPU를 강제로 하드 리셋(Cold Reset)시키는 안전장치 역할을 전담합니다.
두 번째는 윈도우 워치독(WWDG)으로, 메인 APB 버스 클록에서 분주되어 매우 정밀한 마이크로초 단위의 타이밍 감시를 수행합니다. 카운터가 0으로 언더플로될 때만 리셋을 거는 IWDG와 달리, WWDG는 지정된 ‘상한 윈도우 값’보다 일찍 카운터를 피드하거나 ‘하한 언더플로 윈도우(0x3F)’에 도달할 때 즉각 하드웨어 리셋을 유발하여 소프트웨어가 너무 빠르거나 너무 느리게 실행되는 이상 타이밍을 모두 차단합니다.
“독립 워치독(IWDG)은 메인 클록이 멈춘 상태에서도 칩을 안전 상태로 되돌리기 위해 전용 저속 RC 클록(LSI)으로 동작합니다. IWDG 카운터 레지스터에 키 값(0xAAAA)을 재기입하지 않아 다운 카운터가 0x000에 도달하는 순간 즉시 시스템 리셋 신호가 발생하며, 이는 클록 결함에 영향을 받지 않는 페일세이프(Fail-safe) 경로를 보장합니다.”
— STMicroelectronics: STM32F4 Reference Manual (RM0090) IWDG/WWDG Section
위 공식 기술 문서의 규정처럼, IWDG는 소프트웨어가 완전히 통제 불능 상태가 되더라도 전원만 인가되어 있다면 하드웨어 카운트다운을 멈추지 않습니다. 따라서 신뢰성 높은 임베디드 펌웨어를 완성하기 위해서는 두 워치독의 물리적 특성을 시스템 요구 사양에 맞게 선별 배치해야 합니다.

IWDG vs WWDG 타이밍 및 적용 워크로드 비교
워치독 타이머의 선택은 대상 작업의 실시간성 요구 수준과 감시 대상 결함의 유형에 따라 결정됩니다. 하드웨어 프리징에 대비한 일반 감시와 정밀 제어 알고리즘의 타이밍 이탈 감시 특성을 비교하면 다음과 같습니다.
| 비교 항목 | 독립 워치독 (IWDG, Independent) | 윈도우 워치독 (WWDG, Window) |
|---|---|---|
| 구동 클록 소스 | 내부 독립 저속 RC 발진기 (LSI, ~32kHz) | 메인 주변장치 버스 클록 (APB1 PCLK1) |
| 클록 정밀도 | 낮음 (온도/전압에 따라 ±10%~±40% 편차 발생) | 매우 높음 (메인 크리스털 오차 ppm 단위 추종) |
| 리셋 트리거 조건 | 다운 카운터가 0x000에 도달할 때 | 윈도우 상한 이전 갱신 시 + 0x3F 도달 시 |
| 주요 적용처 | 전체 시스템 프리징 방어, 통신 모뎀, 절전 모드 | 모터 제어 주기 감시, 차량 전장, 정밀 타이밍 제어 |
위 표에서 보듯, IWDG는 내부 저속 클록(LSI)의 온도 드리프트가 크기 때문에 타임아웃 설정 시 최소 30%~50% 이상의 안전 마진을 반드시 확보해야 합니다. 반면 WWDG는 너무 이른 피드조차 비정상 루프 실행으로 간주하므로 정밀한 주기 제어가 필요한 고속 알고리즘 감시에 최적화되어 있습니다.

치명적인 피드 위치 실수: 인터럽트 안일주의와 비트마스크 아키텍처
초급 엔지니어가 저지르는 가장 치명적인 실수는 주기적으로 호출되는 1ms 타이머 인터럽트(SysTick 등) 루틴 내부에 `IWDG_ReloadCounter()` 함수를 배치하는 행위입니다. Cortex-M과 같은 현대 프로세서는 우선순위 기반 인터럽트 컨트롤러(NVIC)를 내장하고 있어, 메인 스레드나 중요 통신 태스크가 `while(1)` 데드락에 갇혀 있더라도 타이머 인터럽트는 백그라운드에서 정상적으로 계속 실행됩니다.
결과적으로 실제 시스템은 완전히 먹통이 되었는데도 타이머 인터럽트가 워치독 카운터를 지속적으로 갱신하여 시스템 리셋을 원천 차단하는 이른바 ‘좀비 펌웨어’ 상태가 지속됩니다. 이를 완벽히 방지하려면 각 서브시스템(통신, 센서 수집, 제어 연산)이 정상 완료되었음을 증명하는 비트마스크 체크포인트 감시 아키텍처를 구축해야 합니다.
+
태스크 B (센서) 정상 완료 (0x02)
+
태스크 C (제어) 정상 완료 (0x04)
→
비트마스크 일치 시만 물리 피드 인가
모든 독립적인 필수 루틴이 자신의 실행 플래그 비트를 세트했을 때만 메인 슈퍼루프에서 물리적 하드웨어 피드를 인가하고 비트마스크를 0으로 리셋하는 패턴을 적용해야만 단일 스레드 데드락까지 완벽하게 잡아낼 수 있습니다.

실전 펌웨어 구현: 레지스터 직접 제어 IWDG 및 비트마스크 갱신 루틴
부트로더 및 안전 중심 펌웨어에서 라이브러리 종속성 없이 STM32 마이크로컨트롤러의 IWDG 레지스터를 직접 제어하고, 멀티태스크 실행 무결성을 검증하여 피드하는 C/C++ 소스 코드 스니펫입니다.
#include <stdint.h>
#include <stdbool.h>
#include "stm32f4xx.h"
// 태스크 식별용 비트마스크 정의
#define TASK_COMM_BIT (1 << 0)
#define TASK_SENSOR_BIT (1 << 1)
#define TASK_CONTROL_BIT (1 << 2)
#define ALL_TASKS_MASK (TASK_COMM_BIT | TASK_SENSOR_BIT | TASK_CONTROL_BIT)
static volatile uint8_t g_task_health_bits = 0;
// LSI = 32kHz 기준 타임아웃 설정: Prescaler = 64 (500Hz), Reload = 500 -> 정확히 1.0초
void IWDG_Init_Direct(uint16_t reload_val) {
// 1. IWDG 쓰기 접근 해제 키(0x5555) 인가 (PR 및 RLR 쓰기 허용)
IWDG->KR = 0x5555;
// 2. 분주비(Prescaler) 설정: 64분주 (PR 비트 = 0b100)
// 클록 주기: 32000Hz / 64 = 500Hz (1 tick = 2ms)
IWDG->PR = IWDG_PR_PR_2;
// 3. 재로드(Reload) 카운터 값 설정 (0x000 ~ 0xFFF)
IWDG->RLR = reload_val & 0x0FFF;
// 4. 초기 카운터 리로드 (0xAAAA)
IWDG->KR = 0xAAAA;
// 5. IWDG 타이머 카운트다운 강제 기동 (0xCCCC)
// 한번 활성화되면 하드웨어 리셋 전까지 소프트웨어로 중단 불가
IWDG->KR = 0xCCCC;
}
// 각 태스크에서 정상 실행 후 주기적 호출
void Watchdog_Report_Task_Complete(uint8_t task_bit) {
g_task_health_bits |= task_bit;
}
// 메인 슈퍼루프에서만 호출되는 안전 피드 함수
void Watchdog_Process_Master_Feed(void) {
// 모든 태스크가 정상 사이클을 완주하여 비트마스크가 모두 1인지 확인
if ((g_task_health_bits & ALL_TASKS_MASK) == ALL_TASKS_MASK) {
// 하드웨어 카운터 갱신 (0xAAAA 기입)
IWDG->KR = 0xAAAA;
// 다음 검증 주기를 위해 플래그 초기화
g_task_health_bits = 0;
}
// 하나의 태스크라도 데드락에 빠지면 피드가 차단되어 1.0초 후 하드웨어 리셋 발생
}위 펌웨어에서 `IWDG->KR = 0xCCCC`가 실행되는 순간 하드웨어 타이머는 봉인되어 디버거가 연결되거나 시스템 전원이 차단되지 않는 한 멈추지 않습니다. 또한 3단계 제어 비트가 메인 루프에서 모두 취합되어야만 피드가 단행되므로 실무 환경의 교착 상태를 완벽하게 탐지합니다.
워치독 타이머 설계 및 양산 실무 체크리스트
- 디버그 정지 레지스터(DBGMCU) 설정: 디버깅 중 브레이크포인트에 걸렸을 때 워치독이 리셋을 유발하지 않도록 `DBGMCU_APB1_FZ` 레지스터에서 카운터 정지 비트를 세트한다.
- 플래시 메모리 쓰기 타임아웃 고려: 내부 플래시 소거 및 쓰기(Page Erase) 시간 동안 CPU가 멈추므로 워치독 주기가 플래시 최대 지연보다 길게 설정되었는지 확인한다.
- 리셋 원인 레지스터 검사: 부팅 즉시 `RCC->CSR` 레지스터의 `IWDGRSTF` 플래그를 검사하여 워치독에 의한 리셋인지 판별하고 로그를 플래시나 EEPROM에 영구 기록한다.
- 하드웨어 윈도우 마진 확보: WWDG 사용 시 통신 대기 지연으로 인한 조기 피드가 발생하지 않도록 윈도우 상한 시간 마진을 최소 20% 이상 열어둔다.

실무 엔지니어링 FAQ
Q1. 딥슬립(Stop/Standby) 저전력 모드에 진입할 때 IWDG가 리셋을 유발하는 문제는 어떻게 해결합니까?
IWDG는 코어가 잠들더라도 LSI 클록에 의해 계속 카운트다운을 수행합니다. MCU 옵션 바이트(Option Byte) 설정에서 `IWDG_STDBY` 및 `IWDG_STOP` 플래그를 비활성화하여 저전력 모드 진입 시 워치독 카운터가 자동으로 일시 정지되도록 구성하거나, 슬립 타이머를 워치독 타임아웃보다 짧게 분할하여 주기적으로 깨어나 피드하도록 펌웨어를 작성해야 합니다.
Q2. FreeRTOS와 같은 실시간 OS 환경에서는 워치독을 어떻게 분배하여 관리해야 합니까?
독립적인 ‘Watchdog Supervisor Task’를 가장 낮은 우선순위(Idle 바로 위)로 생성하고, 각 고우선순위 태스크가 정해진 주기마다 이벤트 그룹(Event Group) 비트를 세트하도록 구현합니다. 슈퍼바이저 태스크가 모든 비트를 확인한 후에만 하드웨어 워치독을 피드하도록 설계하면 저우선순위 태스크 기아(Starvation) 현상까지 한 번에 감시할 수 있습니다.
Q3. 소프트웨어 워치독 활성화와 하드웨어 워치독 옵션 바이트의 결정적 차이는 무엇입니까?
소프트웨어 워치독은 펌웨어 코드가 특정 레지스터를 조작해야 동작하므로 부팅 초기화 도중 충돌이 발생하면 방어할 수 없습니다. 반면 옵션 바이트로 하드웨어 워치독을 활성화하면 MCU 전원이 인가되는 순간 코드 실행 전부터 하드웨어 카운터가 강제 가동되므로 부트로더 결함이나 클록 초기화 실패까지 완벽하게 리셋할 수 있습니다.
공식 기술 가이드 및 표준 규격 레퍼런스
이 글은 정보 제공을 목적으로 작성되었으며, 실제 기기·환경·정책에 따라 결과가 다를 수 있습니다. 보다 정확하고 최신인 정보는 아래 공신력 있는 기관의 자료를 함께 참고하시기 바랍니다.


