Watchdog & Reset Recovery

Table of contents

Overview

Watchdog은 software progress가 멈췄을 때 복구를 시작하는 수단이다. 무조건 주기적으로 feed하는 코드만 넣으면 일부 task가 멈춰도 fault를 숨길 수 있다.

Supervision Design

각 필수 task가 주기 안에 progress counter를 갱신하고 supervisor가 모두 충족됐을 때 feed하는 구조를 검토한다. counter 갱신 시점은 loop 진입이 아니라 요구 작업의 실제 진행을 반영한다. window watchdog은 너무 빠른 feed도 오류가 될 수 있다.

Reset Record

reset reason, boot count, 마지막 유효 상태와 fault 요약을 보존 정책에 따라 기록한다. retained RAM·flash의 보존 범위는 reset 종류별로 다르다. flash에 매 tick 기록하여 수명을 소모하지 않는다.

Recovery Policy

반복 reset이면 진단 가능 상태나 제한 기능으로 진입할 수 있도록 요구사항을 정의한다. 정상 상태로 보이게 watchdog을 비활성화하는 것을 해결책으로 삼지 않는다. debugger 연결 시 watchdog 정지 옵션은 실차 실행과 다를 수 있다.

Fault Injection

task 정지, interrupt storm, deadlock, clock 변경, 초기화 실패와 reset 직후 전원 차단을 시험한다. reset 후 output 초기값·pending command 폐기·통신 재동기화까지 확인한다.

S32K312 Watchdog Setup

💡

실제 watchdog IP·clock source·timeout·window·unlock/refresh sequence는 S32K312 매뉴얼과 설치 RTD를 기준으로 확인한다. 아래 health gate는 feed 여부를 판단하는 예제이며 hardware refresh sequence를 구현하지 않는다.

단계 확인할 내용
Reset cause Startup에서 reset status를 읽고 clear 전에 필요한 원인을 보존한다.
Clock 독립 clock 여부·허용 오차·저전력 동작을 확인한다. CPU clock으로 timeout을 계산하지 않는다.
Timeout / Window 최악 작업 지연보다 여유를 두되 요구 복구 시간 안에 있도록 선택한다. 너무 빠른 refresh 금지 조건도 확인한다.
Initialization Boot ROM·Bootloader·Application 사이 watchdog 상태와 첫 refresh deadline을 인계한다.
Lock / Debug 설정 lock 후 변경 가능 여부와 debugger 연결 시 freeze 동작을 검증한다.
Reset output Reset 직후 actuator GPIO·통신 buffer·명령 queue가 요구 상태로 초기화되는지 확인한다.

Progress Supervision in C

각 task가 실제 일을 완료했을 때 progress counter를 갱신한다. 아래 함수에 전달하는 snapshot은 task/ISR 사이의 보호된 복사 또는 검증된 Atomic/RTOS mechanism으로 확보해야 한다.

#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#define TASKS 3u
typedef struct { uint32_t last[TASKS]; } Health;
bool all_progressed(Health *h, const uint32_t now[TASKS]) {
    if (!h || !now) return false;
    for (size_t i=0;i<TASKS;i++)
        if (now[i]==h->last[i]) return false;
    for (size_t i=0;i<TASKS;i++) h->last[i]=now[i];
    return true;
}

모든 task가 매 supervision interval마다 진행해야 한다는 예제다. 서로 다른 주기 task는 각자의 deadline·alive count 범위로 감독한다. all_progressed가 true여도 window open 여부를 확인한 뒤 하나의 supervisor만 feed한다. 부팅 초기 last 값은 첫 유효 snapshot으로 초기화하고 첫 deadline을 별도로 관리한다.

Failure Diagnosis

ISR에서 무조건 feed하면 main/task deadlock을 숨길 수 있다. Supervisor 자체가 멈췄을 때 watchdog이 실제 reset하는지 확인한다. Reset loop가 발생하면 watchdog을 끄기 전에 boot deadline·retained state·clock·계속되는 외부 fault를 분석한다.