linkerarmstm32

Need to understand linker behaviour on STM32 project


I recently spent a lot of time solving a problem with an interrupt-handler, and even though I have solved it, I would like to better understand why things went wrong. (It was related to a UART1 interrupt handler, so I am reducing the code fragments to only that one, but the problem is not related to this specific peripheral).

  1. In the startup file of the MCU, the interrupt vectors are defined as
g_pfnVectors:
[...some lines removed]
  .word USART1_IRQHandler
[...more lines removed]

but a bit further down, there is also

.weak   USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler

In the file stm32wlxx_it.cpp I had implemented the interrupt handler

void USART1_IRQHandler(void) {
     uint32_t isrflags = USART1->ISR;
    if (isrflags & uart1::rdrNotEmpty) {
        uart1::rxNotEmpty();
    }
    if (isrflags & uart1::tdrEmpty) {
        uart1::txEmpty();
    }
}

but I forgot to also add a declaration to stm32wlxx_it.h When building the project, there were no compile or linker errors, but during execution, when the interrupt fired, the code would jump to Default_Handler: which is also defined in the startup file

  .section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b Infinite_Loop
  .size Default_Handler, .-Default_Handler

Question : So if there is an implementation of the interrupt handler, but no declaration, why does the linker falls back to Default_Handler ?


Solution

  • Ok, so the reason is the name mangling of C++.

    As my interrupt handlers use C++, I needed to rename the stm32wlxx_it.c (generated by Stm32CubeMx) file to stm32wlxx_it.cpp. This invokes the C++ compiler, but also mangles the names of the functions. Doing nm stm32wlxx_it.orevealed that the actual name of function in the object file is _Z17USART1_IRQHandlerv.

    When you declare the function in stm32wlxx_it.h it is no longer mangled : if you create the project as C++ project in STM32CubeMx, it will automatically add extern "C" around the declarations.