5 Registers
In this self-diagnostic routine, the CPU registers are tested for stuck bits and coupling faults between each of the bits inside the individual registers but not between registers. The basic algorithm works as follows: The content of the register is pushed to stack so it will be possible to restore the register after the test. The register is set to a known value and verified. Then the register bits are forced to change state, and the register content is verified once more.
If the content of the register is incorrect after either verification, the error flag is raised. When the test is done the register is restored with the original value pushed to the stack. Two types of registers will be tested: register file registers (R0-R31) and I/O registers. These are located in separate memory spaces and are accessed with different instructions.
The registers are tested in the following order (GCC compiler implementation):
- Return value registers: R24, R25.
- Auxiliary registers: R31, R30.
- Stack pointer: SPL, SPH.
- Status register: SREG (except interrupt flag).
- Registers: R0 to R23 and R25 to R29.
In the first three steps tests are performed on the registers that are critical for the self-diagnostic routine:
- Return value register: Used to deliver the result of this self-test.
- Auxiliary register 1, 2: Used to store the value of the registers that must be preserved.
- Stack pointer: Necessary to return to the main program.
- Status register: Flags used by CPU instructions.
The auxiliary registers are critical because they are required to test the stack pointer. If there is an error in these registers, the device will by default stay executing an infinite loop. However, it is possible to call the error handler instead.
In the last steps, the rest of the register file are tested. If there is an error, the self-diagnostic routine will call the error handler and return the value of the test. It is, however, recommended to configure the same behavior as with the critical registers, such that the device will hang in a loop if there is an error in any register. If any registers fail the test, continued code execution is in most cases not recommended.
The self-diagnostic code is written with assembler as it is simpler to do register manipulation in assembler code.
The example application turns LED 1 ON. The main program is an infinite loop running the test multiple times until an error is found. If an error is found the loop exit condition will be met and LED 1 will be turned OFF except if the error is in auxiliary registers.
In order to simulate an error, breakpoints can be set in the self-diagnostic routine. After the application stops at a breakpoint, the content of a register can be modified to simulate a stuck bit. The execution can then be resumed, and the self-diagnostic routine will detect the error.
Depending on the register that is modified, the CPU enters straight into an endless loop inside the self-diagnostic routine or the global error variable is set to one, which leads to switching the LED OFF and then entering an endless loop.
