cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault with PICOLIBC and TouchGFX

ANeam.1
Associate III

Hi, I consistently hit HardFault when using PICOLIBC. I am using a STM32H735G-DK board.

Setup:

1. Start from a black CubeMX project, selecting the board and default pins. The FreeRTOS must be enabled, and the TouchGFX (with the MPU configured). We will target CMake and SR Arm Clang. Generate code.

2. Open TouchGFX and load the project with the file ApplicationTemplate.touchgfx.part. No need to add anything, just generate code.

3. Open the entire project with VSCode. The project by default uses the PICOLIBC in the file starm-clang.cmake. The project as is compiles successfully. flash onto the board and click Continue. The code will instantly go in HardFault_Handler().

Here is a printscreen:

Screenshot 2026-03-15 203157.png

 Can anyone try to reproduce this, just to make sure it is not something only on my side? Thank you!

If I change for STARM_NEWLIB in starm-clang.cmake instead of STARM_PICOLIBC, everything works as expected, no hardfault, and the screen initializes successfully.

I have added a demo project.

1 ACCEPTED SOLUTION

Accepted Solutions
FluxPower42
Associate III

Hi @ANeam.1 

maybe you're experiencing the effects of the bug I described here:
Object initialization silently skipped with picoli... - STMicroelectronics Community

If you have the time and are willing, could you try modifying the linker description file and let us know how it goes?

  .preinit_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .init_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH

>>>>>>>>>>>>>>>>>> new

  /* picolibc uses __bothinit_array_start/end instead of separate preinit/init
     symbols. STM32CubeMX does not define these, causing __libc_init_array to
     silently skip all C++ constructors when building with picolibc. */
  /* PROVIDE(__bothinit_array_start = __preinit_array_start);
  PROVIDE(__bothinit_array_end   = __init_array_end); */

<<<<<<<<<<<<<<<<<<

  .fini_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

 

Best regards Timo

View solution in original post

5 REPLIES 5
FluxPower42
Associate III

Hi @ANeam.1 

maybe you're experiencing the effects of the bug I described here:
Object initialization silently skipped with picoli... - STMicroelectronics Community

If you have the time and are willing, could you try modifying the linker description file and let us know how it goes?

  .preinit_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .init_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH

>>>>>>>>>>>>>>>>>> new

  /* picolibc uses __bothinit_array_start/end instead of separate preinit/init
     symbols. STM32CubeMX does not define these, causing __libc_init_array to
     silently skip all C++ constructors when building with picolibc. */
  /* PROVIDE(__bothinit_array_start = __preinit_array_start);
  PROVIDE(__bothinit_array_end   = __init_array_end); */

<<<<<<<<<<<<<<<<<<

  .fini_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

 

Best regards Timo

ANeam.1
Associate III

Hi @FluxPower42 ,

Yes, this is it! Sorry did not check your post before making mine. Defining __bothinit_array_start and __bothinit_array_end solves the issue.

Thank you!

Hi @ANeam.1 

nice! And thanks for the test.
This just shows how important a quick fix is.

Regards Timo

vincent_grenet
ST Employee

@ANeam.1 
Please be aware STM32Cube bundle st-arm-clang@21.1.1+st.7 delivered today is fixing issue.
Please have a try updating and locking proper version to your project:
image.png

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Additional information about the fix is detailed here in @FluxPower42 's thread.