X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=FreeRTOS-Plus%2FDemo%2FFreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC%2FRunTimeStatsTimer.c;h=737552f2801c47f9821091e061825d3225a6e104;hb=4de4c70f3640e7d758494ab8719978bf2a5f33fb;hp=d32dea7ea8523ee93eae44a8d2dfc09931d4701a;hpb=0881313277d2a7242f19149fcf199f45c160e84e;p=freertos diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/RunTimeStatsTimer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/RunTimeStatsTimer.c index d32dea7ea..737552f28 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/RunTimeStatsTimer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/RunTimeStatsTimer.c @@ -74,65 +74,72 @@ /* FreeRTOS includes. */ #include "FreeRTOS.h" -#include "task.h" /* Utility functions to implement run time stats on Cortex-M CPUs. The collected run time data can be viewed through the CLI interface. See the following URL for more information on run time stats: http://www.freertos.org/rtos-run-time-stats.html */ -/* Used in the run time stats calculations. */ -static uint32_t ulClocksPer10thOfAMilliSecond = 0UL; +/* Addresses of registers in the Cortex-M debug hardware. */ +#define rtsDWT_CYCCNT ( *( ( unsigned long * ) 0xE0001004 ) ) +#define rtsDWT_CONTROL ( *( ( unsigned long * ) 0xE0001000 ) ) +#define rtsSCB_DEMCR ( *( ( unsigned long * ) 0xE000EDFC ) ) +#define rtsTRCENA_BIT ( 0x01000000UL ) +#define rtsCOUNTER_ENABLE_BIT ( 0x01UL ) + +/* Simple shift divide for scaling to avoid an overflow occurring too soon. The +number of bits to shift depends on the clock speed. */ +#define runtimeSLOWER_CLOCK_SPEEDS ( 70000000UL ) +#define runtimeSHIFT_13 13 +#define runtimeOVERFLOW_BIT_13 ( 1UL << ( 32UL - runtimeSHIFT_13 ) ) +#define runtimeSHIFT_14 14 +#define runtimeOVERFLOW_BIT_14 ( 1UL << ( 32UL - runtimeSHIFT_14 ) ) +/*-----------------------------------------------------------*/ void vMainConfigureTimerForRunTimeStats( void ) { - /* How many clocks are there per tenth of a millisecond? */ - ulClocksPer10thOfAMilliSecond = configCPU_CLOCK_HZ / 10000UL; + /* Enable TRCENA. */ + rtsSCB_DEMCR = rtsSCB_DEMCR | rtsTRCENA_BIT; + + /* Reset counter. */ + rtsDWT_CYCCNT = 0; + + /* Enable counter. */ + rtsDWT_CONTROL = rtsDWT_CONTROL | rtsCOUNTER_ENABLE_BIT; } /*-----------------------------------------------------------*/ uint32_t ulMainGetRunTimeCounterValue( void ) { -uint32_t ulSysTickCounts, ulTickCount, ulReturn; -const uint32_t ulSysTickReloadValue = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; -volatile uint32_t * const pulCurrentSysTickCount = ( ( volatile uint32_t *) 0xe000e018 ); -volatile uint32_t * const pulInterruptCTRLState = ( ( volatile uint32_t *) 0xe000ed04 ); -const uint32_t ulSysTickPendingBit = 0x04000000UL; - - /* NOTE: There are potentially race conditions here. However, it is used - anyway to keep the examples simple, and to avoid reliance on a separate - timer peripheral. */ - - - /* The SysTick is a down counter. How many clocks have passed since it was - last reloaded? */ - ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount; +static unsigned long ulLastCounterValue = 0UL, ulOverflows = 0; +unsigned long ulValueNow; - /* How many times has it overflowed? */ - ulTickCount = xTaskGetTickCountFromISR(); + ulValueNow = rtsDWT_CYCCNT; - /* Is there a SysTick interrupt pending? */ - if( ( *pulInterruptCTRLState & ulSysTickPendingBit ) != 0UL ) + /* Has the value overflowed since it was last read. */ + if( ulValueNow < ulLastCounterValue ) { - /* There is a SysTick interrupt pending, so the SysTick has overflowed - but the tick count not yet incremented. */ - ulTickCount++; - - /* Read the SysTick again, as the overflow might have occurred since - it was read last. */ - ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount; + ulOverflows++; } + ulLastCounterValue = ulValueNow; - /* Convert the tick count into tenths of a millisecond. THIS ASSUMES - configTICK_RATE_HZ is 1000! */ - ulReturn = ( ulTickCount * 10UL ) ; + /* Cannot use configCPU_CLOCK_HZ directly as it may itself not be a constant + but instead map to a variable that holds the clock speed. */ - /* Add on the number of tenths of a millisecond that have passed since the - tick count last got updated. */ - ulReturn += ( ulSysTickCounts / ulClocksPer10thOfAMilliSecond ); + /* There is no prescale on the counter, so simulate in software. */ + if( configCPU_CLOCK_HZ < runtimeSLOWER_CLOCK_SPEEDS ) + { + ulValueNow >>= runtimeSHIFT_13; + ulValueNow += ( runtimeOVERFLOW_BIT_13 * ulOverflows ); + } + else + { + ulValueNow >>= runtimeSHIFT_14; + ulValueNow += ( runtimeOVERFLOW_BIT_14 * ulOverflows ); + } - return ulReturn; + return ulValueNow; } /*-----------------------------------------------------------*/