/******************************************************************************* \r
- * Tracealyzer v2.6.0 Recorder Library\r
+ * Tracealyzer v2.7.0 Recorder Library\r
* Percepio AB, www.percepio.com\r
*\r
* trcHardwarePort.c\r
* damages, or the exclusion of implied warranties or limitations on how long an \r
* implied warranty may last, so the above limitations may not apply to you.\r
*\r
- * Copyright Percepio AB, 2013.\r
+ * Tabs are used for indent in this file (1 tab = 4 spaces)\r
+ *\r
+ * Copyright Percepio AB, 2014.\r
* www.percepio.com\r
******************************************************************************/\r
\r
******************************************************************************/\r
uint32_t uiTraceTickCount = 0;\r
\r
-uint32_t DWT_CYCLES_ADDED = 0;\r
+uint32_t DWT_CYCLES_ADDED = 0; /* Used on ARM Cortex-M only */\r
\r
#if (SELECTED_PORT == PORT_ARM_CortexM)\r
\r
-void prvTraceEnableIRQ(void)\r
-{\r
- asm volatile ("cpsie i");\r
-}\r
-\r
-void prvTraceDisableIRQ(void)\r
-{\r
- asm volatile ("cpsid i");\r
-}\r
-\r
-void prvTraceSetIRQMask(uint32_t priMask)\r
+void prvTraceInitCortexM()\r
{\r
- asm volatile ("MSR primask, %0" : : "r" (priMask) );\r
-}\r
+ /* Make sure DWT is enabled is enabled, if supported */\r
+ REG_DEMCR |= DEMCR_TRCENA;\r
+\r
+ do{\r
+ /* Verify that DWT is supported */\r
+ if (REG_DEMCR == 0)\r
+ {\r
+ vTraceError("DWT not supported by this chip!");\r
+ break;\r
+ }\r
+\r
+ /* Verify that DWT_CYCCNT is supported */\r
+ if (REG_DWT_CTRL & DWT_CTRL_NOCYCCNT)\r
+ {\r
+ vTraceError("DWT_CYCCNT not supported by this chip!");\r
+ break;\r
+ }\r
+ \r
+ /* Reset the cycle counter */\r
+ REG_DWT_CYCCNT = 0;\r
\r
-uint32_t prvTraceGetIRQMask(void)\r
-{\r
- uint32_t result;\r
- asm volatile ("MRS %0, primask" : "=r" (result) );\r
- return result;\r
-}\r
+ /* Enable the cycle counter */\r
+ REG_DWT_CTRL |= DWT_CTRL_CYCCNTENA;\r
\r
-void prvTraceInitCortexM()\r
-{\r
- DWT_CTRL_REG |= 1; /* Enable the cycle counter */\r
- DWT_CYCLE_COUNTER = 0;\r
+ }while(0); /* breaks above jump here */\r
\r
if (RecorderDataPtr->frequency == 0)\r
{ \r
void vTracePortGetTimeStamp(uint32_t *pTimestamp)\r
{\r
static uint32_t last_traceTickCount = 0;\r
- static uint32_t last_hwtc_count = 0;\r
- uint32_t traceTickCount = 0;\r
- uint32_t hwtc_count = 0;\r
- \r
+ static uint32_t last_hwtc_count = 0;\r
+ uint32_t traceTickCount = 0;\r
+ uint32_t hwtc_count = 0;\r
+ \r
if (trace_disable_timestamp == 1)\r
{\r
if (pTimestamp)\r
return;\r
}\r
\r
- /* Retrieve HWTC_COUNT only once since the same value should be used all throughout this function. */\r
+ /* Retrieve HWTC_COUNT only once since the same value should be used all throughout this function. */\r
#if (HWTC_COUNT_DIRECTION == DIRECTION_INCREMENTING)\r
- hwtc_count = HWTC_COUNT;\r
+ hwtc_count = HWTC_COUNT;\r
#elif (HWTC_COUNT_DIRECTION == DIRECTION_DECREMENTING)\r
- hwtc_count = HWTC_PERIOD - HWTC_COUNT;\r
+ hwtc_count = HWTC_PERIOD - HWTC_COUNT;\r
#else\r
- Junk text to cause compiler error - HWTC_COUNT_DIRECTION is not set correctly!\r
- Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING\r
+ Junk text to cause compiler error - HWTC_COUNT_DIRECTION is not set correctly!\r
+ Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING\r
#endif\r
- \r
- if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)\r
- {\r
- /* This means last_traceTickCount is higher than uiTraceTickCount,\r
- so we have previously compensated for a missed tick.\r
- Therefore we use the last stored value because that is more accurate. */\r
- traceTickCount = last_traceTickCount;\r
- }\r
- else\r
- {\r
- /* Business as usual */\r
- traceTickCount = uiTraceTickCount;\r
- }\r
-\r
- /* Check for overflow. May occur if the update of uiTraceTickCount has been \r
- delayed due to disabled interrupts. */\r
- if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)\r
- {\r
- /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */\r
- traceTickCount++;\r
- }\r
- \r
- /* Check if the return address is OK, then we perform the calculation. */\r
- if (pTimestamp)\r
- {\r
- /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */\r
- *pTimestamp = traceTickCount * (HWTC_PERIOD / HWTC_DIVISOR);\r
- /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / HWTC_DIVISOR. */\r
- *pTimestamp += (hwtc_count + traceTickCount * (HWTC_PERIOD % HWTC_DIVISOR)) / HWTC_DIVISOR;\r
+\r
+#if (SELECTED_PORT == PORT_Win32)\r
+ /* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn \r
+ uses QueryPerformanceCounter. That function is not always reliable when used over \r
+ multiple threads. We must therefore handle rare cases where the timestamp is less\r
+ than the previous. In practice, the Win32 should "never" roll over since the \r
+ performance counter is 64 bit wide. */\r
+ \r
+ if (last_hwtc_count > hwtc_count)\r
+ {\r
+ hwtc_count = last_hwtc_count;\r
+ }\r
+#endif\r
+\r
+ if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)\r
+ {\r
+ /* This means last_traceTickCount is higher than uiTraceTickCount,\r
+ so we have previously compensated for a missed tick.\r
+ Therefore we use the last stored value because that is more accurate. */\r
+ traceTickCount = last_traceTickCount;\r
+ }\r
+ else\r
+ {\r
+ /* Business as usual */\r
+ traceTickCount = uiTraceTickCount;\r
+ }\r
+\r
+ /* Check for overflow. May occur if the update of uiTraceTickCount has been \r
+ delayed due to disabled interrupts. */\r
+ if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)\r
+ {\r
+ /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */\r
+ traceTickCount++;\r
+ }\r
+ \r
+ /* Check if the return address is OK, then we perform the calculation. */\r
+ if (pTimestamp)\r
+ {\r
+ /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */\r
+ *pTimestamp = traceTickCount * (HWTC_PERIOD / HWTC_DIVISOR);\r
+ /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / HWTC_DIVISOR. */\r
+ *pTimestamp += (hwtc_count + traceTickCount * (HWTC_PERIOD % HWTC_DIVISOR)) / HWTC_DIVISOR;\r
\r
last_timestamp = *pTimestamp;\r
- }\r
- \r
- /* Store the previous values. */\r
- last_traceTickCount = traceTickCount;\r
- last_hwtc_count = hwtc_count;\r
+ }\r
+ \r
+ /* Store the previous values. */\r
+ last_traceTickCount = traceTickCount;\r
+ last_hwtc_count = hwtc_count;\r
}\r
\r
-#endif
\ No newline at end of file
+#endif\r