in AVR_Dx_Atmel_Studio/RTOSDemo/TraceRecorder/trcSnapshotRecorder.c [2963:3070]
void prvTracePortGetTimeStamp(uint32_t *pTimestamp)
{
static uint32_t last_hwtc_count = 0;
uint32_t hwtc_count = 0;
#if TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR
/* systick based timer */
static uint32_t last_traceTickCount = 0;
uint32_t traceTickCount = 0;
#else /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/
/* Free running timer */
static uint32_t last_hwtc_rest = 0;
uint32_t diff = 0;
uint32_t diff_scaled = 0;
#endif /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/
if (trace_disable_timestamp == 1)
{
if (pTimestamp)
*pTimestamp = last_timestamp;
return;
}
/* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */
#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR)
/* Get the increasing tick count */
hwtc_count = (TRC_HWTC_COUNT);
#elif (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR)
/* Convert decreasing tick count into increasing tick count */
hwtc_count = (TRC_HWTC_PERIOD) - (TRC_HWTC_COUNT);
#else
#error "TRC_HWTC_TYPE has unexpected value"
#endif
#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
/* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn
uses QueryPerformanceCounter. That function is not always reliable when used over
multiple threads. We must therefore handle rare cases where the timestamp is less
than the previous. In practice, this should "never" roll over since the
performance counter is 64 bit wide. */
if (last_hwtc_count > hwtc_count)
{
hwtc_count = last_hwtc_count;
}
#endif
#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)
/* Timestamping is based on a timer that wraps at TRC_HWTC_PERIOD */
if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
{
/* This means last_traceTickCount is higher than uiTraceTickCount,
so we have previously compensated for a missed tick.
Therefore we use the last stored value because that is more accurate. */
traceTickCount = last_traceTickCount;
}
else
{
/* Business as usual */
traceTickCount = uiTraceTickCount;
}
/* Check for overflow. May occur if the update of uiTraceTickCount has been
delayed due to disabled interrupts. */
if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)
{
/* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */
traceTickCount++;
}
/* Check if the return address is OK, then we perform the calculation. */
if (pTimestamp)
{
/* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
last_timestamp = traceTickCount * ((TRC_HWTC_PERIOD) / (TRC_HWTC_DIVISOR));
/* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */
last_timestamp += (hwtc_count + traceTickCount * ((TRC_HWTC_PERIOD) % (TRC_HWTC_DIVISOR))) / (TRC_HWTC_DIVISOR);
}
/* Store the previous value */
last_traceTickCount = traceTickCount;
#else /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/
/* Timestamping is based on a free running timer */
/* This part handles free running clocks that can be scaled down to avoid too large DTS values.
Without this, the scaled timestamp will incorrectly wrap at (2^32 / TRC_HWTC_DIVISOR) ticks.
The scaled timestamp returned from this function is supposed to go from 0 -> 2^32, which in real time would represent (0 -> 2^32 * TRC_HWTC_DIVISOR) ticks. */
/* First we see how long time has passed since the last timestamp call, and we also add the ticks that was lost when we scaled down the last time. */
diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest;
/* Scale down the diff */
diff_scaled = diff / (TRC_HWTC_DIVISOR);
/* Find out how many ticks were lost when scaling down, so we can add them the next time */
last_hwtc_rest = diff % (TRC_HWTC_DIVISOR);
/* We increase the scaled timestamp by the scaled amount */
last_timestamp += diff_scaled;
#endif /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/
/* Is anyone interested in the results? */
if (pTimestamp)
*pTimestamp = last_timestamp;
/* Store the previous value */
last_hwtc_count = hwtc_count;
}