cancel
Showing results for 
Search instead for 
Did you mean: 

[Solved] build HAL as static library : SysTick_Handler removed from code

Selso LIBERADO
Associate III

Hello.

To generate a multiplatform code I defined a SW architecture and packaging as follow :

SelsoLIBERADO_0-1695939285574.png

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".

SelsoLIBERADO_1-1695939346062.png

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

SelsoLIBERADO_2-1695939346065.png

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.

 

1 ACCEPTED SOLUTION

Accepted Solutions

Good links indeed !

Actually I like this mechanism to prevent not managed IRQ detection. Where would it land otherwise ?

I'm not sure what is doing ,--whole-archive : scan the whole archive, or embbed it completely.

If the latter is the right behavior, does --gc-sections compensate ? YES actually.

  • without this option my code size is 52 kB
  • with it : 11 kB.

 

For me then the right thing to do is using --whole-archive to scan all archive with --gc-sections to remove unused code.

 

View solution in original post

4 REPLIES 4
TDK
Guru

Resolving strong/weak definitions within the gcc linker for libraries is problematic. Jump down the rabbit hole if you want, but commenting out the weak definition is probably the best solution here.

https://stackoverflow.com/questions/23079997/override-weak-symbols-in-static-library

https://stackoverflow.com/questions/13089166/how-to-make-gcc-link-strong-symbol-in-static-library-to-overwrite-weak-symbol?noredirect=1&lq=1

Lots of others...

If you feel a post has answered your question, please click "Accept as Solution".
Pavel A.
Evangelist III

Looks spooky... another breaking change in the latest GNU compiler & linker? The non-weak functions (of the main app) go before the lib on the link command line. Or not? Can you show the linker command line?

Hello.

The generated command line is already in the post.

For information I also copy the command line generated with cmake, results are equals to cdt build :

/usr/bin/cmake -E cmake_link_script CMakeFiles/test_g0b1re_app.dir/link.txt --verbose=1
arm-none-eabi-gcc -mcpu=Cortex-M0plus -std=gnu11   --specs=nano.specs -mthumb -Wall -Werror -g  -T../STM32G0B1RETX_FLASH.ld --specs=nosys.specs -Wl,-Map=test.map -Wl,--gc-sections -static -Wl,--start-group -lc -lm -Wl,--end-group CMakeFiles/test_g0b1re_app.dir/Startup/startup_stm32g0b1retx.s.obj CMakeFiles/test_g0b1re_app.dir/Sources/app_main.c.obj CMakeFiles/test_g0b1re_app.dir/Sources/syscalls.c.obj CMakeFiles/test_g0b1re_app.dir/Sources/sysmem.c.obj  -o test_g0b1re_app.elf   -L/home/workspace/test_g0b1re_app/../test_stm32_g0b1re_executable/Debug  -ltest_stm32_g0b1re_executable 


arm-none-eabi-gcc -o "test_g0b1re_app_cdt.elf" @"objects.list"  -mcpu=cortex-m0plus -T"/home/nautilus/dev/MCB-RT_Prod/test_g0b1re_app_cdt/STM32G0B1RETX_FLASH.ld" --specs=nosys.specs -Wl,-Map="test_g0b1re_app_cdt.map" -Wl,--gc-sections -static -L"/home/dev/test_stm32_g0b1re_executable/Debug" --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group -Wl,--whole-archive -ltest_stm32_g0b1re_executable -Wl,--no-whole-archive

Good links indeed !

Actually I like this mechanism to prevent not managed IRQ detection. Where would it land otherwise ?

I'm not sure what is doing ,--whole-archive : scan the whole archive, or embbed it completely.

If the latter is the right behavior, does --gc-sections compensate ? YES actually.

  • without this option my code size is 52 kB
  • with it : 11 kB.

 

For me then the right thing to do is using --whole-archive to scan all archive with --gc-sections to remove unused code.