0
\$\begingroup\$

I tried to manually setup a STM32 project for my nucleo board, however the binary behaves strangely during compilation. The current project state is located in a github repository.

I noted two problematic items, but I don't know if they are related:

  • When I set a breakpoint in the entry point function, "Reset_Handler", with gdb-multiarch, the breakpoint is never reached, and the debugging session breaks in a random function: enter image description here

  • Checking the objdump of the binary, arm-none-eabi-objdump -D build/stepper-driver.elf > stepper_dump, I noticed a mismatch between the addresses of the handler functions and the values stored by the vector table:

Vector table:
    08000000 <g_pfnVectors>:
    8000000:    20020000    andcs   r0, r2, r0  # equivalent to .word  _estack
    8000004:    08000389    stmdaeq r0, {r0, r3, r7, r8, r9} # equivalent to .word  Reset_Handler
    8000008:    08000257    stmdaeq r0, {r0, r1, r2, r4, r6, r9} # equivalent to .word  NMI_Handler
    800000c:    080002b9    stmdaeq r0, {r0, r3, r4, r5, r7, r9} # equivalent to .word  HardFault_Handler
    8000010:    080002cf    stmdaeq r0, {r0, r1, r2, r3, r6, r7, r9} # equivalent to .word  MemManage_Handler


