Watchdog Timers: Keeping Embedded Systems Alive
This article is intended for intermediate and advanced C programmers. It explains what watchdog timers are, how they detect software failures, and how they automatically recover embedded systems by resetting the processor when normal program execution stops.
1. Why Do We Need a Watchdog Timer?
Embedded systems are often expected to operate continuously for months or even years without human intervention. Unlike desktop computers, many embedded devices are deployed in remote, inaccessible, or safety-critical environments where manually restarting the system may be difficult, expensive, or impossible.
Unfortunately, software is not immune to failures.
A running application may stop functioning correctly because of:
- An infinite loop
- A deadlock
- Memory corruption
- A stack overflow
- Unexpected hardware faults
- Electromagnetic interference (EMI)
- Software bugs
When such failures occur, the processor may still be powered and running, but the application is no longer making progress.
Consider the following example.
Embedded System
+----------------------+
| Application Running |
+----------+-----------+
|
Unexpected Bug
|
▼
+----------------------+
| Infinite Loop |
+----------+-----------+
|
▼
System Stops Responding
Without a recovery mechanism, the device remains stuck until someone manually resets or power-cycles it.
For some systems, this may simply be an inconvenience.
For others, the consequences can be much more serious.
- An industrial controller may stop controlling a production line.
- An IoT gateway may become unreachable.
- A weather station may stop transmitting measurements.
- An automotive controller may stop responding.
- A medical device may stop performing its intended function.
A robust embedded system should therefore be able to detect that its software has stopped operating correctly and recover automatically without requiring human intervention.
This is exactly the problem that a watchdog timer is designed to solve.
A watchdog timer continuously supervises the execution of the application. As long as the software continues operating normally, it periodically refreshes the watchdog. If the software crashes, hangs, or stops executing correctly, the watchdog is no longer refreshed. After a predefined timeout, it assumes the software has failed and automatically resets the processor.
+----------------+
| Application |
+-------+--------+
|
Refresh Watchdog
|
▼
+------------------+
| Watchdog Timer |
+--------+---------+
|
Timeout Occurred?
|
+----+----+
| |
No Yes
| |
▼ ▼
Continue System Reset
The next section explains what a watchdog timer actually is, how it works, and why it is implemented as a hardware peripheral in most modern microcontrollers.
2. What Is a Watchdog Timer?
A watchdog timer (WDT) is a dedicated hardware peripheral whose primary purpose is to detect software failures and automatically recover the system.
Unlike ordinary timers that generate delays, periodic interrupts, or measure elapsed time, a watchdog timer continuously supervises whether the application is still executing normally.
Most modern microcontrollers include at least one hardware watchdog timer, while some provide multiple watchdogs for different purposes. For example, one watchdog may supervise the main processor, while another monitors safety-critical functions.
The watchdog operates independently of the application software, allowing it to continue running even if the CPU becomes stuck.
2.1 How Does a Watchdog Timer Work?
A watchdog timer starts counting down from a predefined timeout value.
Before the counter reaches zero, the application must refresh the watchdog.
This operation is commonly known as:
- Feeding the watchdog
- Kicking the watchdog
- Petting the watchdog
- Refreshing the watchdog
Although different terms are used, they all mean the same thing: reloading the watchdog timer before it expires.
Each refresh resets the watchdog counter back to its initial value.
As long as the application continues refreshing the watchdog before the timeout expires, the watchdog assumes the software is operating correctly.
2.2 Who Refreshes the Watchdog?
A common misconception is that the watchdog somehow knows whether the software is healthy.
It does not.
The watchdog simply waits to be refreshed before its timeout expires.
It is the application software that periodically refreshes the watchdog, indicating that it is still making forward progress.
A typical embedded application might look like this:
int main(void)
{
watchdog_init();
while (1)
{
read_sensors();
process_data();
update_outputs();
transmit_data();
watchdog_refresh();
}
}
Each time watchdog_refresh() is called, the watchdog counter is reloaded to its maximum value.
2.3 What Happens If the Software Fails?
Suppose the application encounters a bug and becomes trapped in an infinite loop.
while (1)
{
read_sensors();
while (1)
{
/* Application is stuck here */
}
watchdog_refresh(); /* Never reached */
}
Since the application never reaches watchdog_refresh(), the watchdog continues counting down.
When the timeout expires, the watchdog assumes that the software has failed and generates a reset signal.
+----------------------+
| Application Running |
+----------+-----------+
|
Refresh Watchdog?
|
+----------+----------+
| |
Yes No
| |
▼ ▼
Reload Counter Counter Reaches Zero
| |
▼ ▼
Continue Execution Processor Reset
The processor then restarts and begins executing the application from its reset vector.
2.4 Refreshing the Watchdog Correctly
Simply refreshing the watchdog at fixed time intervals is not sufficient.
A watchdog should only be refreshed after the application has successfully completed all of its critical tasks.
If one of the critical tasks hangs, the watchdog should not be refreshed.
Read Sensors ✓
Process Data ✗ (stuck)
Update Outputs (never executed)
Refresh Watchdog (never executed)
The watchdog then times out naturally and resets the processor.
For this reason, experienced embedded developers often follow a simple rule:
Only refresh the watchdog when you know the system is healthy.
3. How Is a Watchdog Timer Used?
Although the implementation differs from one microcontroller to another, the basic workflow is very similar.
A watchdog timer is typically used in four steps:
- Configure the watchdog timeout.
- Enable the watchdog.
- Refresh the watchdog during normal execution.
- Allow the watchdog to reset the processor if the software stops responding.
3.1 Configure the Timeout
Before enabling the watchdog, the application selects an appropriate timeout period.
The timeout determines how long the watchdog waits before declaring that the software has failed.
Choosing the timeout requires careful consideration.
- A timeout that is too short may cause unnecessary resets during normal execution.
- A timeout that is too long delays recovery when the software genuinely fails.
The timeout should therefore be longer than the application's worst-case execution time, but short enough to detect failures quickly.
3.2 Enable the Watchdog
After the timeout has been configured, the watchdog is enabled.
Once enabled, it immediately begins counting down.
Enable Watchdog
│
▼
+----------------+
| Counter = 1000 |
+----------------+
│
▼
999 → 998 → 997 ...
On many microcontrollers, the watchdog is enabled during system initialization.
Some devices also allow the watchdog to be permanently enabled using configuration fuses or option bytes. In such systems, the watchdog starts automatically after every reset and cannot be disabled by software.
This ensures that the application is always protected against software failures.
3.3 Refresh the Watchdog
Once the watchdog is running, the application must periodically refresh it.
This is usually done after all critical tasks have completed successfully.
int main(void)
{
watchdog_init();
while (1)
{
read_sensors();
process_data();
update_outputs();
transmit_data();
watchdog_refresh();
}
}
Each call to watchdog_refresh() reloads the watchdog counter.
As long as the application continues refreshing the watchdog before the timeout expires, the watchdog never resets the processor.
3.4 Automatic Recovery
If the application crashes, deadlocks, or becomes trapped in an infinite loop, it eventually stops refreshing the watchdog.
The watchdog continues counting down independently.
Application Running
│
▼
Unexpected Failure
│
▼
No More Watchdog Refresh
│
▼
Counter Reaches Zero
│
▼
Watchdog Reset
│
▼
Processor Restarts
After the reset, the processor begins executing the application from its reset vector, just as it would after a power-on reset.
If the failure was temporary, the application resumes normal operation without requiring any human intervention.
3.5 Typical Watchdog Workflow
The overall operation of a watchdog timer can be summarized as follows.
Configure Timeout
│
▼
Enable Watchdog
│
▼
Application Starts
│
▼
Execute Critical Tasks
│
▼
Refresh Watchdog?
│ │
Yes No
│ │
▼ ▼
Reload Counter Timeout
│ │
└────┐ ▼
│ Processor Reset
└───────────────► Restart Application
Although using a watchdog timer is straightforward, using it correctly requires careful design. Refreshing the watchdog at the wrong time can prevent it from detecting real software failures.
4. Where Are Watchdog Timers Found?
Watchdog timers are found in a wide variety of computing systems, but they are most commonly associated with embedded systems, where they play a vital role in improving software reliability.
Today, nearly every modern microcontroller includes one or more hardware watchdog timers as standard peripherals.
Examples include:
- STM32
- Microchip PIC
- Atmel AVR
- MSP430
- Renesas RX
- ESP32
- NXP LPC series
- Infineon AURIX
Since the watchdog is implemented in hardware, it operates independently of the application software. Even if the processor becomes trapped in an infinite loop or the operating system stops responding, the watchdog continues counting toward its timeout.
4.1 Beyond Microcontrollers
Watchdog timers are not limited to microcontrollers.
They are also found in:
- Application processors
- System-on-Chip (SoC) devices
- Industrial computers
- Network equipment
- Server platforms
Although these systems may run complex operating systems, the fundamental principle remains the same.
The watchdog expects the supervising software to periodically refresh it. If the refresh stops, the watchdog assumes the system has failed and initiates a reset.
4.2 Why Are Watchdog Timers Primarily Associated with Embedded Systems?
Although watchdog timers are present in many computing platforms, they are most closely associated with embedded systems.
An embedded device typically runs a single firmware application or a small number of tightly coupled real-time tasks.
If that software stops executing, the entire device may become unresponsive.
Unlike desktop computers, embedded systems often operate:
- Without a keyboard
- Without a display
- Without a network connection
- Without an operator nearby
Many are expected to run continuously for months or even years without human intervention.
Examples include:
- Industrial controllers
- Automotive electronic control units (ECUs)
- Medical devices
- Consumer electronics
- IoT devices
- Smart energy meters
- Remote weather stations
- Aerospace and defense systems
For these applications, waiting for someone to manually restart the system is often impractical or impossible.
A watchdog timer provides an inexpensive and highly effective mechanism for automatically recovering from unexpected software failures, making it one of the most important reliability features in modern embedded systems.
5. Best Practices
Simply enabling a watchdog timer does not guarantee that a system can recover from software failures.
A poorly designed watchdog implementation may never detect real failures or may cause unnecessary system resets.
The following practices help ensure that the watchdog serves its intended purpose.
5.1 Refresh the Watchdog Only After Critical Tasks Complete
One of the most common mistakes is refreshing the watchdog simply because the main loop is still executing.
Instead, refresh it only after all critical operations have completed successfully.
If one of these operations hangs or fails, the watchdog should not be refreshed.
Read Sensors ✓
Process Data ✗ (Stuck)
Update Outputs
Transmit Data
No Watchdog Refresh
│
▼
Watchdog Timeout
This ensures that the watchdog reflects the health of the application rather than merely the execution of the main loop.
5.2 Choose an Appropriate Timeout
The timeout period should accommodate the application's worst-case execution time.
A timeout that is too short may cause unnecessary resets during legitimate long-running operations.
Conversely, an excessively long timeout delays recovery from genuine software failures.
The timeout should therefore balance responsiveness with normal execution requirements.
5.3 Keep the Refresh Logic Simple
Refreshing the watchdog should be a small, predictable operation.
Avoid placing unnecessary logic around the refresh call.
Good:
Poor:
The decision to refresh should always be based on the health of the application.
5.4 Monitor the Entire System
A watchdog should represent the health of the entire application, not just a single function or task.
For example, a system may consist of multiple activities.
If Task C stops executing while the others continue, blindly refreshing the watchdog may hide the failure.
The refresh should occur only after verifying that all critical components are operating as expected.
5.5 Record the Reset Cause
After a watchdog reset, valuable diagnostic information may be lost.
Whenever possible, the application should determine why the processor restarted.
Many microcontrollers provide reset-status registers that indicate whether the previous reset was caused by:
- Power-on reset
- External reset
- Brown-out reset
- Watchdog timeout
- Software reset
Recording this information can greatly simplify debugging intermittent failures.
5.6 Test the Watchdog
A watchdog should never be assumed to work simply because it has been enabled.
Deliberately create fault conditions during development.
Examples include:
- Enter an intentional infinite loop.
- Disable the watchdog refresh.
- Simulate a deadlock.
- Force a task to stop executing.
Verify that:
- The watchdog expires.
- The processor resets.
- The application restarts correctly.
- The system returns to normal operation.
A watchdog that has never been tested should not be relied upon in production.
5.7 Treat the Watchdog as a Recovery Mechanism
A watchdog timer does not prevent software bugs.
Instead, it provides an automatic recovery mechanism when those bugs prevent the application from operating normally.
It should complement, not replace good software engineering practices such as:
- Careful design
- Code reviews
- Static analysis
- Unit testing
- Integration testing
A reliable system aims to avoid failures, while the watchdog ensures the system can recover if a failure still occurs.
The next section discusses common watchdog pitfalls and mistakes that can make a watchdog ineffective.
6. Watchdog Pitfalls
A watchdog timer is only as effective as its implementation.
Many watchdog failures are not caused by the hardware itself, but by software that refreshes the watchdog incorrectly. In these situations, the watchdog continues to be serviced even though the application is no longer functioning correctly.
The following are some of the most common implementation mistakes.
6.1 Refreshing the Watchdog Unconditionally
One of the biggest mistakes is refreshing the watchdog every time the main loop executes, regardless of whether critical tasks have completed successfully.
If process_data() later becomes stuck, the watchdog may still be refreshed before the failure occurs, delaying or even preventing detection.
Instead, the watchdog should only be refreshed after all required tasks have completed successfully.
6.2 Refreshing the Watchdog from an Interrupt
Another common mistake is refreshing the watchdog inside a periodic interrupt.
Suppose the main application becomes trapped in an infinite loop.
Although the application has failed, the timer interrupt continues executing and repeatedly refreshes the watchdog.
As a result, the watchdog never expires, and the software remains permanently stuck.
A watchdog should normally be refreshed by the application logic whose health it is intended to monitor, not by an independent interrupt.
6.3 Refreshing Too Frequently
Some developers refresh the watchdog much more often than necessary.
This scatters watchdog servicing throughout the codebase, making it difficult to determine whether the system is genuinely healthy.
A single, well-defined refresh point is usually easier to understand, maintain, and verify.
6.4 Ignoring Long-Running Operations
Some operations legitimately require more time than usual.
Examples include:
- Flash memory programming
- Firmware updates
- Large file transfers
- Cryptographic calculations
- Complex signal processing
If these operations exceed the watchdog timeout, the processor may reset even though the software is operating correctly.
Possible solutions include:
- Selecting a longer timeout
- Refreshing the watchdog at carefully controlled checkpoints
- Temporarily using a different watchdog configuration (if supported by the hardware)
The chosen approach should ensure that the watchdog still detects genuine software failures.
6.5 Creating a Reset Loop
Sometimes the software repeatedly encounters the same fault immediately after every reboot.
Power On
│
▼
Application Starts
│
▼
Software Fault
│
▼
Watchdog Reset
│
└──────────────┐
▼
Application Starts
This results in a continuous reset loop.
If possible, the application should detect repeated watchdog resets and enter a safe or recovery mode instead of repeatedly executing the failing code.
6.6 Forgetting to Record the Reset Cause
After a watchdog reset, valuable diagnostic information may disappear.
If the application immediately starts running normally, developers may never know that a watchdog timeout occurred.
Many microcontrollers provide reset-status registers that allow firmware to determine why the processor restarted.
Recording this information during startup greatly simplifies debugging intermittent failures.
6.7 Assuming the Watchdog Solves Every Problem
A watchdog timer is not a substitute for robust software design.
It cannot:
- Prevent software bugs
- Detect incorrect calculations
- Repair corrupted data
- Recover unsaved application state
- Guarantee functional safety
Its purpose is much narrower:
Detect that normal software execution has stopped and automatically restart the processor.
When used correctly, a watchdog greatly improves system availability. When used incorrectly, it may provide a false sense of reliability while allowing serious software failures to remain undetected.
7. Alternatives and Complements
A watchdog timer is an effective recovery mechanism, but it is not the only technique for improving system reliability.
In many embedded systems, watchdogs are used alongside other hardware and software mechanisms that help detect faults, prevent failures, or place the system into a safe state before a reset becomes necessary.
7.1 Heartbeat Monitoring
In systems with multiple tasks or threads, each task can periodically report that it is still executing correctly.
This is commonly referred to as a heartbeat.
If one task stops reporting its heartbeat, the supervisor withholds the watchdog refresh, allowing the watchdog to reset the system.
This approach provides a much more accurate indication of overall system health than simply refreshing the watchdog from the main loop.
7.2 Windowed Watchdogs
Some microcontrollers provide a windowed watchdog instead of, or in addition to a standard watchdog.
A standard watchdog only requires the application to refresh the watchdog before the timeout expires.
A windowed watchdog introduces an additional rule:
- Refreshing too late causes a reset.
- Refreshing too early also causes a reset.
Time
│
├──────────────┬──────────────┬──────────────►
Too Early Valid Window Too Late
Reset Refresh Here Reset
This prevents software from continuously refreshing the watchdog inside a tight loop while the rest of the application has failed.
7.3 Brown-Out Detection
Not all system failures are caused by software.
A sudden drop in the supply voltage can cause the processor to execute incorrect instructions or corrupt memory.
To protect against this, many microcontrollers include Brown-Out Detection (BOD) or Brown-Out Reset (BOR) circuitry.
Unlike a watchdog, which monitors software execution, a brown-out detector monitors the stability of the power supply.
7.4 Error Detection Mechanisms
Many embedded systems continuously monitor for hardware and communication errors.
Examples include:
- Memory parity errors
- ECC (Error Correcting Code) memory
- CRC verification
- Communication timeouts
- Peripheral fault detection
These mechanisms detect faults that a watchdog cannot.
Depending on the severity of the error, the application may attempt recovery, enter a safe state, or deliberately stop refreshing the watchdog to trigger a system reset.
7.5 Safe-State Design
In safety-critical systems, an immediate reboot is not always the correct response.
The system may first need to place hardware into a known safe condition.
Examples include:
- Disabling motor outputs
- Closing fuel valves
- Activating emergency brakes
- Turning off high-power actuators
This ensures that hazardous outputs are placed in a safe condition before the processor restarts.
7.6 No Single Mechanism Is Sufficient
Each reliability mechanism addresses a different class of failures.
| Mechanism | Primary Purpose |
|---|---|
| Watchdog Timer | Recover from software hangs |
| Heartbeat Monitoring | Verify that critical tasks are still executing |
| Windowed Watchdog | Detect both missed and premature refreshes |
| Brown-Out Detection | Recover from unstable power supply |
| CRC / ECC / Parity | Detect data corruption |
| Safe-State Logic | Protect equipment and users during faults |
A robust embedded system combines several of these techniques rather than relying on any single mechanism.
The watchdog remains one of the most important components because it provides an automatic recovery path when software can no longer execute normally.
8. Summary
Watchdog timers are one of the simplest yet most effective mechanisms for improving the reliability of embedded systems.
They operate independently of the application software, continuously monitoring whether the firmware is still executing normally. As long as the application periodically refreshes the watchdog, the system continues running. If the software hangs, deadlocks, or enters an infinite loop, the watchdog eventually expires and automatically resets the processor.
Application Running
│
▼
Refresh Watchdog
│
▼
Continue Execution
OR
Software Failure
│
▼
No Refresh
│
▼
Watchdog Timeout
│
▼
Processor Reset
│
▼
Application Restarts
Throughout this article, we explored:
- Why embedded systems need watchdog timers.
- How hardware watchdog timers operate.
- How watchdogs are configured and refreshed.
- Where watchdog timers are commonly found.
- Best practices for implementing them correctly.
- Common mistakes that reduce their effectiveness.
- Related mechanisms that complement watchdog timers.
Perhaps the most important lesson is that a watchdog should only be refreshed when the application has demonstrated that it is healthy. Blindly servicing the watchdog defeats its purpose and may allow software failures to remain undetected indefinitely.
A watchdog timer is not a substitute for good software design, thorough testing, or careful fault handling. Instead, it serves as the system's final line of defense, providing an automatic recovery mechanism when unexpected software failures prevent normal program execution.
When implemented correctly, a watchdog can transform a system that requires manual intervention after every crash into one that detects failures, recovers automatically, and continues operating with minimal downtime.
Relevant Links
C/C++ Material on this website
(such as memory managment, pointers, embedded C programming etc.)