1 /*******************************************************************************
\r
2 * Tracealyzer v2.5.0 Recorder Library
\r
3 * Percepio AB, www.percepio.com
\r
7 * Contains together with trcHardwarePort.h all hardware portability issues of
\r
8 * the trace recorder library.
\r
11 * This software is copyright Percepio AB. The recorder library is free for
\r
12 * use together with Percepio products. You may distribute the recorder library
\r
13 * in its original form, including modifications in trcPort.c and trcPort.h
\r
14 * given that these modification are clearly marked as your own modifications
\r
15 * and documented in the initial comment section of these source files.
\r
16 * This software is the intellectual property of Percepio AB and may not be
\r
17 * sold or in other ways commercially redistributed without explicit written
\r
18 * permission by Percepio AB.
\r
21 * The trace tool and recorder library is being delivered to you AS IS and
\r
22 * Percepio AB makes no warranty as to its use or performance. Percepio AB does
\r
23 * not and cannot warrant the performance or results you may obtain by using the
\r
24 * software or documentation. Percepio AB make no warranties, express or
\r
25 * implied, as to noninfringement of third party rights, merchantability, or
\r
26 * fitness for any particular purpose. In no event will Percepio AB, its
\r
27 * technology partners, or distributors be liable to you for any consequential,
\r
28 * incidental or special damages, including any lost profits or lost savings,
\r
29 * even if a representative of Percepio AB has been advised of the possibility
\r
30 * of such damages, or for any claim by any third party. Some jurisdictions do
\r
31 * not allow the exclusion or limitation of incidental, consequential or special
\r
32 * damages, or the exclusion of implied warranties or limitations on how long an
\r
33 * implied warranty may last, so the above limitations may not apply to you.
\r
35 * Copyright Percepio AB, 2013.
\r
37 ******************************************************************************/
\r
39 #include "trcHardwarePort.h"
\r
41 #if (USE_TRACEALYZER_RECORDER == 1)
\r
45 uint32_t trace_disable_timestamp = 0;
\r
46 uint32_t last_timestamp = 0;
\r
48 /*******************************************************************************
\r
51 * This variable is should be updated by the Kernel tick interrupt. This does
\r
52 * not need to be modified when developing a new timer port. It is preferred to
\r
53 * keep any timer port changes in the HWTC macro definitions, which typically
\r
54 * give sufficient flexibility.
\r
55 ******************************************************************************/
\r
56 uint32_t uiTraceTickCount = 0;
\r
58 /******************************************************************************
\r
59 * vTracePortGetTimeStamp
\r
61 * Returns the current time based on the HWTC macros which provide a hardware
\r
62 * isolation layer towards the hardware timer/counter.
\r
64 * The HWTC macros and vTracePortGetTimeStamp is the main porting issue
\r
65 * or the trace recorder library. Typically you should not need to change
\r
66 * the code of vTracePortGetTimeStamp if using the HWTC macros.
\r
68 ******************************************************************************/
\r
69 void vTracePortGetTimeStamp(uint32_t *pTimestamp)
\r
71 static uint32_t last_traceTickCount = 0;
\r
72 static uint32_t last_hwtc_count = 0;
\r
73 uint32_t traceTickCount = 0;
\r
74 uint32_t hwtc_count = 0;
\r
76 if (trace_disable_timestamp == 1)
\r
79 *pTimestamp = last_timestamp;
\r
83 /* Retrieve HWTC_COUNT only once since the same value should be used all throughout this function. */
\r
84 #if (HWTC_COUNT_DIRECTION == DIRECTION_INCREMENTING)
\r
85 hwtc_count = HWTC_COUNT;
\r
86 #elif (HWTC_COUNT_DIRECTION == DIRECTION_DECREMENTING)
\r
87 hwtc_count = HWTC_PERIOD - HWTC_COUNT;
\r
89 Junk text to cause compiler error - HWTC_COUNT_DIRECTION is not set correctly!
\r
90 Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING
\r
93 if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
\r
95 /* This means last_traceTickCount is higher than uiTraceTickCount,
\r
96 so we have previously compensated for a missed tick.
\r
97 Therefore we use the last stored value because that is more accurate. */
\r
98 traceTickCount = last_traceTickCount;
\r
102 /* Business as usual */
\r
103 traceTickCount = uiTraceTickCount;
\r
106 /* Check for overflow. May occur if the update of uiTraceTickCount has been
\r
107 delayed due to disabled interrupts. */
\r
108 if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)
\r
110 /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */
\r
114 /* Check if the return address is OK, then we perform the calculation. */
\r
117 /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
\r
118 *pTimestamp = traceTickCount * (HWTC_PERIOD / HWTC_DIVISOR);
\r
119 /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / HWTC_DIVISOR. */
\r
120 *pTimestamp += (hwtc_count + traceTickCount * (HWTC_PERIOD % HWTC_DIVISOR)) / HWTC_DIVISOR;
\r
122 last_timestamp = *pTimestamp;
\r
125 /* Store the previous values. */
\r
126 last_traceTickCount = traceTickCount;
\r
127 last_hwtc_count = hwtc_count;
\r