summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole
diff options
context:
space:
mode:
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2013-06-25 10:44:44 +0000
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2013-06-25 10:44:44 +0000
commitf69b82e91ad84c23abeaffada7ca14d06e4edc7a (patch)
tree642974a494a1a21f77762bc6d6800602a3df7189 /FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole
parent1b35701c1bfc1cb9741317346f0a3414031fce86 (diff)
downloadfreertos-f69b82e91ad84c23abeaffada7ca14d06e4edc7a.tar.gz
Re-implement the LPC18xx and SmartFusion2 run time stats implementation to use the free running Cortex-M cycle counter in place of the systick.
Correct the run-time stats counter implementation in the RZ demo. Guard against run time counters going backwards in tasks.c. git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@1946 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole')
-rw-r--r--FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole/RTOSDemo/RunTimeStatsTimer.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole/RTOSDemo/RunTimeStatsTimer.c b/FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole/RTOSDemo/RunTimeStatsTimer.c
index 0ce8bc630..ba195276f 100644
--- a/FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole/RTOSDemo/RunTimeStatsTimer.c
+++ b/FreeRTOS/Demo/CORTEX_SmartFusion2_M2S050_SoftConsole/RTOSDemo/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 vConfigureTimerForRunTimeStats( 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 ulGetRunTimeCounterValue( 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;
}
/*-----------------------------------------------------------*/