Geeks With Blogs
Windows Embedded Annotations
Beware of the watchdog!
Introduction
 
A watchdog timer (WDT) is a timer that is able to reset a system when it elapses, recovering a hung system: resetting a system is not exactly what would you call recovering but sometimes it’s the only option. The timer must be refreshed (or fed) periodically by software to avoid the reset: if the software is not able to do it, probably the software itself is hanging so resetting the system will unblock the situation.
 
Most embedded processors and microcontrollers have an integrated WDT while some Super I/O chips implement watchdog for processors that do not integrate one.
Watchdog support in Windows Embedded CE
 
Windows CE kernel supports by default software watchdog timers: a thread can create a WDT using the CreateWatchDogTimer function. The function has several parameters but the most significant are:
 
  • The timeout value
  • The action the kernel will take when the timeout expires (kill the process which owns the WDT, reset the system or no action at all)
 
Note that the kernel will use IOCTL_HAL_REBOOT to reset the system so the OAL must implement it for the watchdog to actually trigger a reset.
 
CreateWatchDogTimer returns a handle that you can pass to other functions:
 
 
You can take a look at the kernel watchdog code if you installed the shared source code (%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\NK\KERNEL\watchdog.c)
 
If  the device has a hardware WDT the OEM can support it through the following OAL global variables:
 
  • pfnRefreshWatchDog: this is a pointer to a function which is called by the kernel to refresh the hardware watchdog. The default value for pfnRefreshWatchDog is NULL, which indicates that there is a watchdog timer does not exist.
  • dwWatchDogPeriod: this variable specifies the watchdog period, in milliseconds, where the hardware watchdog must be refreshed before system reset. The default value for dwWatchDogPeriod is 0, which indicates that there is a watchdog timer does not exist.
  • dwWatchDogThreadPriority: this variable specifies the kernel watchdog thread priority. The default value of dwWatchDogThreadPriority is DEFAULT_WATCHDOG_PRIORITY, which is equal to 100.
 
The kernel watchdog thread will call pfnRefreshWatchDog every dwWatchDogPeriod milliseconds refershing the timer thus avoiding the system reset. If you have a hardware watchdog you can recover the system in two critical situations: a critical thread hangs (the software WDT will trigger); the kernel hangs (the hardware WDT will trigger).
 
Take in account that having the hardware WDT enabled and breaking into the debugger will probably hurt you…
 
Attached to this post you can find a sample application that create a WDT, refresh it for some time than stops doing it resetting the system. Thanks to my collegue Lorenzo Bertolissi that coded it
 
Posted on Tuesday, March 17, 2009 10:04 PM Windows CE | Back to top


Comments on this post: Beware of the watchog!

# re: Beware of the watchog!
Requesting Gravatar...
Ciao Luca,
you provided a great description of this useful but sometimes dangerous feature of CE.
I would add also a note about external watchdogs.
As you said when you debug the OS using platform builder and break the system everything inside the OS is stopped and so the watchdog will trigger. On some devices you may have a watchdog that is not controlled by the CPU and so you can't stop it using software operations (I had to work on a board using one of them!) and so you will have to care that the people that design the hardware provide some hardware mechanism (a jumper or, most commonly, a resistor that should be de-soldered) to disconnect that kind of watchdog from the reset logic of your board or you will have a device that can't be debugged or, at least, that will make debugging a very painful process.
Luckily the designers of the board where I discovered that kink of watchdogs were quite smart and did not forget that feature during design!
Left by Valter Minute on Mar 18, 2009 12:46 AM

Your comment:
 (will show your gravatar)


Copyright © Luca Calligaris | Powered by: GeeksWithBlogs.net