cancel
Showing results for 
Search instead for 
Did you mean: 

CPU Load using Ulink Pro

Manoj Chandran
Associate II
Posted on October 11, 2017 at 16:13

Hi,

We are using STM32F479 processor in our design. We want to calculate the CPU load using Ulink Pro. We are unable to get the performance analysis using ulink pro when the system clock is 168MHz (system_stm32f4xx.c - (DFP 1.0.7)). If the system clock is configured to  140 MHz or lesser, it is working. Could any one please help to sort out the issue. One point is, we have select device as STM32F439 in keil since we are using older version of keil and it supports processor only upto STM32F439.

5 REPLIES 5
Posted on October 11, 2017 at 16:58

One would bench performance internally using DWT_CYCCNT, which will be fine >200 MHz

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on October 12, 2017 at 07:14

Hi Clive,

Thank you for the response.  We want to calculate is total CPU load of the actual application and also the code coverage of the program. Using ulink pro, when the SystemClockfrequency is set to less than 120MHz (PLL_N 240 and PLL_P 2) we are able to get the details but when set to 168MHz (frequency above 120MHz) we are unable to get the code coverage and Performance analysis. 

Regards,

Manoj

Posted on October 12, 2017 at 14:21

Yes, no doubt because you've hit the bandwidth limit of the probe. You're going to have to either scale the numbers, or change your approach.

I'd suggest you instrument the code so you can count cycles across routine enter/exit points. You could also use GPIO pins and a scope to monitor loading, for example around a WFI loop in your idle routine.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on October 12, 2017 at 16:15

Hi Clive,

.

But with same ulink pro I was able to take the performance and code coverage of STM32F407 processor working at 168 MHz. When I ported the code to STM32F479  processor, we are finding issue in taking code coverage and performance analysis. We are using DFP 1.0.7. could you please help to configure the clock of STM32F479 to 168 MHz.The function used is attached below (system_stm32f4xx.c)

/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */

&sharpdefine PLL_M 25

/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */

&sharpdefine PLL_Q 7

&sharpif defined (STM32F40_41xxx)

&sharpdefine PLL_N 336

/* SYSCLK = PLL_VCO / PLL_P */

&sharpdefine PLL_P 2

&sharpendif /* STM32F40_41xxx */

&sharpif defined (STM32F427_437xx) || defined (STM32F429_439xx)

&sharpdefine PLL_N 336

/* SYSCLK = PLL_VCO / PLL_P */

&sharpdefine PLL_P 2

&sharpendif /* STM32F427_437x || STM32F429_439xx */

&sharpif defined (STM32F401xx)

&sharpdefine PLL_N 336

/* SYSCLK = PLL_VCO / PLL_P */

&sharpdefine PLL_P 4

&sharpendif /* STM32F401xx */

/******************************************************************************/

/**

* @}

*/

/** @addtogroup STM32F4xx_System_Private_Macros

* @{

*/

/**

* @}

*/

/** @addtogroup STM32F4xx_System_Private_Variables

* @{

*/

&sharpif defined (STM32F40_41xxx)

uint32_t SystemCoreClock = 168000000;

&sharpendif /* STM32F40_41xxx */

&sharpif defined (STM32F427_437xx) || defined (STM32F429_439xx)

uint32_t SystemCoreClock = 168000000;

// uint32_t SystemCoreClock = 180000000;

&sharpendif /* STM32F427_437x || STM32F429_439xx */

&sharpif defined (STM32F401xx)

uint32_t SystemCoreClock = 84000000;

&sharpendif /* STM32F401xx */

__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};

/**

* @}

*/

/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes

* @{

*/

static void SetSysClock(void);

&sharpif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) || defined (PREMAIN_FSMC_SETUP) /* Keil */

static void SystemInit_ExtMemCtl(void);

&sharpendif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM || defined (PREMAIN_FSMC_SETUP) */ /* Keil */

/**

* @}

*/

/** @addtogroup STM32F4xx_System_Private_Functions

* @{

*/

/**

* @brief Setup the microcontroller system

* Initialize the Embedded Flash Interface, the PLL and update the

* SystemFrequency variable.

* @param None

* @retval None

*/

void SystemInit(void)

{

/* FPU settings ------------------------------------------------------------*/

&sharpif (__FPU_PRESENT == 1) && (__FPU_USED == 1)

SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */

&sharpendif

/* Reset the RCC clock configuration to the default reset state ------------*/

/* Set HSION bit */

RCC->CR |= (uint32_t)0x00000001;

/* Reset CFGR register */

RCC->CFGR = 0x00000000;

/* Reset HSEON, CSSON and PLLON bits */

RCC->CR &= (uint32_t)0xFEF6FFFF;

/* Reset PLLCFGR register */

RCC->PLLCFGR = 0x24003010;

/* Reset HSEBYP bit */

RCC->CR &= (uint32_t)0xFFFBFFFF;

/* Disable all interrupts */

RCC->CIR = 0x00000000;

&sharpif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) || defined (PREMAIN_FSMC_SETUP) /* Keil */

