Stm32 Hard Fault - PC Address *.map matching
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-03-25 12:04 AM
Hello,
To capture the details of the Hard Fault, I’m using the following handler:
void HardFault_Handler(void)
{
__asm volatile
(
"TST lr, #4 \n"
"ITE EQ \n"
"MRSEQ r0, MSP \n"
"MRSNE r0, PSP \n"
"B hard_fault_handler_c \n"
);
}
void hard_fault_handler_c(unsigned int *hardfault_args)
{
unsigned int stacked_r0 = hardfault_args[0];
unsigned int stacked_r1 = hardfault_args[1];
unsigned int stacked_r2 = hardfault_args[2];
unsigned int stacked_r3 = hardfault_args[3];
unsigned int stacked_r12 = hardfault_args[4];
unsigned int stacked_lr = hardfault_args[5];
unsigned int stacked_pc = hardfault_args[6];
unsigned int stacked_psr = hardfault_args[7];
printf("\n[HardFault] Hata!\n");
printf("R0 = 0x%08X\n", stacked_r0);
printf("R1 = 0x%08X\n", stacked_r1);
printf("R2 = 0x%08X\n", stacked_r2);
printf("R3 = 0x%08X\n", stacked_r3);
printf("R12 = 0x%08X\n", stacked_r12);
printf("LR = 0x%08X\n", stacked_lr);
printf("PC = 0x%08X\n", stacked_pc);
printf("PSR = 0x%08X\n", stacked_psr);
while (1);
}
I'm getting hard fault in my STM32L4XX project. The output is:
[HardFault]!
R0 = 0x2000FFE8
R1 = 0x0000000A
R2 = 0x00000040
R3 = 0x00000002
R12 = 0x00000000
LR = 0x00000000
PC = 0x0800656F
PSR = 0x08000EEC
The *.map file is inside the zip
- Labels:
-
STM32CubeIDE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-03-25 5:15 AM
Hi @MvA54 !
I have investigated your attached *.map file.
Seems the hard fault is triggered in the libc (libc_nano.a) function _puts_r():
.text._puts_r 0x08006520 0xaa C:/ST/STM32CubeIDE_1.14.1/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344/tools/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(libc_a-puts.o)
0x08006520 _puts_r
*fill* 0x080065ca 0x2
.text.puts 0x080065cc 0x10 C:/ST/STM32CubeIDE_1.14.1/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344/tools/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(libc_a-puts.o)
0x080065cc puts
Do you use puts() in your code? Because puts() calls _puts_r() according the newlib sources.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-03-25 5:40 AM
> Do you use puts() in your code?
GCC compiler converts printf calls with one argument to puts. So it could be a printf.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-03-25 5:44 AM
@Pavel A. wrote:> Do you use puts() in your code?
GCC compiler converts printf calls with one argument to puts. So it could be a printf.
Yes that's true. Have forgotten to write that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-03-25 5:49 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-03-25 7:28 AM
@MvA54 wrote:Here, I’m intentionally dividing a uint8_t value by zero inside the APP_Test_Init function, causing a Hard Fault.When I examine the *.map file, shouldn’t I be able to see the APP_Test_Init function?
Dividing by zero should "normally" generate an usage fault on the ARMv7-M architecture, not a hard fault.
You can read this in the ARMv7-M TRM:UDIV
UsageFault raised by UDIV
Because when I try to divide by zero in C:
int test(unsigned char a)
{
return a / 0;
}
GCC use UDIV for the calculation in the resulting object file:
test.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <test>:
0: b480 push {r7}
2: b083 sub sp, #12
4: af00 add r7, sp, #0
6: 4603 mov r3, r0
8: 71fb strb r3, [r7, #7]
a: 79fb ldrb r3, [r7, #7]
c: 2200 movs r2, #0
e: fbb3 f3f2 udiv r3, r3, r2
12: b2db uxtb r3, r3
14: 4618 mov r0, r3
16: 370c adds r7, #12
18: 46bd mov sp, r7
1a: bc80 pop {r7}
1c: 4770 bx lr
