Watchdog timers — purpose, feeding, types
Overview
A watchdog timer (WDT) is a hardware timer that automatically resets or interrupts a system if software fails to periodically "feed" it. It's a fault-tolerance mechanism that protects embedded systems from software hangs, infinite loops, and deadlocks.

In embedded systems, software can "hang" due to bugs, memory corruption, or hardware faults. Without intervention, the system stays frozen indefinitely. A watchdog timer forces the system to either prove it's alive (by resetting the timer) or be automatically restarted.
WHY this matters: Embedded systems often run unattended in critical applications (medical devices, automotive, industrial control). A software hang could be catastrophic. The watchdog provides automatic recovery without human intervention.
The Fundamental Mechanism
HOW it works:
- Initialization: Configure WDT with timeout period (e.g., 500ms)
- Enable: Start the countdown
- Normal operation: Software "feeds" (resets) the timer within timeout period
- Fault condition: If software hangs, feeding stops → timer expires → system reset/interrupt
- Recovery: System restarts, ideally recovering from the fault
Where:
- = timeout period (seconds)
- = maximum counter value (hardware-dependent, often 16-bit = 65535)
- = clock frequency feeding the WDT
- prescaler = clock divider (1, 8, 64, 256, 1024 typical values)
WHY this formula? The watchdog is just a down-counter clocked by a divided system clock. The timeout is how long it takes to count from to 0 at the divided clock rate.
DERIVATION:
- Counter decrements once per clock cycle at divided frequency
- Divided frequency:
- Time per decrement:
- Total time for decrements:
Calculate timeout:
Wait, that's too long! Most embedded systems use shorter prescalers. With prescaler = 64:
WHY this matters? You choose the prescaler based on how quickly you want recovery. Longer timeout = more tolerance for legitimate long operations. Shorter timeout = faster recovery from hangs but risk false resets during valid long operations.
Types of Watchdog Timers
1. Hardware-Only Watchdog
Characteristics:
- Independent of CPU core
- Often uses separate clock source (internal RC oscillator)
- Reset via dedicated register write or I/O pin toggle
- Configuration locked at startup or via fuses
Feeding mechanism:
// AVR example - write specific value to WDT register
WDTCSR |= (1 << WDE); // Enable watchdog
// In main loop:
wdt_reset(); // Clears the timer (inline assembly: __asm__ __volatile__ ("wdr"))WHY separate clock? If the main clock fails, the system hangs but the watchdog still runs on its independent clock and can trigger a reset.
void setup() { // Configure for 250ms timeout wdt_enable(WDTO_250MS); // Macro sets prescaler bits }
void loop() { // Do work... critical_sensor_read(); compute_control_output(); // Feed watchdog before timeout wdt_reset(); // Must happen within250ms delay(100); // Safe - leaves150ms margin }
**WHY this step?** `wdt_enable()` sets hardware bits that configure the timeout. `wdt_reset()` resets the counter to maximum. If `loop()` hangs in any function, the reset never happens, timer expires, system resets.
> [!mistake] Feeding Too Frequently
> **Wrong approach:**
> ```c
> void loop() {
> wdt_reset(); // First thing in loop
> potentially_hanging_function(); // Bug here never detected!
> }
> ```
**WHY this feels right:** "I'll reset the watchdog immediately so I never forget."
**The problem:** If `potentially_hanging_function()` hangs, the watchdog was already reset, so you get a full timeout period before recovery. Worse, if there's a tight loop that bypasses most code but hits the reset, the watchdog never catches the logic error.
**The fix:** Feed the watchdog ==after== critical operations complete successfully, using it as a "heartbeat" that proves the main loop executed fully:
```c
void loop() {
sensor_read();
process_data();
update_outputs();
wdt_reset(); // Only feed if we completed full loop iteration
}
2. Software-Controlled Watchdog
Characteristics:
- Can be turned off via register writes
- More configuration options (interrupt vs reset)
- Less protection against wild pointers or stack corruption
Feeding mechanism:
// STM32 example
HAL_IWDG_Refresh(&hiwdg); // Reload counter registerWHY allow software control? During debugging, development, or firmware updates, you may need to disable the watchdog. Production systems often use hardware-locked watchdogs.
3. Window Watchdog
Where:
- = minimum time before feeding is allowed
- = maximum time before feeding causes timeout
- = actual time when feed occurs
WHY two bounds?
- Upper bound (): Like normal watchdog, catches hangs
- Lower bound (): Catches code running too fast (interrupt storms, tight loops, timing bugs)
DERIVATION of bounds: In hardware, a window watchdog uses two comparators:
- Counter value compared to upper threshold: → reset
- Counter value compared to lower threshold: → reset allowed
Time mapping:
Thus:
uint32_t last_feed = 0;
void loop() { uint32_t now = HAL_GetTick(); // milliseconds
do_critical_work();
// Feed only in valid window
if (now - last_feed >= 60 && now - last_feed <= 80) {
HAL_WWDG_Refresh(&hwdg);
last_feed = now;
}
}
**Scenario - bug caught:** Suppose an interrupt fires every 10ms and calls `loop()`. Without window watchdog, the normaldog gets fed 8 times per80ms period - looks healthy! But the timing is wrong. The window watchdog resets the system because feeding at 10ms is too early, forcing you to fix the timing bug.
**WHY this step?** Window watchdogs enforce not just "is the code running?" but "is the code running at the RIGHT RATE?" This catches timing violations that regular watchdogs miss.
## Watchdog Feeding Strategies
### Strategy 1: Main Loop Heartbeat
```c
void main() {
wdt_enable(WDTO_500MS);
while(1) {
task(); // 50ms
task2(); // 100ms
task3(); // 50ms
// Total: ~200ms per iteration
wdt_reset(); // Heartbeat - proves full loop executed
}
}
WHY this works? Each feed proves all tasks completed. If any task hangs, the feed doesn't happen, timeout triggers.
Timeout sizing: > worst-case loop time + margin. Here: 500ms > 200ms + margin.
Strategy 2: Task-Based Feeding (RTOS)
// FreeRTOS example
void watchdog_task(void *param) {
const TickType_t feed_interval = pdMS_TO_TICKS(200);
while(1) {
// Check if all critical tasks reported in
if (task1_alive && task2_alive && task3_alive) {
wdt_reset();
task1_alive = false; // Reset flags
task2_alive = false;
task3_alive = false;
}
vTaskDelay(feed_interval);
}
}
void critical_task1(void *param) {
while(1) {
do_work();
task1_alive = true; // Report health
vTaskDelay(pdMS_TO_TICKS(50));
}
}WHY this approach? In RTOS with multiple tasks, the watchdog task only feeds if ALL critical tasks reported in. If any task hangs, the system resets.
DERIVATION of feed interval:
- Each critical task reports every
- Watchdog task checks every
- Timeout must satisfy:
If task reports every 50ms, watchdog checks every 200ms, timeout should be > 250ms + margin = 500ms.
Problem: How often to feed the watchdog?
Analysis:
- Longest critical period: Task C at 1000ms
- Watchdog timeout must be > 1000ms to allow Task C to complete
- Set timeout = 1500ms (1.5× longest period for margin)
- Watchdog task runs at 500ms, collects "alive" flags from all tasks
- Feed only if all flags set since last check
WHY these numbers? Each task sets its flag after successful completion. Watchdog task verifies all tasks ran in the last check period (500ms). But timeout is 1500ms tolerate Task C's 1000ms period. If any task fails for >1500ms, system resets.
WHY this feels right: "If any task is alive, feed the watchdog."
The problem: System can be partially failed. Task1 and Task2 hang, but Task3 keeps running and feeding the watchdog. Critical functions are broken but system doesn't reset.
The fix: Use AND logic - ALL critical tasks must report:
if (task1_alive && task2_alive && task3_alive) { // AND - correct
wdt_reset();
}Strategy 3: Hierarchical Feeding
For complex systems, use multiple watchdogs:
- Hardware watchdog (1s timeout): Last resort, catches total system hang
- Software watchdog (500ms): Monitors main loop, can generate interrupt before hard reset
- Task watchdogs (per-task timeouts): Each critical task has its own monitor
WHY layers? Defense in depth. Inner layers catch problems earlier with more context (interrupt handler can log state before reset). Outer layer guarantees recovery even if inner layers fail.
Watchdog Timer Reset Handling
When a watchdog triggers, the system resets. Firmware must detect this on startup:
#include <avr/wdt.h>
void setup() {
uint8_t reset_source = MCUSR; // Read reset status register
MCUSR = 0; // Clear for next time
if (reset_source & (1 << WDRF)) {
// Watchdog caused reset
log_error("WDT reset occurred");
error_count++;
if (error_count > 3) {
enter_safe_mode(); // Too many resets, something seriously wrong
}
}
wdt_enable(WDTO_500MS); // Re-enable watchdog
}WHY check reset source? Distinguish watchdog resets from power-on, brown-out, or software resets. Track watchdog resets over time to detect chronic reliability issues.
Where:
- = hardware reset pulse duration (typically 1-10ms)
- = bootloader execution time (0ms if no bootloader, or50-500ms)
- = application initialization time (variable, should be minimized)
WHY this matters? In real-time systems, watchdog recovery causes a service interruption of duration . Design initialization to be as fast as possible while still ensuring safe startup.
DERIVATION: These times add serially because each must complete before the next begins. Minimize each component:
- : Hardware fixed, typically<10ms
- : Disable bootloader in production or use fast bootloader
- : Initialize only critical subsystems before feeding first watchdog; defer non-critical init
Target: < 1 second for most embedded systems.
Practical Considerations
Timeout Selection:
- Too short: False resets during valid long operations
- Too long: Slow recovery from actual faults
- Rule of thumb: = 2× to 3× nominal loop time
Interrupt vs Reset: Some watchdogs offer interrupt mode: generate interrupt before final reset. Use this to:
- Log system state for debugging
- Attempt recovery (clear stuck peripheral, reset state machine)
- If recovery fails, allow progression to hard reset
Testing Watchdogs: You MUST test that the watchdog actually works:
void test_watchdog() {
wdt_enable(WDTO_500MS);
while(1) {
// Deliberately don't feed - should reset in 500ms
}
// Should never reach here
}WHY test? Misconfigured watchdog gives false confidence. Always verify it triggers in development.
Power Consumption: Watchdogs typically use independent RC oscillators that run in sleep modes. Adds ~1-10µA to sleep current. Factor this into battery life calculations for ultra-low-power designs.
Recall Explain to a12-Year-Old
Imagine you have a little robot that does homework for you. But sometimes, the robot gets confused and freezes up - it just sits there, not doing anything, stuck forever.
A watchdog timer is like setting a kitchen timer for the robot. You tell the robot: "Every 5 minutes, you must come press this button to reset the timer. If you forget, the timer goes BEEP and I'll turn you off and back on to fix you."
Now, when your robot is working properly, every few minutes it thinks "Oh, time to reset that timer!" and presses the button. The timer resets, and everything keeps going.
But if the robot freezes - it can't press the button. The timer keeps counting down... 4 minutes... 3 minutes... 2... 1... BEEP! The timer goes off, which automatically turns the robot off and back on (like unplugging it and plugging it back in). When it restarts, it's not frozen anymore - problem fixed!
The trick is: the robot has to remember to press the button ONLY when it's actually working correctly on homework. If it presses the button while it's stuck in a bad loop (like doing the same math problem wrong over and over), that doesn't help. So you train the robot to only press the button after it finishes a complete homework problem correctly.
That's exactly what embedded systems do with watchdog timers - they make sure the computer is actually working right, and if it freezes, they automatically restart it!
Connections
- Interrupt Service Routines - Watchdog can generate interrupts before reset
- Real-Time Operating Systems - RTOS task monitoring with watchdogs
- Hardware Timer Peripherals - Watchdog uses timer hardware
- System Reset Sources - Detecting and handling different reset types
- Fault Tolerance - Watchdog is one layer of fault-tolerant design
- Brown-Out Detection - Works alongside watchdog for power fault protection
- Safe State Design - System behavior after watchdog reset
- Bootloader Design - Watchdog behavior during firmware updates
#flashcards/coding
What is a watchdog timer? :: A hardware timer that automatically resets the system if software fails to periodically "feed" (reset) it, providing protection against software hangs and deadlocks.
Why use an independent clock source for the watchdog?
What is a window watchdog?
What is the formula for watchdog timeout?
Why feed the watchdog AFTER critical operations, not before?
What's the difference between hardware-only and software-controlled watchdog? :: Hardware-only cannot be disabled by software (maximum protection); software-controlled can be enabled/disabled at runtime (more flexible but less protection).
In RTOS, should watchdog feeding use AND or OR logic for task flags?
How to detect if a watchdog caused the last reset?
What should timeout be relative to loop time?
Why might you use interrupt mode before reset?
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Watchdog timer ek bahut important safety mechanism hai jo embedded systems mein use hota hai. Socho ki tumhara microcontroller kisi infinite loop ya deadlock mein fas gaya hai - normal case mein system permanently hang ho jayega aur manually restart karna padega. Lekin critical applications mein jaise medical devices, car electronics, ya industrial machinery, ye acceptable nahi hai.
Watchdog timer ka kaam simple hai:ek hardware counter hai jo continuously count down karta rehta hai. Tumhare software ko regularly is counter ko "feed" karna padta hai (matlab reset karna padta hai). Agar software properly chal raha hai, to har100ms ya 500ms mein (jo bhi configure kiya ho) wo watchdog timer ko reset kar dega. Lekin agar code kahin hang ho gaya, to feeding nahi hogi, counter zero tak pahunch jayega, aur automatically system reset ho jayega - hardware level pe, software ka koi control nahi. Ye bilkul automatic recovery hai.
Window watchdog ek advanced version hai jahan tumhe ek specific time window ke andar feed karna padta hai - na bahut jaldi, na bahut der se. Agar tumne bahut jaldi feed kar diya (matlab code bahut fast loop mein hai jo nahi hona chahiye), to bhi reset ho jayega. Agar bahut late kiya, to bhi reset. Isse timing bugshi catch ho jate hain jo normal watchdog miss kar deta.
Production embedded systems mein watchdog timer mandatory hai kyunki field mein unattended operation mein automatic recovery ka yahi ek reliable tarika hai. Proper timeout selection, strategic feeding points, aur reset handling design karke, tum apne system ko fault-tolerant bana sakte ho - agar kuch galat hua, system khud recover kar lega bina human intervention ke.