I debug STM32 project created with CMake. It uses HAL library and at the beginning I configure HAL and SysTick.
root/
├─ core/
│ ├─ core.c
│ ├─ core.h
│ ├─ stm32g4xx_it.c
│ ├─ stm32g4xx_it.h
│ ├─ CMakeLists
├─ main.c
├─ startup.s
├─ CMakeLists.txt
startup.s
file contains weak SysTick_Handler, as follows:
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
stm32g4xx_it.c
also contains SysTick_Handler
which overrides weak declaration.
The problem is when compile, link and load the app as it looks like above, SysTick interrupt ends in Default_Handler
. If I remove weak declaration from startup.s
file, then it works properly and correct handler function is executed. I think this is a result of how cmake works. In the root directory there's a main CMakeLists.txt file which compiles startup.s
and main.c
files, then links core library. The correct SysTick handler
is placed in the core library, thus compilation of startup.s
file "doesn't see" the other implementation of this handler function.
What is the correct yet elegant approach to solve it?
Another question which comes to my mind is how should I write code for other interrupt handlers and how to link them in CMake building system? Let's say I have a UART module and that module has its own interrupt handlers. Should I create a separate library which is based on startup.s
file and link all other modules which have interrupt handlers to it? I thought CMake should make building more transparent, readable and easy but that way it looks more like spaghetti. Probably I'm missing something...
EDIT 4/14/2021
I found out that the problem is only related to startup asm file. For example, I can create a weak function symbol in main.c, e.g.:
__attribute__((weak)) void SystemInit(void)
In the core library, in core.c I create function:
void SystemInit(void)
then after compilation and linking the correct function from core.c is used. So it looks like there's something strictly related to asm file here.