Skip to main content
KiptonM
Senior III
October 14, 2021
Solved

How do you measure the execution CPU cycles for a section of code?

  • October 14, 2021
  • 4 replies
  • 8716 views

I am running a STM32F466RE with no OS, using the STM32CubeIDE.

Is there a code profiler, or some other way I can measure how many CPU clock cycles it takes for a certain section of code to execute?

I am trying to compare different methods of processing ADC results and trying to find the fastest, or what are the speed hits by doing it one way versus another. Or if it makes a difference what order I execute my statements in.

This should be standard stuff.

This topic has been closed for replies.
Best answer by Tesla DeLorean

The DWT CYCCNT is the way one usually does this...

Present on all STM32 using the CM3, CM4 and CM7 cores.

//****************************************************************************
 
volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004;
volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000;
volatile unsigned int *DWT_LAR = (volatile unsigned int *)0xE0001FB0;
volatile unsigned int *SCB_DHCSR = (volatile unsigned int *)0xE000EDF0;
volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC;
volatile unsigned int *ITM_TER = (volatile unsigned int *)0xE0000E00;
volatile unsigned int *ITM_TCR = (volatile unsigned int *)0xE0000E80;
 
//****************************************************************************
 
static int Debug_ITMDebug = 0;
 
//****************************************************************************
 
void EnableTiming(void)
{
 if ((*SCB_DHCSR & 1) && (*ITM_TER & 1)) // Enabled?
 Debug_ITMDebug = 1;
 
 *SCB_DEMCR |= 0x01000000;
 *DWT_LAR = 0xC5ACCE55; // enable access
 *DWT_CYCCNT = 0; // reset the counter
 *DWT_CONTROL |= 1 ; // enable the counter
}
 
//****************************************************************************
 
void Delay(uint32_t cycles)
{
 uint32_t start = *DWT_CYCCNT;
 
 while((*DWT_CYCCNT - start) < cycles);
}
 
//****************************************************************************

4 replies

S.Ma
Principal
October 14, 2021

At leasy 2 options: activate and use the debug cycle counter, take timestamp before amd after the function and take min max values over time if interrupts are allowed to fire. Other method is use a timer clocked at core frequency... needed in cortex m0+ as there isn't debug cycle counter...

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
October 14, 2021

The DWT CYCCNT is the way one usually does this...

Present on all STM32 using the CM3, CM4 and CM7 cores.

//****************************************************************************
 
volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004;
volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000;
volatile unsigned int *DWT_LAR = (volatile unsigned int *)0xE0001FB0;
volatile unsigned int *SCB_DHCSR = (volatile unsigned int *)0xE000EDF0;
volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC;
volatile unsigned int *ITM_TER = (volatile unsigned int *)0xE0000E00;
volatile unsigned int *ITM_TCR = (volatile unsigned int *)0xE0000E80;
 
//****************************************************************************
 
static int Debug_ITMDebug = 0;
 
//****************************************************************************
 
void EnableTiming(void)
{
 if ((*SCB_DHCSR & 1) && (*ITM_TER & 1)) // Enabled?
 Debug_ITMDebug = 1;
 
 *SCB_DEMCR |= 0x01000000;
 *DWT_LAR = 0xC5ACCE55; // enable access
 *DWT_CYCCNT = 0; // reset the counter
 *DWT_CONTROL |= 1 ; // enable the counter
}
 
//****************************************************************************
 
void Delay(uint32_t cycles)
{
 uint32_t start = *DWT_CYCCNT;
 
 while((*DWT_CYCCNT - start) < cycles);
}
 
//****************************************************************************

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
KiptonM
KiptonMAuthor
Senior III
October 15, 2021

Thank you that will work. Not a way I would have thought of, but I can work with that.

Is there a number somewhere in the system that I can use to convert the number of clocks to time?

I am looking for a number that tells me the period of the clock or the frequency of the clock used, so I can convert to time. Like nanoseconds, microseconds, or milliseconds?

Piranha
Principal III
October 20, 2021

The DWT counter runs with a CPU core clock. You can read it's frequency from the standard global SystemCoreClock variable or just use some compile time constant.