Infinite loops in memory Bus Fault tests
Article ID: 103490401
Published date: 24 Jul 2017
Last updated: -
Applies to: Cortex-M
Why does my memory Bus Fault test loop infinitely?
A Bus Fault is an Error signal returned to the processor from the bus interconnect, or from a selected slave device, in response to a requested bus transfer.
For normal operation, there are two likely outcomes of a Bus Fault:
The error is fatal. The operating system resets the system or terminates the current task.
The error is fixable. The exception handler corrects the problem and the bus access is attempted again after the return from exception.
When an exception occurs, the current execution context is automatically pushed onto the current stack and the exception vector is loaded to run the exception handler code.
The stacked context includes various items:
Link register (LR).
Combined program status register (xPSR).
Scratch registers (r0-r3, r12).
Program counter (PC), which allows the processor transparently to return to the interrupted code after the exception has been handled.
It is normal for the stacked PC to be the address of the faulting instruction, so this instruction will be executed again after the fault has been corrected.
If a test program causes a Bus Fault, but has no way of correcting the fault, it will continually return from the exception handler and re-execute the faulting instruction. This causes the fault to be triggered repeatedly.
There are at least two ways to overcome this situation:
The return address (the PC in the stacked context) can be modified so that the return from the exception handler is to the instruction following the opcode that caused the fault. This method is complicated by two issues.
The stacked context might be on either of two stacks if the Process Stack Pointer is in use. Therefore it is necessary to inspect the current LR in the exception handler to determine which stack contains the relevant stack frame.
It is then necessary to determine the size of the opcode that caused the fault, so the correct adjustment to the stacked PC can be made. This requires the use of the stacked PC to locate the faulting opcode, after which the opcode can be analyzed to determine the opcode size (16- or 32-bit).
A simpler approach is to allow the faulting memory access to repeat, but to modify the register that contains the base address for the access so that the repeated memory access will now be to a non-faulting location. If the base register is one of the stacked scratch registers, it will still be necessary to determine which stack contains the stack frame so that changes can be made to that register value. However, if a non-scratch register is used for the base register, the register value can be modified directly in the handler to influence the memory access after the return-from-exception. This is the simplest solution.