SystemInit_ExtMemCtl();

&sharpendif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM || defined (PREMAIN_FSMC_SETUP) */ /* Keil */

/* Configure the System clock source, PLL Multiplier and Divider factors,

AHB/APBx prescalers and Flash settings ----------------------------------*/

SetSysClock();

/* Configure the Vector Table location add offset address ------------------*/

&sharpifdef VECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */

&sharpelse

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */

&sharpendif

}

static void SetSysClock(void)

{

/******************************************************************************/

/* PLL (clocked by HSE) used as System clock source */

/******************************************************************************/

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

/* Enable HSE */

RCC->CR |= ((uint32_t)RCC_CR_HSEON);

/* Wait till HSE is ready and if Time out is reached exit */

do

{

HSEStatus = RCC->CR & RCC_CR_HSERDY;

StartUpCounter++;

} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

if ((RCC->CR & RCC_CR_HSERDY) != RESET)

{

HSEStatus = (uint32_t)0x01;

}

else

{

HSEStatus = (uint32_t)0x00;

}

if (HSEStatus == (uint32_t)0x01)

{

/* Select regulator voltage output Scale 1 mode */

RCC->APB1ENR |= RCC_APB1ENR_PWREN;

PWR->CR |= PWR_CR_VOS;

/* HCLK = SYSCLK / 1*/

RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

&sharpif defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)

/* PCLK2 = HCLK / 2*/

RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

/* PCLK1 = HCLK / 4*/

RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

&sharpendif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */

&sharpif defined (STM32F401xx)

/* PCLK2 = HCLK / 2*/

RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;

/* PCLK1 = HCLK / 4*/

RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;

&sharpendif /* STM32F401xx */

/* Configure the main PLL */

RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

/* Enable the main PLL */

RCC->CR |= RCC_CR_PLLON;

/* Wait till the main PLL is ready */

while((RCC->CR & RCC_CR_PLLRDY) == 0)

{

}

&sharpif defined (STM32F427_437xx) || defined (STM32F429_439xx)

/* Enable the Over-drive to extend the clock frequency to 180 Mhz */

PWR->CR |= PWR_CR_ODEN;

while((PWR->CSR & PWR_CSR_ODRDY) == 0)

{

}

PWR->CR |= PWR_CR_ODSWEN;

while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)

{

}

/* Configure Flash prefetch, Instruction cache, Data cache and wait state */

FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

&sharpendif /* STM32F427_437x || STM32F429_439xx */

&sharpif defined (STM32F40_41xxx)

/* Configure Flash prefetch, Instruction cache, Data cache and wait state */

FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

&sharpendif /* STM32F40_41xxx */

&sharpif defined (STM32F401xx)

/* Configure Flash prefetch, Instruction cache, Data cache and wait state */

FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;

&sharpendif /* STM32F401xx */

/* Select the main PLL as system clock source */

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

RCC->CFGR |= RCC_CFGR_SW_PLL;

/* Wait till the main PLL is used as system clock source */

while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);

{

}

}

else

{ /* If HSE fails to start-up, the application will have wrong clock

configuration. User can add here some code to deal with this error */

}

}

Posted on October 12, 2017 at 17:01

Feel free to declutter system_stm32f4xx.c so the behaviour is clear and unambigous.

I avoid a lot of the define nonsense, and compute the initial SystemCoreClock in a way less prone to breaking. I let the compiler do it's job

&sharpifdef PLL_SOURCE_HSI

  uint32_t SystemCoreClock = (((HSI_VALUE / PLL_M) * PLL_N) / PLL_P);

&sharpelse

  uint32_t SystemCoreClock = (((HSE_VALUE / PLL_M) * PLL_N) / PLL_P);

&sharpendif

I also identify the Core ID and set the clocks appropriately, but this does require the value to be recomputed in main()

int main(void)

{

  SystemCoreClockUpdate(); /* Update as runtime wipes statics */

...

}

I also make it a habit to print out current configuration, so no one is confused and the settings match those provided to the trace probe.

{

  RCC_ClocksTypeDef RCC_Clocks;

  printf('%08X\n', DBGMCU->IDCODE);

  printf('%d\n', SystemCoreClock);

  RCC_GetClocksFreq(&RCC_Clocks);

  printf('SYS:%d H:%d, P1:%d, P2:%d\r\n',

    RCC_Clocks.SYSCLK_Frequency,

    RCC_Clocks.HCLK_Frequency, // AHB

    RCC_Clocks.PCLK1_Frequency, // APB1

    RCC_Clocks.PCLK2_Frequency); // APB2

}

You might want to discuss further with your support contacts at KEIL and ST

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..