AM64x MCU+ SDK  09.02.00
PMU

The ARM Cortex R5F core includes logic to detect various events that can occur, for example a cache miss, cache access, etc. These events provide useful information about the behaviour of the processor that you can use when debugging or profiling code. The events are made visible on an output event bus and can be counted using registers in the Performance Monitoring Unit (PMU) of the core. This SW library is an abstraction to the PMU with APIs to profile code blocks.

The PMU consists of three event counting registers, one cycle counting register and 12 CP15 registers, for controlling and interrogating the counters. So in total four profiling metrics are possible for each profile point. Out of this one is fixed, the cycle counter. The other three are programmable to any of the events supported by the R5 core. For details of the events, please refer to the ARM Cortex R5F technical reference manual under section "Events and Performance Monitor"

Features Supported

The driver consists of a high-level interface offering the following features:

  • API to initialize profile object and counters
  • APIs to start and end profiling
  • APIs to print stats of a specific profile point or the all the profile points

Features NOT Supported

  • Sysconfig configurability of counters is not supported
  • Counter overflow is not handled (counters are reset for each profile point)

Example Usage

Include the below file to access the APIs

#include <stdio.h>
#include <drivers/pmu.h>

Sample configuration

PMU_EventCfg gPmuEventCfg[3] =
{
{
.name = "ICache Miss",
.type = CSL_ARM_R5_PMU_EVENT_TYPE_ICACHE_MISS,
},
{
.name = "DCache Access",
.type = CSL_ARM_R5_PMU_EVENT_TYPE_DCACHE_ACCESS,
},
{
.name = "DCache Miss",
.type = CSL_ARM_R5_PMU_EVENT_TYPE_DCACHE_MISS,
},
};
PMU_Config gPmuConfig =
{
.numEventCounters = 3U,
.eventCounters = gPmuEventCfg,
};

Initialization

PMU_init(&gPmuConfig);

Profiling sample

PMU_profileStart("Block1");
/* Code Block 1 */
uint32_t i, j, k = 0;
uint32_t arr[100] = { 0U };
for(i = 0; i < 100; i++)
{
for(j = 0; j < 100; j++)
{
arr[k] = i + j;
k = (k+1) % 100;
}
}
PMU_profileEnd("Block1");

For more details on usage, please refer PMU Multievent

API

APIs for PMU

PMU_profileStart
int32_t PMU_profileStart(const char *name)
Function to start profiling with the current configuration.
PMU_init
int32_t PMU_init(PMU_Config *cfg)
Function to initialize the PMU for profiling.
PMU_EventCfg
Data structure used in PMU_Config.
Definition: pmu.h:77
PMU_profileEnd
int32_t PMU_profileEnd(const char *name)
Function to end profiling with the current configuration.
PMU_Config
Data structure to be used with PMU_init.
Definition: pmu.h:90
PMU_Config::bCycleCounter
uint32_t bCycleCounter
Definition: pmu.h:91
PMU_EventCfg::name
const char * name
Definition: pmu.h:80