5.5.23 · D3Embedded Systems & Real-Time Software

Worked examples — Watchdog timers — purpose, feeding, types

3,288 words15 min readBack to topic

This page is the "no case left behind" companion to the parent watchdog note. Before we begin, let us re-earn the one formula that everything below leans on, so no symbol arrives unexplained.

Figure 1 turns this into a picture: watch the blue line ramp down from , and see each yellow dot snap it back to the top — that snap is a "feed". The red dashed line at zero is where a reset fires.

Figure — Watchdog timers — purpose, feeding, types

The scenario matrix

Every question a watchdog topic can throw at you lives in one of these cells. The examples afterward each announce which cell they fill.

Cell Case class What is being tested
A Plain timeout, given all values Direct use of the formula
B Solve backwards for the prescaler Pick to hit a target
C 8-bit vs 16-bit counter (small ) Effect of counter width
D Zero / degenerate input (, or "never fed") Limiting behaviour, sanity edges
E Feed-margin: does the loop finish in time? Worst-case loop timing
F Too-late fault (a hang) Regular WDT catches slow/frozen code
G Too-early fault (window WDT) Window WDT catches fast/runaway code
H Real-world word problem Choosing timeout for a real device
I Exam twist (interrupt storm looks "healthy") Why a window is needed

Worked examples

Example 1 — Cell A: plain timeout

Forecast: guess first — will it be milliseconds, seconds, or minutes? Jot it down.

  1. Write in Hz. . Why this step? The formula needs pulses-per-second, and "k" hides a factor of ; keeping units clean prevents 1000× errors.
  2. Plug in. (recall ). Why this step? Direct application — every symbol is known.
  3. Arithmetic. s per full count at ; times gives s. Why this step? Splitting it shows the middle number ( s) is the "no-prescaler" timeout, which we reuse later.

Verify: Units — . ✓ Order of magnitude: tens of seconds, matching the parent note's number for .


Example 2 — Cell B: solve backwards for the prescaler

Forecast: guess whether you need a small or large .

  1. Rearrange the formula for . From , isolate . Why this step? We know the answer and want the knob — so put alone.
  2. Plug the target. . Why this step? This ideal is what you'd need if prescalers were continuous.
  3. Snap to the fixed menu. is nearest to . Why this step? Hardware only offers the discrete menu defined above; you must round to a value that physically exists.
  4. Check the real timeout at . . Why this step? The delivered timeout, not the ideal one, is what actually protects you.

Verify: is within of the target — the closest any menu prescaler gets. ✓


Example 3 — Cell C: 8-bit vs 16-bit counter

Forecast: will the 8-bit version be shorter or longer, and by roughly what factor?

  1. 8-bit timeout. . Why this step? Direct formula with the small .
  2. 16-bit timeout, same knobs. . Why this step? Isolate the only thing that changed — the counter width.
  3. Ratio. . Why this step? Shows counter width scales timeout linearly — a wider counter buys hundreds of times more patience.

Verify: exactly (since ). ✓ A narrow counter forces you to either feed very often or use a huge prescaler.


Example 4 — Cell D: degenerate inputs & limits

Forecast: guess the shortest timeout and what happens if you never feed.

  1. is the no-divide limit. . Why this step? passes every clock pulse — no slowing — so it is the floor of the timeout range for this hardware.
  2. Interpret "never fed". The counter simply runs once, uninterrupted, then triggers a reset. Why this step? A watchdog that is enabled but never fed is guaranteed to fire after exactly one timeout — this is the dead-man's-switch limit.
  3. Degenerate case ? Illegal — no such prescaler exists on the menu; dividing clock by is meaningless. Why this step? Cover the invalid input so the reader never expects it. Hardware simply won't offer .

Verify: Shortest timeout equals the row of Example 1's split. ✓ Consistency across examples confirms the formula.


Example 5 — Cell E: feed-margin timing

