[Solved] build HAL as static library : SysTick_Handler removed from code
Hello.
To generate a multiplatform code I defined a SW architecture and packaging as follow :

Build system :
- Vendor package can use the cdt project to generate the BSP (cdt builder is the only toolchain supported for system init code generation )
- Application is created as cmake project created by stmCubeIDE (new in stmcube ide 1.13) and links to the BSP.
At first sight the APP would be a complete application and the LLD a library providing only the HAL calls. That would mean that the APP hosts :
- Startup code
- Linker script
- Interrupt.
I am not sure the HAL could work with independently defined interrupt handler so I let those be part of LLD except the linker script (present but not used).
The LLD package contains :
- System init (peripheral and clocks, interrupt handler, startup code)
- The main() (that can be changed though, but I’m lazy about calling the init function in the right order).
Progress summary
Issue to create the HAL as library : it needs to be configured as a full binary. The workaround was to let it as is for project generation, and then in the project setting change the artefact to build as static library.
When launching, the sw hangs at startup, with an "unexpected interrupt".

I can bet it is the systick since the value is always 0 before the crash :

Also I called in the app code HAL_SuspendTick, and the crash does not happen anymore.
I’ve check where is put the vector table in the map :
.isr_vector 0x0000000008000000 0xbc
0x0000000008000000 . = ALIGN (0x4)
*(.isr_vector)
.isr_vector 0x0000000008000000 0xbc CMakeFiles/test_g0b1re_app.dir/Startup/startup_stm32g0b1retx.s.obj
0x0000000008000000 g_pfnVectors
0x00000000080000bc . = ALIGN (0x4)
I have checked where is put the systick handler :
0x0000000008000690 SysTick_Handler
But in fact in the list file I don’t find it at this address but the default handler :
08000690 <ADC_COMP_IRQHandler>:
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
8000690: e7fe b.n 8000690 <ADC_COMP_IRQHandler>
So during linkink process the Systick_Handler is replaced by the default handler, but why ?
I checked the :
- The project enabled the systick interrupt
- startup code was executed (of course)
- HAL_InitTick returned HAL_OK.
- Check for difference in linker script file (LLD, APP) : no difference.
I also checked the generated command lines to build :
arm-none-eabi-gcc -o "test_g0b1re_app_cdt.elf" @"objects.list" -Wl,--start-group -ltest_stm32_g0b1re_executable -Wl,--end-group -mcpu=cortex-m0plus -T"/home/ /dev/test_g0b1re_app_cdt/STM32G0B1RETX_FLASH.ld" --specs=nosys.specs -Wl,-Map="test_g0b1re_app_cdt.map" -Wl,--gc-sections -static -L"/home/test_stm32_g0b1re_executable/Debug" --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
I Tried to :
- create app cdt project instead of cmake : same result
- Move startup from LLD to APP
- Move the main from LLD to APP
- Uncomment USER_VECT_TAB_ADDRESS in system_stm32g0xx.c (to set SCB->VTOR)
- Enable option : place libraries in a linker group.
Always same result : falls in default handler.
Now it works with the followings :
- Invert the packages : set the app as library, and LLD as binary.
- Comment in the startup file the weak alias for SysTick_Handler.
So again how can the Systick_Handler be removed during compilation ? How can I avoid that ?
EDIT :
So thanks to chat-GPT I could resolve this by adding the linker option : -Wl,--whole-archive -ltest_stm32_g0b1re_executable -Wl,--no-whole-archive
I see a small increase in code size in flash, probable for the function added. I assume that with -gc-sections options, the linker will remove the not used functions. I shall check this with a complex project.
