AnsweredAssumed Answered

STM32F4 function call overhead

Question asked by andreas.isenegger on Apr 8, 2014
Latest reply on May 2, 2014 by gonzalez.laurent


I'm fairly new to the STM32 processors, but got to like them quickly. Currently working with the STM32F401RE on a NUCLEO board, I made an observation I can't explain. Maybe somebody else can (easily).

I let the STM32CubeMX generate the startup code. I configured it to use the HSI source (HSI RC, f = 16MHz) as SYSCLK, let the AHB prescaler at default 1, thus the HCLK is 16MHz too.

Then I configured the SysTick to 100us. I know this is a bit shorter than usual, but for this project it's fine. I wrote a test that allows me to check with my watch that it really uns at 10kHz (e.g. wait 50000 times for the tick to occur results in 5s). That works fine.

Now to the problem. The time for calling two very short functions seems far too long to me. Pseudocode:

unsigned long long diff_us, time1_us, time2_us;
drvSysTick_getUptime(&time1_us); // Time driver function, see below
diff_us = time2_us – time1_us; // diff_us = 118us

My time driver functions, which base on the SysTick, return values for diff like 118us. Using latest Keil MDK, switching optimization doesn't reduce the value.

118us at 16MHz correspond to 1888 CPU cycles. I have no idea what could take that long. drvSysTick_getUptime() looks exactly like this:

int drvSysTick_getUptime(unsigned long long* uptime)
    unsigned int sysTickValue; // System Tick counter counts down!
    DISABLE_INTERRUPTS(); // __disable_irq()
    sysTickValue = SysTick->VAL;
    *uptime = sInstDscr.uptime; // Updated by ISR, value in us
    ENABLE_INTERRUPTS(); // __enable_irq()
    sysTickValue = SysTick->LOAD - sysTickValue;
    *uptime += (unsigned long long)sysTickValue * 1000000 / SystemCoreClock;
    return R_SUCCESS;

Any hint appreciated.
Kind regards,