2020-02-26 07:14 AM
Hi all,
I am working on a STM32F103VEtx MCU. In my firmware I have redirected the printf function to a UART for debugging purposes. When I start running the code, the printf function causes the hard fault handler to hit. Please see the call stack attached below
Thread #1 (Suspended : Signal : SIGINT:Interrupt)
prvGetRegistersFromStack() at stm32f1xx_it.c:109 0x800441a
<signal handler called>() at 0xfffffff9
std() at 0x8007abe
__sinit() at 0x8007b76
printf() at 0x8006dac
main() at main.c:130 0x800400c
It seems like std() function call triggers the hard fault. Please help me to figure out and fix the issue.
Thanks in advance,
Pramod K. G.
2020-02-26 10:14 AM
Step through and figure out which instruction causes it. The standard printf uses malloc, which may be causing it.
2020-02-26 12:09 PM
Hi TDK,
Thanks for the response. I already had tried 'step through' the printf function and it was not working for me. Hardfault handler was hitting when I do a step in to printf function.
From the NVIC register CFSR, I could see that BFARVALID and PRECISERR are set. Also the content of BFAR is 0.
I tried with increasing the heap and stack but the results were same.
2020-02-26 01:40 PM
2020-02-26 01:44 PM
Probably linking in the wrong libraries.
Do a disassembly/listing and walk the code.
I'd personally look at the CPU registers and code surrounding the failure.
Likely to be a Read as the fault is precise.
Perhaps a value in a structure or a pointer
2020-02-26 11:13 PM
Thanks for looking into this issue.
Attaching the disassembly code snippet where issue is happening
std:
08007ab9: movs r3, #0
08007abb: push {r4, lr}
08007abd: mov r4, r0
08007abf: strd r3, r3, [r0]
08007ac3: str r3, [r0, #8]
08007ac5: strh r1, [r0, #12]
08007ac7: str r3, [r0, #100] ; 0x64
08007ac9: strh r2, [r0, #14]
08007acb: strd r3, r3, [r0, #16]
It seems like hardfault is triggered from the line of code "08007abd: mov r4, r0". When clicking the std() function in call stack it is jumping to above mentioned line of code. Attaching the screenshot for more clarification.
2020-02-27 12:37 AM
A mov won't cause any fault, it's just moving a value of one register to another. It's most likely the next one, storing two words to memory pointed by [r0], which is the first parameter of the function call. So this function is called with a NULL pointer argument.
Get the sources of your C runtime library, and look into it, what could cause it to be called with a NULL pointer.
2020-02-27 04:29 AM
Thanks for the response.
can you please tell how can I get the sources of your C runtime library?
2020-02-27 05:21 AM
Ok, but what are the register values?
Betting R0 is NOT aligned and the STRD is failing
2020-02-27 06:17 AM
Hi Clive1,
Attaching the general purpose resister values
r0 0
r1 4
r2 0
r3 0
r4 -171798145
r5 0
r6 0
r7 12
r8 115200
r9 8
r10 7
r11 536871196
r12 -171798145
sp 0x2000017c <__global_locale+64>
lr 0x8007b77 (Hex)
pc 0x8007abe <std+6>
xPSR 0x61000000 (Hex)
msp 0x2000013c <__global_locale>
psp 0x0
primask 0
basepri 0
faultmask 0
control 0 .
I am seeing weird behavior with sprintf also.
Eg.
sprintf(buff, (const char *)"sprintf testing\n\r"); => No issues
sprintf(buff, (const char *)"sprintf %d\n\r",10); => Hitting hard-fault
You said "Probably linking in the wrong libraries", can you please explain?
My Linker flags => -specs=nosys.specs -specs=nano.specs -u _printf_float