cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32 Hard Fault - PC Address *.map matching

MvA54
Associate II

Hello,

Hard Fault Handler Code:
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); }
View more


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

 

Problem: The PC address 0x0800656F shows where the error occurs. I checked the *.map file but couldn’t figure out which function it corresponds to. Where might I be going wrong? How can I match this address with the *.map file?

The *.map file is inside the zip

5 REPLIES 5
krotti42
Associate III

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.

 

Do you use puts() in your code?

GCC compiler converts printf calls  with one argument to puts. So it could be a printf.


@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.

MvA54
Associate II
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?

@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:UDIVUDIVUsageFault raised by UDIVUsageFault 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