Forecast: guess the margin in ms, then guess yes/no for the doubling.

  1. Worst-case time between feeds = full loop. . Why this step? Because we feed only after the loop (see the parent's [!mistake] on feeding too early), the gap between two feeds is one whole loop.
  2. Margin. . Why this step? Margin is the slack before a legitimate slow loop trips the dog. Positive margin = safe.
  3. Answer the doubling question directly. Double the task → new loop . Compare to timeout: , so yes, it is still safe, with a new margin of . Why this step? The question asked a specific 2× scenario, so we compute that exact case rather than a general bound.
  4. How far could that task grow before trouble? The fixed tasks eat , leaving for the middle task — so it could grow from up to (a 4× blow-up) before touching the timeout edge. Why this step? Frames the 2× answer inside the full safe range, so the reader sees both the specific case and its headroom.

Figure 2 shows this as a bar: the blue chunk is the loop, the green chunk is the margin, and the red dashed line is the timeout the two together must not cross.

Figure — Watchdog timers — purpose, feeding, types

Verify: ✓. Doubled loop → safe ✓. Max middle-task length ✓.


Example 6 — Cell F: a "too-late" fault (a hang)

Let = the time of the last successful feed (the last moment the counter was reloaded to ). Every timing below is measured from .

Forecast: guess how many ms after the hang starts the reset happens.

  1. Last good feed. Iteration 6 finished and fed at . The counter reloads to . Why this step? The reset clock starts from the last successful feed , not from the hang.
  2. Counter free-runs. With no more feeds, the counter marches , taking the full . Why this step? A hang = feeding stopped = the never-fed limit of Example 4 kicks in.
  3. Reset instant. Reset fires at . The dead time (from hang start, which is after ) is at most . Why this step? Gives the guaranteed upper bound on downtime — the number a safety engineer cares about.

Figure 3: the green vertical lines are healthy feeds up to ; the red band is the hang with no feeds; the red dashed line marks the reset at .

Figure — Watchdog timers — purpose, feeding, types

Verify: Dead time ✓. If the hang starts right after a feed, worst-case downtime = ; if late in the loop, less. The dog always recovers within one timeout.


Example 7 — Cell G: a "too-early" fault (window watchdog)

A window watchdog accepts a feed only inside a time window. Define, measured since the previous feed:

  • — the earliest legal feed time. Feeding before is a fault (code running too fast).
  • — the latest legal feed time. Feeding after is a fault (code hung, like a plain dog).
  • — the actual time, since the last feed, at which this feed occurs.

The rule is . In this example the hardware is set so and .

Forecast: legal or reset? And which bound is violated?

  1. Compare against the lower bound. , and . Since , we feed too early. Why this step? A window watchdog has two comparators; the early feed fails the "not before " test.
  2. Result. Feeding before is treated as a fault → reset. Why this step? The whole point of the lower bound: code running too fast (an interrupt storm, a runaway loop) is as broken as code frozen.
  3. Why a plain watchdog misses it. A plain dog only checks . Since , it would happily accept the fast feed and see "healthy". No upper-only dog can detect early. Why this step? Names exactly the gap the window fills — a regular WDT has no lower bound at all.

Figure 4 shades the timeline into three zones since the last feed: a red "too early" zone below , a green "OK window" between the bounds, and a red "too late" zone above . The yellow dot at lands in the red early zone.

Figure — Watchdog timers — purpose, feeding, types

Verify: → out of window → reset ✓. A plain dog with only : → accepted, bug hidden ✓ (proving the window is necessary).


Example 8 — Cell G/D limit: right on the boundary

Forecast: are the endpoints inside or outside?

  1. Interpret strict inequalities. The bounds are strict (, not ): the open interval . Why this step? Boundary behaviour is a classic degenerate case — "exactly on the edge" must be pinned down.
  2. Test each. : fails (). : safe (). : fails (). Why this step? Applies the two comparators literally at the edges.
  3. Design lesson. Aim for the centre (), never the edge, so clock jitter of a few ms can't push you out. Why this step? Real clocks drift; margin on both sides is the safe target.

Verify: Only satisfies ✓; both endpoints are excluded by the strict inequalities ✓.


Example 9 — Cell H: real-world word problem

Forecast: guess which menu prescaler wins.

  1. Set the requirement. Need (one cycle) with slack for the transmit — target roughly : long enough to never false-trip, short enough to recover quickly. Why this step? The timeout must exceed the longest legitimate time between feeds, or valid long operations trip false resets.
  2. Compute the base () timeout once. . Why this step? Every menu value is just this base scaled by , so computing it once lets us read off all others by multiplying.
  3. Scan the menu by multiplying by .
    • : — smaller than the transmit → false resets. Reject.
    • : — comfortably above and above ; recovers in a sane time. Accept.
    • : — over two minutes to recover from a hang; needlessly slow. Reject. Why this step? Walking the menu shows is the smallest prescaler that clears both legitimate operations, giving the fastest safe recovery.
  4. State the chosen timeout. With : . Why this step? The final deliverable — the number you actually program into the device.

Verify: gives ✓ and transmit ✓; gives → correctly rejected ✓; gives , over-long ✓. See Fault Tolerance and Safe State Design for what the device should do after such a reset.


Example 10 — Cell I: the exam twist (interrupt storm "looks healthy")

Forecast: guess the feed count in .

  1. Count feeds. One feed per , so in an span: feeds. Why this step? Frequency of feeding tells us how the dog "sees" system health.
  2. Why it looks healthy to a plain dog. Each feed happens well before , so the counter never reaches zero. The plain dog reports "alive" — even though the timing is too fast. Why this step? Exposes the blind spot: a plain dog answers "is it running?" not "is it running at the right rate?"
  3. Window dog reaction. With window (so ), a feed at violates the lower bound () → reset on the very first fast feed, forcing you to find the timing bug. Why this step? Directly contrasts the two watchdog types on the exact failure a regular dog cannot see. This is the "why windows exist" punchline.
  4. Resolution. The system reboots on the storm, enters its safe state, and the developer sees a reset traceable to the too-early feed — the timing bug is now visible and fixable rather than silently corrupting behaviour. This is precisely the case a plain watchdog would have masked; see also Real-Time Operating Systems where feed timing is scheduled per task. Why this step? Closes the scenario: not just "reset happens" but "the bug becomes diagnosable", which is the whole payoff of Cell I.

Verify: feeds ✓; → window dog resets ✓; → plain dog accepts, bug hidden ✓.


Recall Quick self-test

Timeout for , , ? ::: Smallest menu prescaler to get near at , 16-bit? ::: , giving Ratio of 16-bit to 8-bit timeout at equal clock and prescaler? ::: exactly Worst-case downtime for a hang with a dog? ::: (one full timeout) If the middle task doubles to under a dog, safe? ::: yes — loop becomes Which watchdog catches a feed that comes too early? ::: the window watchdog (lower bound ) Feeds in if an ISR feeds every ? ::: — and a plain dog sees it as "healthy"