6 Program Counter
The program counter is tested using the watchdog timer (WDT) for indirect time-slot monitoring of the application.
The WDT is a system function for monitoring correct program operation that allows recovering from error situations such as runaway or deadlocked code. The WDT is a timer clocked independently from the CPU. It is configured to a predefined timeout period and is constantly running when enabled.
If the WDT is not reset within the timeout period, it will issue a system reset. Resetting the WDT is done by executing the WDT reset instruction (WDR) from the application code. In addition, the WDT in the tinyAVR® 1-series has a window mode. This makes it possible to define a time slot or window inside the total timeout period during which the WDT must be reset. If the WDT is reset outside this window, either too early (window is closed) or too late, a system reset will be issued. Compared to the normal mode, this can also catch situations where an error causes constant execution of the WDT reset instruction. Therefore, it is required that the Class B software uses the window mode and that the closed period is at least 50% of the total period.
The WDT will run in active mode and all sleep modes if enabled. It is asynchronous, running from a CPU-independent clock source, and it will continue to operate and issue a system reset even if the main clocks fail.
There is a configuration change protection mechanism in the tinyAVR® 1-series that ensures that WDT settings cannot be changed by accident.
Since the WDT is an integral safety feature in the tinyAVR® 1-series, a self-diagnostic routine that tests this module in normal and window mode has been designed. These tests are executed after reset in the pre-init section of the application, before the main function. A flow diagram of the test is shown in Figure 6-1.
The self-diagnostic routine verifies that:
- System reset is issued after WDT timeout in both normal and window mode
- WDT can be reset using the WDR instruction in both normal and window mode
- The device is reset upon untimely WDT reset in window mode
The flow diagram shows that the device is reset a number of times during the WDT test. An SRAM variable and the reset flags of the device are used by the self-diagnostic routine to keep track of the test phase. The user can configure what to do in the event of brown-out or software reset, or how to process a reset caused by the watchdog when the test is in the 'WDT_OK' state.
The self-diagnostic routine uses Timer Counter A (TCA) in order to check the timing of the WDT oscillator. TCA has a clock source independent of the WDT clock. TCA is used to estimate the period of the WDT, and the program checks that this estimate is within the interval (T/2, T3/2), where T is the nominal period of the WDT. The TCA is clocked from the system clock. The system clock is typically the internal 20 MHz clock. This clock is more stable over temperature and voltage drift than the clock used by the WDT.
The expected (error-free) execution flow is as follows:
- After power-on or external reset, check that WDT can issue a system reset: Set test state to 'WDT_1' and let the system be reset by a WDT timeout.
- Check that WDT can be reset: Set the test state to 'WDT_2' and reset the WDT before it times out.
- Check that window mode works correctly: Change the WDT to window mode. First, wait for the window to be open and reset the WDT before timeout. Then, change the state to 'WDT_3' and issue a reset when the window is closed. This should result in a system reset.
- Set test state to 'WDT_4' and let the system be reset by a WDT timeout while configured in window mode.
- Set up WDT according to application settings. Set test state to 'WDT_OK' and continue to the main function.
The first step is to make sure that the WDT can issue a system reset. This is done by setting up the WDT and wait until it issues a system reset. In addition, the TCA is used to estimate the watchdog period, which is required in later phases of the test. This is done by configuring the TCA with a small period (approx. 1 ms) and counting the number of TCA-periods until a system reset. If the program is left waiting for the system reset for longer than the theoretical maximum timeout period, the error state is set.
The second step is to make sure that the WDT can be reset, and to check the timing of the WDT. The error state is set. The test state will be in the error state until this step of the test is done. A check is performed to see that the estimated WDT period is higher or equal to the theoretical minimum. Checking that the difference in frequency between the WDT and TCA is within an interval provides confidence that both modules are working as expected. Next, the WDT is set up, and TCA is set to wait for approximately ¾ of the WDT period - WDT synchronization delay. This checks that the WDT does not expire earlier than expected. Then the WDT is reset and the program, once again, waits ¾ of the period to issue a new WDT reset. The reason for this is that if there was any problem in the mechanism that resets the WDT, there would be a system reset while the program is waiting for the second time. An early system reset would leave the test in the error state. After the WDT reset is verified, the test state is set to 'WDT_2' and the program waits for the WDT to time out and issue a system reset. An error is issued if TCA is left counting too long.
The third step checks that the WDT works correctly in window mode. This consists of configuring the WDT in window mode and wait until the WDT is in the open window before issuing a WDT reset. If the WDT were in the open window only, the WDT will be reset and not the entire device. If the device was reset at this point, it will be detected when it starts back up. The program continues, and the WDT is now back in the closed window after WDT reset. The test state is set to 'WDT_3', and a reset of the WDT is performed while in the closed window. When the window is closed, the WDT should issue a system reset. If a system reset does not occur, the error state is set.
In the fourth step, the WDT is again configured in window mode and left running. If the WDT operates as expected, it will get a timeout after passing the closed and open window and perform a system reset. If a system reset does not occur within a reasonable time, an error state is set.
In the fifth and final step, the program simply sets up the WDT in window mode and sets the 'WDT_OK' state. Note that after this, the main application is responsible for resetting the WDT according to the configured settings.
If the test sets the error state, a user-configurable error handler can be called. By default, the device will stay executing an infinite loop. This is considered to be the safest option as a working WDT is crucial for a reliable software application.
The counter and the test state variables are declared so that the compiler does not initialize them after reset. This way, they can be used across resets. The tinyAVR® 1-series has a register that stores the reset cause, which is used to decide whether it is the first iteration of the test.
The demo application sets up an interrupt for a button, switches an LED ON, and
stays in a loop where the WDT is reset as long as the variable
classb_error
is not set. If this variable is set, then the LED is
turned OFF, and the application ends.
When the button is pressed, the program stops resetting the WDT, which leads to a
WDT timeout and, therefore, a system reset. This ‘unexpected’ system reset should be
caught by the self-diagnostic routine, which in this demo is configured to set the
variable classb_error
, set up the WDT, and continue to the main
application. After pressing the button, the LED will be switched OFF, and the
application will not be responsive until a power-on reset, or external reset.