Hello Francessco,
as mentioned within the referred article, the performance counter functionality requires the target system to provide a high precision timer. For that purpose the function EwGetPerfCounter() in the module ewextrte.c has to be implemented.
Within your implementation you are using EwGetTicks() - which has a resolution in milliseconds. However, the performance measurement is based on microseconds. In order to get reliable measurements you need a more precise time source than EwGetTicks().
I just made an implementation of EwGetPerfCounter() based on the DWT cycle counter (which has a frequency of 400 MHz on the STM32H743 Evalboard). In principle the following implementation works fine - allthough the cycle counter register overflows after a couple of seconds.
Please make the following changes within your ewextrte.c file. First add some includes:
#include "stm32h7xx_hal.h"
#include "stm32h743i_eval.h"
Replace your EwGetPerfCounter implementation with the following code:
#ifdef EW_PRINT_PERF_COUNTERS
/* variables for cycle counter */
static unsigned long PrevCycCnt = 0;
static unsigned long MicroSeconds = 0;
static unsigned long Seconds = 0;
/* helper function to initialize measuring unit (cycle counter) */
static void CycleCounterInit( void )
{
/* Enable TRC */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
/* Unlock DWT registers */
if ((*(uint32_t*)0xE0001FB4) & 1)
*(uint32_t*)0xE0001FB0 = 0xC5ACCE55;
/* clear the cycle counter */
DWT->CYCCNT = 0;
/* start the cycle counter */
DWT->CTRL = 0x40000001;
/* initialize counters */
PrevCycCnt = 0;
}
/* helper function to get cycle counter value since last call */
static unsigned long GetCycleCounterDelta( void )
{
unsigned long cycCnt;
unsigned long result;
/* get delta between current counter value and last counter value */
cycCnt = DWT->CYCCNT;
result = cycCnt - PrevCycCnt;
PrevCycCnt = cycCnt;
return result;
}
/*******************************************************************************
* FUNCTION:
* EwGetPerfCounter
*
* DESCRIPTION:
* The function EwGetPerfCounter() should return the current time as number of
* seconds and microseconds. The reference time point is nonrelevant.
*
* ARGUMENTS:
* aSeconds - Pointer to a variable where the current time is stored.
* aMicroseconds - Pointer to a variable where the current time is stored.
* aCPUMicroseconds - Pointer to a variable where the real CPU usage is stored.
*
* RETURN VALUE:
* None
*
*******************************************************************************/
void EwGetPerfCounter( unsigned long* aSeconds, unsigned long* aMicroSeconds,
unsigned long* aCPUMicroseconds )
{
static char initialized = 0;
if ( !initialized )
{
CycleCounterInit();
initialized = 1;
}
MicroSeconds += GetCycleCounterDelta() / 400; /* running with 400 MHz */
if ( MicroSeconds > 1000000 )
{
MicroSeconds -= 1000000;
Seconds++;
}
/* return seconds and milliseconds */
*aSeconds = Seconds;
*aMicroSeconds = MicroSeconds;
if ( aCPUMicroseconds )
*aCPUMicroseconds = MicroSeconds;
}
#endif
Within ewmain.c you have to modify the main loop in order to reset and print the measurement results:
if ( CoreRoot__DoesNeedUpdate( RootObject ))
{
EwResetPerfCounters();
EwUpdate( Viewport, RootObject );
EwPrintPerfCounters();
}
Don't forget to define EW_PRINT_PERF_COUNTERS within your makefile and to rebuild the entire project (using source codes of GFX and RTE)!
Now you should get the expected performance measurements on your target...
I hope this helps.
Best regards,
Manfred