08000388 <Reset_Handler>:
 8000388:   f8df d034   ldr.w   sp, [pc, #52]   @ 80003c0 <LoopFillZerobss+0x12>
 800038c:   480d        ldr r0, [pc, #52]   @ (80003c4 <LoopFillZerobss+0x16>)
 800038e:   490e        ldr r1, [pc, #56]   @ (80003c8 <LoopFillZerobss+0x1a>)
 8000390:   4a0e        ldr r2, [pc, #56]   @ (80003cc <LoopFillZerobss+0x1e>)
 8000392:   2300        movs    r3, #0
 8000394:   e002        b.n 800039c <LoopCopyDataInit>


08000256 <NMI_Handler>:
 8000256:   b480        push    {r7}
 8000258:   af00        add r7, sp, #0
 800025a:   e7fe        b.n 800025a <NMI_Handler+0x4>


080002b8 <HardFault_Handler>:
 80002b8:   f01e 0f04   tst.w   lr, #4
 80002bc:   bf0c        ite eq
 80002be:   f3ef 8008   mrseq   r0, MSP
 80002c2:   f3ef 8009   mrsne   r0, PSP
 80002c6:   4671        mov r1, lr
 80002c8:   f7ff bfc8   b.w 800025c <HardFault_Handler_C>
 80002cc:   bf00        nop

080002ce <MemManage_Handler>:
 80002ce:   b480        push    {r7}
 80002d0:   af00        add r7, sp, #0
 80002d2:   e7fe        b.n 80002d2 <MemManage_Handler+0x4>

The addresses of the vector table is incremented by one of the correct values.

My current theory is that the execution of my binary starts from the beginning of the vector table, and the mismatch among the addresses caused the error described by the previous item (random function during the debugging session).

What's happening in the first error I described?

Does my theory make sense? (explained in first answer)

What am I doing wrong that's causing the addresses mismatch and how can I solve it? (solved - not an error)

Update

The addresses mismatch is already explained by a comment, however the initial problem still happens.

Update 2

Including the memory dump around Reset_Handler function

memory dump:

   0x8000370 <SystemInit+60>:   lsls    r1, r0, #12
   0x8000372 <SystemInit+62>:   str r3, [r4, #112]  @ 0x70
   0x8000374 <SystemInit+64>:   ldr r3, [r4, #0]
   0x8000376 <SystemInit+66>:   bic.w   r3, r3, #16777216   @ 0x1000000
   0x800037a <SystemInit+70>:   str r3, [r4, #0]
   0x800037c <SystemInit+72>:   ldr.w   r3, [r4, #140]  @ 0x8c
   0x8000380 <SystemInit+76>:   bic.w   r3, r3, #16777216   @ 0x1000000
   0x8000384 <SystemInit+80>:   str.w   r3, [r4, #140]  @ 0x8c
   0x8000388 <Reset_Handler>:   ldr r3, [r4, #8]
   0x800038a <Reset_Handler+1>: bic.w   r3, r3, #3
   0x800038e <Reset_Handler+5>: str r3, [r4, #8]
   0x8000390 <Reset_Handler+7>: ldr r3, [r4, #8]
   0x8000392 <Reset_Handler+9>: bic.w   r3, r3, #240    @ 0xf0
   0x8000396 <Reset_Handler+13>:    str r3, [r4, #8]
   0x8000398 <Reset_Handler+15>:    ldr r3, [r4, #8]
   0x800039a <Reset_Handler+17>:    bic.w   r3, r3, #7168   @ 0x1c00
   0x800039e <Reset_Handler+21>:    orr.w   r3, r3, #6144   @ 0x1800
   0x80003a2 <Reset_Handler+25>:    str r3, [r4, #8]
   0x80003a4 <Reset_Handler+27>:    ldr r3, [r4, #112]  @ 0x70
   0x80003a6 <Reset_Handler+29>:    bic.w   r3, r3, #768    @ 0x300
   0x80003aa <Reset_Handler+33>:    orr.w   r3, r3, #512    @ 0x200
   0x80003ae <Reset_Handler+37>:    str r3, [r4, #112]  @ 0x70
   0x80003b0 <Reset_Handler+39>:    ldr r3, [r4, #112]  @ 0x70
   0x80003b2 <Reset_Handler+41>:    orr.w   r3, r3, #32768  @ 0x8000
   0x80003b6 <Reset_Handler+45>:    str r3, [r4, #112]  @ 0x70
   0x80003b8 <Reset_Handler+47>:    ldr r3, [r4, #8]
   0x80003ba <Reset_Handler+49>:    bic.w   r3, r3, #123731968  @ 0x7600000
   0x80003be <Reset_Handler+53>:    str r3, [r4, #8]
   0x80003c0 <Reset_Handler+55>:    mov r1, r8
   0x80003c2 <LoopFillZerobss+20>:  movw    r0, #3326   @ 0xcfe
   0x80003c6 <LoopFillZerobss+24>:  bl  0x8000298 <HardFault_Handler_C+60>
   0x80003ca <LoopFillZerobss+28>:  ldr r3, [r5, #4]
   0x80003cc <LoopFillZerobss+30>:  and.w   r3, r3, r9
   0x80003d0 <LoopFillZerobss+34>:  str r3, [r5, #4]
   0x80003d2 <LoopFillZerobss+36>:  ldr r2, [r5, #12]
   0x80003d4 <LoopFillZerobss+38>:  movw    r1, #3326   @ 0xcfe
   0x80003d8 <WWDG_IRQHandler>: rbit    r3, r1
   0x80003dc <__libc_init_array>:   clz r3, r3
   0x80003e0 <__libc_init_array+4>: lsl.w   r3, r3, r8
   0x80003e4 <__libc_init_array+8>: movs    r7, #3
   0x80003e6 <__libc_init_array+10>:    lsl.w   r3, r7, r3
   0x80003ea <__libc_init_array+14>:    bic.w   r3, r2, r3
   0x80003ee <__libc_init_array+18>:    rbit    r1, r1
   0x80003f2 <__libc_init_array+22>:    mov.w   r0, #256    @ 0x100
   0x80003f6 <__libc_init_array+26>:    str r3, [r5, #12]
   0x80003f8 <__libc_init_array+28>:    mov r1, r6
   0x80003fa <__libc_init_array+30>:    bl  0x8000298 <HardFault_Handler_C+60>
   0x80003fe <__libc_init_array+34>:    ldr r1, [r5, #12]
   0x8000400 <__libc_init_array+36>:    mov.w   r3, #256    @ 0x100
   0x8000404 <__libc_init_array+40>:    rbit    r2, r3

objdump generated from elf file:

 8000370:   f8d3 3088   ldr.w   r3, [r3, #136]  @ 0x88
 8000374:   4a03        ldr r2, [pc, #12]   @ (8000384 <SystemInit+0x50>)
 8000376:   f443 0370   orr.w   r3, r3, #15728640   @ 0xf00000
 800037a:   f8c2 3088   str.w   r3, [r2, #136]  @ 0x88
 800037e:   bf00        nop
 8000380:   bd80        pop {r7, pc}
 8000382:   bf00        nop
 8000384:   e000ed00    and lr, r0, r0, lsl #26

08000388 <Reset_Handler>:
 8000388:   f8df d034   ldr.w   sp, [pc, #52]   @ 80003c0 <LoopFillZerobss+0x12>
 800038c:   480d        ldr r0, [pc, #52]   @ (80003c4 <LoopFillZerobss+0x16>)
 800038e:   490e        ldr r1, [pc, #56]   @ (80003c8 <LoopFillZerobss+0x1a>)
 8000390:   4a0e        ldr r2, [pc, #56]   @ (80003cc <LoopFillZerobss+0x1e>)
 8000392:   2300        movs    r3, #0
 8000394:   e002        b.n 800039c <LoopCopyDataInit>

08000396 <CopyDataInit>:
 8000396:   58d4        ldr r4, [r2, r3]
 8000398:   50c4        str r4, [r0, r3]
 800039a:   3304        adds    r3, #4

0800039c <LoopCopyDataInit>:
 800039c:   18c4        adds    r4, r0, r3
 800039e:   428c        cmp r4, r1
 80003a0:   d3f9        bcc.n   8000396 <CopyDataInit>
 80003a2:   4a0b        ldr r2, [pc, #44]   @ (80003d0 <LoopFillZerobss+0x22>)
 80003a4:   4c0b        ldr r4, [pc, #44]   @ (80003d4 <LoopFillZerobss+0x26>)
 80003a6:   2300        movs    r3, #0
 80003a8:   e001        b.n 80003ae <LoopFillZerobss>

080003aa <FillZerobss>:
 80003aa:   6013        str r3, [r2, #0]
 80003ac:   3204        adds    r2, #4

080003ae <LoopFillZerobss>:
 80003ae:   42a2        cmp r2, r4
 80003b0:   d3fb        bcc.n   80003aa <FillZerobss>
 80003b2:   f7ff ffbf   bl  8000334 <SystemInit>
 80003b6:   f000 f811   bl  80003dc <__libc_init_array>
 80003ba:   f7ff ff49   bl  8000250 <main>
 80003be:   4770        bx  lr
 80003c0:   20020000    andcs   r0, r2, r0
 80003c4:   20000000    andcs   r0, r0, r0
 80003c8:   20000000    andcs   r0, r0, r0
 80003cc:   08000444    stmdaeq r0, {r2, r6, sl}
 80003d0:   20000000    andcs   r0, r0, r0
 80003d4:   2000001c    andcs   r0, r0, ip, lsl r0

080003d8 <ADC_IRQHandler>:
 80003d8:   e7fe        b.n 80003d8 <ADC_IRQHandler>
    ...

080003dc <__libc_init_array>:
 80003dc:   b570        push    {r4, r5, r6, lr}
 80003de:   4d0d        ldr r5, [pc, #52]   @ (8000414 <__libc_init_array+0x38>)
 80003e0:   4c0d        ldr r4, [pc, #52]   @ (8000418 <__libc_init_array+0x3c>)
 80003e2:   1b64        subs    r4, r4, r5
 80003e4:   10a4        asrs    r4, r4, #2
 80003e6:   2600        movs    r6, #0
 80003e8:   42a6        cmp r6, r4
 80003ea:   d109        bne.n   8000400 <__libc_init_array+0x24>
 80003ec:   4d0b        ldr r5, [pc, #44]   @ (800041c <__libc_init_array+0x40>)
 80003ee:   4c0c        ldr r4, [pc, #48]   @ (8000420 <__libc_init_array+0x44>)
 80003f0:   f000 f818   bl  8000424 <_init>
 80003f4:   1b64        subs    r4, r4, r5
 80003f6:   10a4        asrs    r4, r4, #2
 80003f8:   2600        movs    r6, #0
 80003fa:   42a6        cmp r6, r4
 80003fc:   d105        bne.n   800040a <__libc_init_array+0x2e>
 80003fe:   bd70        pop {r4, r5, r6, pc}
 8000400:   f855 3b04   ldr.w   r3, [r5], #4
 8000404:   4798        blx r3
\$\endgroup\$
5
  • \$\begingroup\$ Do you use openocd or stlink GDB servere or something else? \$\endgroup\$
    – Misaz
    Commented Nov 19, 2023 at 22:13
  • \$\begingroup\$ I use stlink server: "st-util build/stepper-driver.bin /dev/stm32f4". The debug hardware is already present in the Nucleo board that I've been working with. \$\endgroup\$
    – andre.hre
    Commented Nov 19, 2023 at 22:51
  • \$\begingroup\$ with gdb-multiarch Why? Could you try dedicated arm-none-eabi-gdb? Also, dump (read out) content of FLASH at around the Reset_Handler and compare to bin/hex/disasm. \$\endgroup\$
    – wek
    Commented Nov 20, 2023 at 16:28
  • \$\begingroup\$ I've had some trouble using arm-none-eabi-gdb, however, fortunately, I've just fixed it. But even when changing to the arm tool, the same error occurs. The content around Reset_Handler was added to the question, it's better formatted there than here, in the comment. I also included the dump I generated with arm-none-eabi-objdump of the elf generated by the compilation process. The content of the dumped memory is different from the objdump generated in my dev environment. I don't have any idea what's causing the difference between them. \$\endgroup\$
    – andre.hre
    Commented Nov 21, 2023 at 23:56
  • \$\begingroup\$ The content of the dumped memory is different from the objdump generated in my dev environment. That's the root of the problem, then. It appears that the FLASH for whatever reason does not get programmed with the current binary. Maybe FLASH is write protected in option bytes? Try to read it out and check/erase/reprogram/check option bytes using some "known good" tool, e.g. CubeProgrammer + genuine STLink. \$\endgroup\$
    – wek
    Commented Nov 23, 2023 at 13:15

1 Answer 1

3
\$\begingroup\$

From the arm Cortex-M3 vector table documentation:

The least-significant bit of each vector must be 1, indicating that the exception handler is Thumb code, see Thumb state.

Because the vector addresses will always have at least 16bit alignment, the LSB is not required to be able to find the correct ISR (address LSB will always be 0). The designers decided to make use of this LSB to indicate whether the vector ha dler is Thumb code.

So in summary, you are doing nothing wrong, the addresses in the vector table are correct. The vector should be at the location specified in the vector table bitwise-ANDed with 0xFFFFFFFE.

\$\endgroup\$
1
  • \$\begingroup\$ Do you have any idea about the first problem I described? It's been a long time I've been stuck at it, and I don't have any idea what's causing it. \$\endgroup\$
    – andre.hre
    Commented Nov 19, 2023 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.