]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHardwarePort.c
+ New feature added: Task notifications.
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-Trace / trcHardwarePort.c
index ac4a6f263b6159c99edbb8e3897cd8b04fb7a283..7d3937b4aa92c2ce2dd28456c42d369901afe8c8 100644 (file)
@@ -1,5 +1,5 @@
 /******************************************************************************* \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
@@ -32,7 +32,9 @@
  * 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
@@ -56,36 +58,37 @@ uint32_t last_timestamp = 0;
  ******************************************************************************/\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
@@ -109,10 +112,10 @@ void prvTraceInitCortexM()
 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
@@ -120,51 +123,64 @@ void vTracePortGetTimeStamp(uint32_t *pTimestamp)
                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