I'm using IAR to debug my application that is running on STM32F4 uC and I get a UsageFault exception where the INVSTATE=1 in CFSR register. in the Debug Log I get the following messages: UsageFault, attempt to execute an instruction when EPSR.T==0
after reading a bit I understand that the LR register should contain the address of the command that caused the fault, however, LR register contains 0xFFFFFFF1!!
my question is: how can I get the address of the command that caused the fault?
You have to expand a stack to get correct LR value, please try the following function:
void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress ) {
/* pulFaultStackAddress: {r0, r1, r2, r3, r12, lr, pc, psr } */
/* These are volatile to try and prevent the compiler/linker optimising them
away as the variables never actually get used. If the debugger won't show the
values of the variables, make them global my moving their declaration outside
of this function. */
volatile uint32_t lr; /* Link register. */
volatile uint32_t pc; /* Program counter. */
volatile uint32_t psr;/* Program status register. */
lr = pulFaultStackAddress[ 5 ];
pc = pulFaultStackAddress[ 6 ];
psr = pulFaultStackAddress[ 7 ];
for(;;)
}
void HardFault_Handler(void) {
__asm volatile
(
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" ldr r1, [r0, #24] \n"
" b prvGetRegistersFromStack \n"
);
}
When you get LR you will possible found function where occur exception. Use disposable windows to get code location.
Usually, this happens when user code leave bounds of the array or using not initialized data pointer
User contributions licensed under CC BY-SA 3.0