Reputation: 1035
I am trying to port over this [code][1] to read the stack frame in the hard fault handler for my STM32F302C8:
__asm volatile
(
" tst lr, #4 n"
" ite eq n"
" mrseq r0, msp n"
" mrsne r0, psp n"
" ldr r1, [r0, #24] n"
" ldr r2, handler2_address_const n"
" bx r2 n"
" handler2_address_const: .word prvGetRegistersFromStack n"
);
However, the generated assembly instruction doesn't load the correct value of prvGetReigsetersFromStack
into R2
.
Version 1:
08000b22 <HardFault_Handler>:
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
SHARED_HARD_FAULT_HANDLER_ASSEMBLY
8000b22: f01e 0f04 tst.w lr, #4
8000b26: bf0c ite eq
8000b28: f3ef 8008 mrseq r0, MSP
8000b2c: f3ef 8009 mrsne r0, PSP
8000b30: 6981 ldr r1, [r0, #24]
8000b32: 4a00 ldr r2, [pc, #0] ; (8000b34 <HardFault_Handler+0x12>)
8000b34: 4710 bx r2
08000b36 <handler2_address_const>:
8000b36: 08006c15 stmdaeq r0, {r0, r2, r4, sl, fp, sp, lr}
}
Note the comment (8000b34 <HardFault_Handler+0x12>)
, I am loading the value at 8000b34
to r2 instead of the value at 8000b36
(i.e. handler2_address_const
)
What's even more interesting is, if I move the function definition somewhere in the same source file, the code now behaves as expected:
Version 2:
08000b58 <HardFault_Handler>:
void HardFault_Handler(void)
{
8000b58: b480 push {r7}
8000b5a: af00 add r7, sp, #0
__asm volatile(
8000b5c: f01e 0f04 tst.w lr, #4
8000b60: bf0c ite eq
8000b62: f3ef 8008 mrseq r0, MSP
8000b66: f3ef 8009 mrsne r0, PSP
8000b6a: 6981 ldr r1, [r0, #24]
8000b6c: 4a00 ldr r2, [pc, #0] ; (8000b70 <handler2_address_const>)
8000b6e: 4710 bx r2
08000b70 <handler2_address_const>:
8000b70: 08006c25 stmdaeq r0, {r0, r2, r5, sl, fp, sp, lr}
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n");
}
Note that the comment is now (8000b70 <handler2_address_const>)
, which is the memory address that contains a function pointer to `prvGetRegistersFromStack.
Note that in both versions of the code, the generated instruction is the same: ```` ldr r2, [pc, #0]
, but the comment is different. I thought maybe this was just a mistake by the disassembler, but with **Version 1** of my code, `prvGetRegistersFromStack` never gets called.
I am using the newest `arm-none-eabi-gcc-2019q3-update`.
[1]: https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
Upvotes: 0
Views: 187
Reputation: 1035
Update: The root-cause was due to alignment. I found two possible solutions:
bx
with b
and just branch directly to the functionHardFault_Handler()
Upvotes: 1