Resolving Hard Fault with STM32F407
I've been working on debugging a hard fault occuring on an STM32F4-discovery board.
For context, I'm working with a custom USB library which is used to communicate with an Android device in Accessory mode (this code uses usbh_core, etc and is similar to the usbh_cdc code) and also using a fatfs library to read/write to an SD card. The hard fault occurs when I unplug or replug in my USB connection.
There is way too much code to share, but the issue is more how to debug the hard fault than anything else. I've tried outputting the stack and key variables in the stack, as well as use_Unwind_Backtrace, without any real luck.
Here is what the hard fault handler outputs:
SCB->HFSR = 0x40000000
SCB->CFSR = 0x00008200
SCB->BFAR = 0x20020ae8
SCB->MMFAR = 0x20020ae8
MSP = 0x2001fdc0
PSP = 0x00000000Here are the first 8 values in the stack
R0 = 0x00000000
R1 = 0x2001fdc0
R2 = 0x2000c938
R3 = 0x20020adc
R12 = 0x2000cd38
LR = 0xfffffff9
PC = 0x20000adc
PSR = 0x00000001Here is the output of the backtrace:
Backtrace:
#0: program counter at 080e989c
#1: program counter at 080e999c With this as the relevant info from the .MAP file
.text 0x080e9744 0xc30 obj//04-ProgramCode/Errors/Programming.o
0x080e9838 trace_fcn
0x080e9888 print_backtrace_here
0x080e98a8 RebootToBootloader
0x080e9974 discoveryIgnoreHandler
0x080e997c discoveryIgnore2Handler
0x080e9984 discoveryDMAHandler
0x080e998c discoveryHARD_FAULTHandler
0x080e9e54 discoveryMPU_FAULTHandler
.data.impure_data
0x20000678 0x428 C:\Progra~1\SCICOS~1.1\contrib\E4coder\E4CODE~1\sdk\DISCOV~1\GNU_TO~1/arm-none-eabi/lib/thumb\libc.a(lib_a-impure.o)
.data._impure_ptr
0x20000aa0 0x4 C:\Progra~1\SCICOS~1.1\contrib\E4coder\E4CODE~1\sdk\DISCOV~1\GNU_TO~1/arm-none-eabi/lib/thumb\libc.a(lib_a-impure.o)
0x20000aa0 _impure_ptr
.data 0x20000aa4 0x0 C:\Progra~1\SCICOS~1.1\contrib\E4coder\E4CODE~1\sdk\DISCOV~1\GNU_TO~1/arm-none-eabi/lib/thumb\libc.a(lib_a-init.o)
.data 0x20000aa4 0x0 C:\Progra~1\SCICOS~1.1\contrib\E4coder\E4CODE~1\sdk\DISCOV~1\GNU_TO~1/arm-none-eabi/lib/thumb\libc.a(lib_a-malloc.o)
.data 0x20000aa4 0x0 C:\Progra~1\SCICOS~1.1\contrib\E4coder\E4CODE~1\sdk\DISCOV~1\GNU_TO~1/arm-none-eabi/lib/thumb\libc.a(lib_a-mallocr.o)
.data.__malloc_av_
0x20000aa4 0x408 C:\Progra~1\SCICOS~1.1\contrib\E4coder\E4CODE~1\sdk\DISCOV~1\GNU_TO~1/arm-none-eabi/lib/thumb\libc.a(lib_a-mallocr.o)
0x20000aa4 __malloc_av_
.data.__malloc_trim_threshold
0x20000eac 0x4 C:\Progra~1\SCICOS~1.1\contrib\E4coder\E4CODE~1\sdk\DISCOV~1\GNU_TO~1/arm-none-eabi/lib/thumb\libc.a(lib_a-mallocr.o)
0x20000eac __malloc_trim_thresholdThe code for my backtrace is something I found on stack exchange:
_Unwind_Reason_Code trace_fcn(_Unwind_Context *ctx, void *d)
{
int *depth = (int*)d;
char msg[80];
sprintf(msg,"\t#%d: program counter at %08x\n", *depth, _Unwind_GetIP(ctx));
SendAsyncPriority(msg);
(*depth)++;
return _URC_NO_REASON;
}
void print_backtrace_here()
{
int depth = 0;
_Unwind_Backtrace(&trace_fcn, &depth);
}As you can see, the HFSR and CFSR are indicating that the BFAR value is accurate (I disable the SCnSC->ACTLR write buffer to ensure it is), but the BFAR value is a RAM-style address, not an address in program memory (as I normally have seen). However, the RAM only goes to 0x20020000, so this is pointing beyond my stack.
I'm guessing that somewhere, I'm loading a stack value, addressing somewhere beyond this value, then trying to access it as a function or something, but I have no idea how I could be doing that in my code, and no clue as to what part of my code might be doing that.
Any suggestions on how to debug this would be really useful. I'm thinking that getting a functional backtrace would give me a clue as to what section of code is causing this issue, but for whatever reason the backtrace is clearing at the hard fault handler.
