1

In an embedded system, I require a watchdog to be able to pass ESD qualifications. Having no experience with watchdogs, I went through this Memfault article. I liked the events "registration" and "flags" since it easily allows us to do conditional ORing of events depending on the system's state. Plus it feels scalable.

For the feeding part, here's what I put in place:

/** @brief Raise the event flag and feed the watchdog if all required event flags are set. * * @param[in] event_flag Bitmask corresponding to the triggering event. */ static void watchdog_feed_if_all_events_set(watchdog_event_t event_flag) { /* Declare as volatile since this function could be called from concurrent ISRs. */ static volatile watchdog_event_t watchdog_fed_events; enter_critical(); watchdog_fed_events |= event_flag; if ((watchdog_fed_events & watchdog_required_events) == watchdog_required_events) { bsp_watchdog_feed(); watchdog_fed_events = 0; } exit_critical(); } 

This function can then be called from any part of the application, including from ISRs.

Now for the question:

I was told it was senseless to feed a watchdog from an ISR and that a redesign is required, but no rationale was provided. I see nothing wrong with my implementation and it works just fine. I feel like a watchdog design is closely related/dependent to the system on which it is implemented and that there are no one-size-fits-all designs.

Am I missing something? Why would someone want to avoid feeding a watchdog from an ISR?

0

3 Answers 3

4

The goal of a watchdog is to intervene (with a reboot typically) if your software enters into a faulty state where it stops fulfilling the requirements.

If you expect events from different parts of the software before feeding the watchdog, that is a good design. It is probably one of the better designs for checking that the entire system is still functioning.

The advise not to feed the watchdog from an ISR is probably based on the concept of using a single (dedicated) timer ISR to feed the watchdog. In that scenario, everything but the high-priority ISR could be blocked on an endless loop and the watchdog would never intervene.

1
  • Thank you, your answer helps me better understand the bigger picture and the typical expectations for a watchdog. Commented Dec 17, 2024 at 15:29
0

The purpose of a watchdog is to reboot your system if the main loop has become unresponsive. In this situation, timer ISRs still run. So you will falsely tell the watchdog that everything is OK when it isn't.

5
  • What if the main loop runs but an interrupt driven IC is faulty and cease to function? It is as much a failure as if the main loop would become unresponsive. You're saying that a watchdog shouldn't be used for this purpose? Commented Dec 17, 2024 at 13:54
  • I'm saying that's why you got told "it was senseless to feed a watchdog from an ISR"; the normal use covers the "main" execution against software issues. Crucially, you can only feed it from one place, so if you're doing it from the ISR you can't do it from main() Commented Dec 17, 2024 at 14:04
  • Sorry for my ignorance, but why could I not conditionally feed it from multiple places? Commented Dec 17, 2024 at 14:06
  • 3
    @DarkFranX, a typical design it to feed the watchdog unconditionally from a context that runs with a low enough priority that a fault in any other "task" would cause a delay in execution and hence a delay in feeding the watchdog. That doesn't mean the typical implementation is the only possible one. Commented Dec 17, 2024 at 14:27
  • Feeding the watchdog from multiple places is an "or". It keeps working if any of them are working. Commented Dec 18, 2024 at 10:30
0

Is Feeding a Watchdog Timer from an Interrupt Service Routine a Bad Practice?

I have used this ISR watchdog kick quite successfully with a paired watchdog signal from the main job loop.

Detail:

  1. A low(est) priority periodic ISR (e.g. some timer), sets the watchdog signal high. Then one can be confident that the ISR priority level is not stuck high.

  2. Main foreground job loop (some low priority task) sets the watchdog signal low.

So if either the lowly ISR is starved or main job loop never gets to its most menial task, the watchdog timeout will fire as both up and down transitions are needed to keep the watchdog timer quiet.

Tip: If your system desires a user driven re-start, simple execute an endless loop:

disable_all_interrupts(); // Maybe this too. while(1); // Loop forever. 

which will effect a watchdog timeout. This also serves as a test for the watchdog system.
We have to test it somehow, right?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.