Skip to main content
Graduate II
April 24, 2024
Solved

Best way to boost STM32U5 speed during libc init

  • April 24, 2024
  • 4 replies
  • 1869 views

[This is a follow-up to https://community.st.com/t5/stm32-mcus-embedded-software/setting-up-clocks-on-stm32u5-nucleo-board-in-startup-assembler/m-p/665708#M47209]

As discussed in the issue referenced above, we do quite a lot of work in C constructors (as part of a test system)  and as a result __libc_init takes a loooong time to execute on an STM32U5 unless we can chivvy the chip into life early.

As a fix for this I put in a bl to my SystemClock_Config in my startup .s file before __libc_init is called.  However, I found that the call to HAL_PWREx_ControlVoltageScaling() in my SystemClock_Config() function times out unless HAL_Init() is called first.

So I add a bl to HAL_Init before the bl to SystemClock_Config, that's fine, but HAL_Init() enables SysTick and, unfortunately, the FreeRTOS port code for CM33, as provided by https://github.com/STMicroelectronics/x-cube-freertos, occupies SysTick_Handler() and, irretrievably, calls into FreeRTOS internals which are most definitely not set up at this point, so start-up goes bang when I use FreeRTOS; the ThreadX port is better behaved but I need FreeRTOS to work and I don't want to fiddle with its internals.

QUESTION: what is the best/simplest way to get the processor running smartly before __libc_init is called?

    This topic has been closed for replies.
    Best answer by Uwe Bonnes

    Best way: Set up clocks as described here.

    Second best: Switch MSI startup clock from 4 Mhz to 24 Mhz. At startup 4 Mhz is selected. Flash can run with 0 wait states at 24 Mhz even at voltage range3, so you do not need to change other settings. So probably about a 6-fold speed increase.

    4 replies

    Super User
    April 24, 2024
    1. Find out what it is in HAL_Init() that SystemClock_Config() depends upon;
    2. Implement that before calling SystemClock_Config() 

     

    Alternatively, just implement what SystemClock_Config() does as direct register accesses.

    Using LL_ calls may help ...

    Graduate II
    April 24, 2024

    Understood, I was just hoping that there would be something simpler that would just get the processor basically "out of bed" as this could be a problem for anyone running C++ code and I doubt that the average C++ programmer would be equipped to set up a system at this level...?

    Graduate II
    April 24, 2024

    Best way: Set up clocks as described here.

    Second best: Switch MSI startup clock from 4 Mhz to 24 Mhz. At startup 4 Mhz is selected. Flash can run with 0 wait states at 24 Mhz even at voltage range3, so you do not need to change other settings. So probably about a 6-fold speed increase.

    Graduate II
    April 24, 2024

    >>QUESTION: what is the best/simplest way to get the processor running smartly before __libc_init is called?

    Get clocks/ PLLs up in SystemInit(), per original ARM/CMSIS expectations

    Not that those are fast per se, PLL/HSE can take time to start. HSI or MSI is already running, so could perhaps leverage that into PLL and it's just the locking time. But the memory interactions for the statics clear/copy will be more prompt. Cost of clock bring-up will be the same, earlier or later in the process.

    Bring up external memories too, then these can be sources of initialization data. Enable caching and FPU, etc

    If using a loader model, don't need to bring up PLL's and clocks a second time.

    Graduate II
    April 24, 2024

    @Uwe Bonnes: your second best is exactly the kind of thing I was looking for, will investigate.