/******************************************************************************* * FreeRTOS+Trace v2.3.0 Recorder Library * Percepio AB, www.percepio.com * * trcPort.c * * Contains all portability issues of the trace recorder library. * See also trcPort.h, where port-specific macros are defined. * * Terms of Use * This software is copyright Percepio AB. The recorder library is free for * use together with Percepio products. You may distribute the recorder library * in its original form, including modifications in trcPort.c and trcPort.h * given that these modification are clearly marked as your own modifications * and documented in the initial comment section of these source files. * This software is the intellectual property of Percepio AB and may not be * sold or in other ways commercially redistributed without explicit written * permission by Percepio AB. * * Disclaimer * The trace tool and recorder library is being delivered to you AS IS and * Percepio AB makes no warranty as to its use or performance. Percepio AB does * not and cannot warrant the performance or results you may obtain by using the * software or documentation. Percepio AB make no warranties, express or * implied, as to noninfringement of third party rights, merchantability, or * fitness for any particular purpose. In no event will Percepio AB, its * technology partners, or distributors be liable to you for any consequential, * incidental or special damages, including any lost profits or lost savings, * even if a representative of Percepio AB has been advised of the possibility * of such damages, or for any claim by any third party. Some jurisdictions do * not allow the exclusion or limitation of incidental, consequential or special * damages, or the exclusion of implied warranties or limitations on how long an * implied warranty may last, so the above limitations may not apply to you. * * OFFER FROM PERCEPIO: * For silicon companies and non-corporate FreeRTOS users (researchers, students * , hobbyists or early-phase startups) we have an attractive offer: * Provide a hardware timer port and get a FREE single-user licence for * FreeRTOS+Trace Professional Edition. Read more about this offer at * www.percepio.com or contact us directly at support@percepio.com. * * FreeRTOS+Trace is available as Free Edition and in two premium editions. * You may use the premium features during 30 days for evaluation. * Download FreeRTOS+Trace at http://www.percepio.com/products/downloads/ * * Copyright Percepio AB, 2012. * www.percepio.com ******************************************************************************/ #include "trcUser.h" #if (configUSE_TRACE_FACILITY == 1) #if (INCLUDE_SAVE_TO_FILE == 1) static char* prvFileName = NULL; #endif /******************************************************************************* * uiTraceTickCount * * This variable is updated by the traceTASK_INCREMENT_TICK macro in the * FreeRTOS tick handler. This does not need to be modified when developing a * new timer port. It is prefered to keep any timer port changes in the HWTC * macro definitions, which typically give sufficient flexibility. ******************************************************************************/ uint32_t uiTraceTickCount = 0; /****************************************************************************** * uiTracePortGetTimeStamp * * Returns the current time based on the HWTC macros which provide a hardware * isolation layer towards the hardware timer/counter. * * The HWTC macros and uiTracePortGetTimeStamp is the main porting issue * or the trace recorder library. Typically you should not need to change * the code of uiTracePortGetTimeStamp if using the HWTC macros. * * OFFER FROM PERCEPIO: * For silicon companies and non-corporate FreeRTOS users (researchers, students * , hobbyists or early-phase startups) we have an attractive offer: * Provide a hardware timer port and get a FREE single-user license for * FreeRTOS+Trace Professional Edition. Read more about this offer at * www.percepio.com or contact us directly at support@percepio.com. ******************************************************************************/ void uiTracePortGetTimeStamp(uint32_t *pTimestamp) { static uint32_t last_traceTickCount = 0; static uint32_t last_hwtc_count = 0; uint32_t traceTickCount = 0; uint32_t hwtc_count = 0; /* Retrieve HWTC_COUNT only once since the same value should be used all throughout this function. */ #if (HWTC_COUNT_DIRECTION == DIRECTION_INCREMENTING) hwtc_count = HWTC_COUNT; #elif (HWTC_COUNT_DIRECTION == DIRECTION_DECREMENTING) hwtc_count = HWTC_PERIOD - HWTC_COUNT; #else Junk text to cause compiler error - HWTC_COUNT_DIRECTION is not set correctly! Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING #endif 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. */ *pTimestamp = traceTickCount * (HWTC_PERIOD / HWTC_DIVISOR); /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / HWTC_DIVISOR. */ *pTimestamp += (hwtc_count + traceTickCount * (HWTC_PERIOD % HWTC_DIVISOR)) / HWTC_DIVISOR; } /* Store the previous values. */ last_traceTickCount = traceTickCount; last_hwtc_count = hwtc_count; } /******************************************************************************* * vTracePortEnd * * This function is called by the monitor when a recorder stop is detected. * This is used by the Win32 port to store the trace to a file. The file path is * set using vTracePortSetOutFile. ******************************************************************************/ void vTracePortEnd() { vTraceConsoleMessage("\n\r[FreeRTOS+Trace] Running vTracePortEnd.\n\r"); #if (WIN32_PORT_SAVE_WHEN_STOPPED == 1) vTracePortSave(); #endif #if (WIN32_PORT_EXIT_WHEN_STOPPED == 1) /* In the FreeRTOS/Win32 demo, this allows for killing the application when the recorder is stopped (e.g., when the buffer is full) */ system("pause"); exit(0); #endif } #if (INCLUDE_SAVE_TO_FILE == 1) /******************************************************************************* * vTracePortSetOutFile * * Sets the filename/path used in vTracePortSave. * This is set in a separate function, since the Win32 port calls vTracePortSave * in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set. ******************************************************************************/ void vTracePortSetOutFile(char* path) { prvFileName = path; } /******************************************************************************* * vTracePortSave * * Saves the trace to a file on a local file system. The path is set in a * separate function, vTracePortSetOutFile, since the Win32 port calls * vTracePortSave in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set. ******************************************************************************/ void vTracePortSave() { char buf[180]; FILE* f; if (prvFileName == NULL) { prvFileName = "FreeRTOSPlusTrace.dump"; sprintf(buf, "No filename specified, using default \"%s\".", prvFileName); vTraceConsoleMessage(buf); } fopen_s(&f, prvFileName, "wb"); if (f) { fwrite(RecorderDataPtr, sizeof(RecorderDataType), 1, f); fclose(f); sprintf(buf, "\n\r[FreeRTOS+Trace] Saved in: %s\n\r", prvFileName); vTraceConsoleMessage(buf); } else { sprintf(buf, "\n\r[FreeRTOS+Trace] Failed to write to output file!\n\r"); vTraceConsoleMessage(buf); } } #endif #endif