In the last blog we looked at the private timers provided with each CPU in the Zynq All Programmable SoC. In this blog we will look at the Zynq SoC’s private watchdog timer, how you can use it, and we’ll look at an example of its use.
However, before we look at how we can configure and use the Zynq watchdog, I think it would be a good idea to explore why you might need a watchdog timer and how a watchdog works. Watchdogs address the inevitability of unresponsive software and provide a reliable solution to this problem. No matter what the end application, all engineers want to provide a reliable solution and good system designers know they must design for all eventualities.
A system-engineering team must undertake a number of steps to ensure a reliable design. The first step is to establish a requirements baseline that defines the behavior of the system and its software. The engineering team then implements these requirements, following a software life cycle that includes:
Generation of the design documentation
Software design and source coding
A validation strategy to verify that the requirements have been achieved
Most designs will include methods to ensure that the software can respond rationally to system faults. These faults can have one of two effects—either allowing the software to continue operation while maintaining either a full or reduced service or complete failure to respond. When the software fails to respond, a watchdog timer can either restart the system or ensure that the system fails safely. (The issue of safety critical systems and software is a complex one and would take more room than I have here to cover in detail here.)
In the very simplest sense a watchdog is a timer that counts down from a pre-loaded value. As the software application executes, it periodically resets the watchdog. Should the software fail to reset the watchdog, its count will reach zero and the watchdog circuit then resets the processor. When the software is operating normally, the watchdog count never reaches zero. If the software fails for some reason, then the watchdog is not reset, the count reaches zero, the processor is reset, and the software reboots. Many systems have a register with a bit that’s set when the watchdog triggers. This feature allows the system to come up back from the watchdog reset while noting the fact that the watchdog triggered the reset.
Each of the two ARM Cortex-A9 processors within the Zynq SoC has a private watchdog timer. These private watchdogs can be used as either a timer like the private timer (discussed in the previous blog post in this series) or as a watchdog. The Zynq watchdog timer is controlled via six registers:
Watchdog Load Register: Holds the value which the watchdog timer counts down from. In auto-reload mode, the watchdog counter resets to the value stored in this register. Writes to this register will result in the watchdog counter register being reset to this value.
Watchdog Counter Register: This is the watchdog counter itself. It’s decrementing counter. Depending upon the watchdog mode, writing to this register reloads the counter. In watchdog mode, this register can only be updated by writing to the Watchdog Load Register.
Watchdog Control Register: This register controls the configuration of the watchdog (timer or watchdog), the pre-scaler setting, the interrupt enable, auto-reload mode, and the enabling of the watchdog in its currently configured mode.
Watchdog Interrupt Status Register: Contains a single event flag that shows when the counter has reached zero. Writing to this register resets it.
Watchdog Reset Status Register: This register contains a single bit that is only cleared by power-on reset (not a watchdog-triggered reset). It can also be cleared by a software application. The reset status bit allows the software to determine whether or not the reason for a reboot was caused by a watchdog timeout.
Watchdog Disable Register: This register requires two specific patterns to be written to it to enable the watchdog mode bit within the Watchdog Control Register when the watchdog is set to timer mode.
As we saw with the Zynq SoC’s private timer, the Zynq software-development environment provides a number of functions and macros that you can use to configure and drive the watchdog. These are included within
This file enables the facilities to:
Test if the watchdog has expired
Load the watchdog
Start, stop, and restart the watchdog
Set the watchdog mode
Configure and initialize the watchdog
The following example configures the watchdog to operate as a traditional watchdog with no refresh so that the watchdog resets the Zynq SoC when it times out. The example code then checks to determine the cause of the reset following a watchdog reset (e.g. power-on reset or watchdog timeout) and reports this over STDOUT. Pressing the pushbutton starts the private timer, illuminates the LED, and starts the watchdog.
To do all of this, we follow a standard approach of configuring the watchdog as we have done for all of the peripherals to date using the data from xparameters.h and the configuration routines:
Following initialization and loading of the watchdog, the next steps are to enable the interrupt (within the interrupt configuration function) and to set the watchdog to the watchdog function as opposed to the timer function using the XScuWdt_SetWdMode() function: