cancel
Showing results for 
Search instead for 
Did you mean: 

Troubleshooting a Hard Fault

johnjohn9105
Associate III
Posted on September 15, 2012 at 17:52

I am attempting to buid an ARM-GCC/Eclipse build environment from scratch. I'm beginning to realize that this is a bigger task than I'd first thought.

In any case, I was able to build the STM32F0 demo project and upload it to the STM32F0DISCOVERY board with ST-LINK. Using ST-LINK Utility, and later, OpenOCD, I'm finding that my code is in an infinite loop in the Hard Fault Handler. Since I don't yet have source-level debugging enabled in Eclipse I'm using a telnet session to OpenOCD to debug. I've determined that the handler is getting called when startup_stm32f0xx.s is calling __libc_init_array. The instruction at address 0x0800061a is:

08000610 <LoopFillZerobss>:
8000610: 4b09 ldr r3, [pc, #36] ; (8000638 <LoopForever+0x16>)
8000612: 429a cmp r2, r3
8000614: d3f9 bcc.n 800060a <FillZerobss>
8000616: f7ff ff53 bl 80004c0 <SystemInit>
800061a: f000 ec88 blx 8000f2c <__libc_init_array>
800061e: f7ff febd bl 800039c <main>

The instruction at 0x08000f2c is:

08000f2c <__libc_init_array>:
8000f2c: e92d4070 push {r4, r5, r6, lr}

When I step from the first address to the second, I encounter the fault. The OpenOCD session looks like:


> reset

target state: halted

target halted due to breakpoint, current mode: Thread

xPSR: 0x61000000 pc: 0x0800061a msp: 0x20002000

> reg

===== arm v7m registers

(0) r0 (/32): 0x20000000

(1) r1 (/32): 0x00000002

(2) r2 (/32): 0x0028000A

(3) r3 (/32): 0x00000008

(4) r4 (/32): 0xFFFFFFFF

(5) r5 (/32): 0xFFFFFFFF

(6) r6 (/32): 0xFFFFFFFF

(7) r7 (/32): 0xFFFFFFFF

(8) r8 (/32): 0xFFFFFFFF

(9) r9 (/32): 0xFFFFFFFF

(10) r10 (/32): 0xFFFFFFFF

(11) r11 (/32): 0xFFFFFFFF

(12) r12 (/32): 0xFFFFFFFF

(13) sp (/32): 0x20002000

(14) lr (/32): 0x08000539

(15) pc (/32): 0x0800061A

(16) xPSR (/32): 0x61000000

(17) msp (/32): 0x20002000

(18) psp (/32): 0xFFFFFFFC

(19) primask (/1): 0x00

(20) basepri (/8): 0x00

(21) faultmask (/1): 0x00

(22) control (/2): 0x00

===== cortex-m3 dwt registers

(23) dwt_ctrl (/32)

(24) dwt_cyccnt (/32)

(25) dwt_0_comp (/32)

(26) dwt_0_mask (/4)

(27) dwt_0_function (/32)

(28) dwt_1_comp (/32)

(29) dwt_1_mask (/4)

(30) dwt_1_function (/32)

> step

target state: halted

target halted due to single-step, current mode: Handler HardFault

xPSR: 0x61000003 pc: 0x0800049c msp: 0x20001fe0

halted: PC: 0x0800049c

> reg

===== arm v7m registers

(0) r0 (/32): 0x20000000

(1) r1 (/32): 0x00000002

(2) r2 (/32): 0x0028000A

(3) r3 (/32): 0x00000008

(4) r4 (/32): 0xFFFFFFFF

(5) r5 (/32): 0xFFFFFFFF

(6) r6 (/32): 0xFFFFFFFF

(7) r7 (/32): 0xFFFFFFFF

(8) r8 (/32): 0xFFFFFFFF

(9) r9 (/32): 0xFFFFFFFF

(10) r10 (/32): 0xFFFFFFFF

(11) r11 (/32): 0xFFFFFFFF

(12) r12 (/32): 0xFFFFFFFF

(13) sp (/32): 0x20001FE0

(14) lr (/32): 0xFFFFFFF9

(15) pc (/32): 0x0800049C

(16) xPSR (/32): 0x61000003

(17) msp (/32): 0x20001FE0

(18) psp (/32): 0xFFFFFFFC

(19) primask (/1): 0x00

(20) basepri (/8): 0x00

(21) faultmask (/1): 0x00

(22) control (/2): 0x00

===== cortex-m3 dwt registers

(23) dwt_ctrl (/32)

(24) dwt_cyccnt (/32)

(25) dwt_0_comp (/32)

(26) dwt_0_mask (/4)

(27) dwt_0_function (/32)

(28) dwt_1_comp (/32)

(29) dwt_1_mask (/4)

(30) dwt_1_function (/32)

>

It seems to me that the PUSH instruction is causing the fault (either that or the branch instruction), but I'm afraid I don't have sufficient experience with ARM architectures to know why. The stack pointer appears to be correct for the STM32F0 before the fault. The contents of the stack after the fault are:

1.
> mdw 0x20001FE0 0x20
2.
0x20001fe0: 20000000 00000002 0028000a 00000008 ffffffff 08000539 0800061a 61000000
3.
0x20002000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff

Can anyone help me determine why my code is faulting? As I said, I'm rather ignorant of ARM architectures and would appreciate any assistance the community could offer. I did do some web searches on relevant keywords but I wasn't able to find anything that appeared relevant to this situation.
2 REPLIES 2
Posted on September 15, 2012 at 18:20

It looks like it's trying to call 32-bit ARM code, the Cortex-Mx parts only run Thumb(2) code, or at least a sub-set on the M0.

So, you are probably linking the wrong library/CRT code.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
johnjohn9105
Associate III
Posted on September 15, 2012 at 18:51

Thanks, Clive! I was about to report the same thing. The stacked xPSR register, I think, is 0x61000000, which has the T bit cleared, which means there was an attempt to switch to the ARM instruction set.

Adding the linker flags ''-mthumb -mcpu=cortex-m0'' resolved the issue.

I wish I knew more about what these flags do; I've been unable to find any good documentation on them. But at least I have blinkylights now!