Hello,
In all of my past experiences with a watchdog timer, the behavioral model has been the following:
* Configure the watchdog to certain timeout period.
* Call a function to reset the watchdog more frequently than the timeout periond.
* If the watchdog is not reset before the timeout period, the processor is reset.
I would like to use the watchdog on my LM3S8962. But when I look at the Stellarisware watchdog example, I see that the "resetting" of the watchdog timer is done in an ISR. This does not seem like a good design to me. Among others, one of the failure modes that a watchdog protects against is a run-away loop, or some other dynamic stimuli that upsets the high-level timing of the code. If I have a nice, high-priority interrupt that resets the watchdog even though I am hopelessly stuck in a loop, what protection is the watchdog actually providing?
Utlimately, the main question, is the following:
Using the Stellarisware watchdog.c as a basis for my question, can I modify that code such that the watchdog is reset outside of the watchdog ISR? I don't care if I still have to register and install an ISR for the watchdog interrupt, I will just leave it empty.
Thanks
Kevin
Hello Kevin,
Yes, you can clear the Watchdog interrupt status bit outside of an ISR (in your main application loop for example). However, I would recommend continuing to use the WatchdogIntClear() method to perform this clear. You might also want to use the WatchdogLock() after your initialization is complete to avoid any stray accesses disabling the Watchdog function.
RE: watchdog ISR in the example
You can optionally leave the Watchdog interrupt disabled (don't call IntEnable(INT_WATCHDOG)) and thus not bother setting up an ISR. It won't impact the functionality if you are clearing the status elsewhere.
Mitch, Kevin,
I think it makes anyway sense to really use the interrupt routine associated with the watchdog. However, because of its unusual concept, I'd expect a more complete demo code resp. hints in the processor's datasheet.
Using an interrupt routine catches too long interrupt inhibit times or other related problems. That's okay. As Kevin points out, an additional mechanism is required to catch main program hang-up issues.
My solution: in a main application loop (top level), a variable wdtick is set regularly. Within the watchdog interrupt routine, handling is as follows:
if (wdtick) { wdtick = 0; WatchdogIntClear(WATCHDOG0_BASE);}
(however, it must be ensured that the interrupt is not blocking when the flag is not reset - any comments?)
I'm rather confused by this 'interrupt' implementation of watchdog. What does this prevent from happening or reset in a useful way?
- If the processor is stuck in an interrupt routine - then it will never reset.
- If the processor is stuck in a subloop of the main loop but still services the interrupt - then it will never reset.
- etc., etc. etc.
The idea behind a watchdog is supposed to be simple: Start watchdog. If no one resets the timer within the timeout period, reset the processor. Include a mechanism to pause the countdown for things like firmware updates, or high priority services.
The given watchdog example is useless - might as well have a button on the screen that just pulls reset low thru GPIO. Functionally it's the same. How does using the interrupt routine make sense here.. Can someone explain?
Todd, it looks like you've read the former postings a bit too much on the fly. To your complaints:
- if the processor is stuck in an interrupt routine, it will reset, because the watchdog is no longer triggered with watchdog refreshes
- if the mainloop is stuck in a subloop, my suggested variable wdtick is not set. Since the interrupt clears this variable, it will no longer trigger watchdog refreshes...
No I didn't read them on the fly. I read the documentation. - and your previous post wasn't clear : "..I think it makes anyway sense to really use the .." ..?
Nested interrupts and blocking could create a situation that the watchdog interrupt could continue to be serviced but we never return to other lower priority tasks, or ..a watchdog that is reset while interrupts are being serviced correctly..
This doesn't solve problems. It creates potential new ones.
Todd, thanks for your reply. I guess that there is some misunderstanding, either on my side or on yours. I'd appreciate it when the case becomes clear. Anybody will benefit from this. Well, what's going on, when a watchdog interrupt is serviced continually, but lower priority tasks, or the mainloop are blocking? In the latter case, 'my' interrupt routine will never call
WatchdogIntClear(WATCHDOG0_BASE)
Which will result in a watchdog reset. Indeed, when I have a blocking of my main loop, a processor reset occurs.
Rob, you say that you know that 'your' watchdog interrupt won't get called at the wrong time. What are you doing to 'your' interrupt such that you can ensure that it doesn't call at the wrong time?
You suggest that if you get stuck in a loop in your main routine that the watchdog will correctly recover your program (by NOT calling the watchdog interrupt). Wouldn't this only work if you had the foresight to turn interrupts off?
Kevin, please read the code snippet above. I'd suggest that this is self-explaining.
Rob,
I don't believe that your code will work as you describe. You say that your special interrupt will not be called. I was asking a follow up question of how you actually accomplish this special behavior. What characteristics and/or properties are you applying to your watchdog interrupt to ensure that it is not called when it should not be called. It sounds like your are saying the following:
"I will know ahead of time when my code will hit an unrecoverable error, from which only the watchdog timer can save me. So when I know that the unrecoverable error is about to occur, I first disable interrupts so that the watchdog timer will not reset once I hit the error."
If I have misunderstood your description of your design, could you please correct me?
In his code above, two things must happen to reset the watchdog timer.
The interrupt must occur, and the the flag must be set (by main line code).
So - if his code block disables the interrupt, the watchdog will time out and his device will reset. If his code goes stray, the main line code will stop executing, won't set the flag, and the interrupt code will see that the flag isn't set so will never reset the watchdog timer - so his device will reset.
Well, masterminds provide a more qualified insight then others?
As a corollary to slandrums contribution, I'd state that it is generally a good idea to refresh the watchdog timer as a result of logical ANDs of several important places where program code is going through cyclically. E.g. the variable wdtick as given in the example may have assigned individual bits which are set by program code, and in interrupt code, watchdog refresh is allowed only, when all assigned bits are set.
Ah, okay, I didn't see the code above that shows your algorithm. My appologies. So the interrupt will actually execute, but the contents of the ISR won't execute unless the code is working properly. I wouldn't choose that approach, but it does look like it will work.
"I'd state that it is generally a good idea to refresh the watchdog timer as a result of logical ANDs of several important places where program code is going through cyclically."
I agree very much.
Suspect that WD management further benefits - not just from logical And'ing of program flow events - but also from check/verify of key MCU frequencies, voltages, even pwm duties. 32 bit wide register(s) provide adequate room for added content - of course test & set must be quick/efficient. (or refreshed/tested only every n cycles)
Within reason - the greater the number of "key MCU areas" being properly monitored - the more robust your MCU system... Thanks to all early-on participants & slandrum for some keen insights. Believe that a better "mouse watch-trap" has emerged...
I am using the Concerto, vs the Stellaris, but I understand that the operation and behavior is consistent. I am trying to get WDT0 implemented to provide a work-around to another problem and have been testing both the watchdog example in V110 and V130 examples for the Master. The example do show that the system will reset. The problem is, the reset never quits! I have tried it with the interrupt as well as without (just putting WatchdogIntClear(WATCHDOG0_BASE); in my main task), but neither seems to stop the reset every 2 seconds. Even removing the return from the interrupt service routine had no effect.
Does anyone have any idea why this would occur?
Thanks,
Pat
An update. By eliminating the ISR, I can now get the watchdog example to work properly. However, when I try to apply the concept to my application, I have no success. Placing the WatchdogIntClear in my main task, stops the app from running. I also found that the NVIC statement (HWREG(NVIC_VTABLE) = 0x20005000;) seems to prevent operation as well. When everything else is enabled and the NVIC and Clear is removed, the app runs forever, never reseting, so apparently, the WDT is not actually running. I am using the f28m35h52c1 chip. Any help here would be greatly appreciated.