| /******************************************************************************* | |
| * Tracealyzer v2.6.0 Recorder Library | |
| * Percepio AB, www.percepio.com | |
| * | |
| * trcUser.h | |
| * The public API of the trace recorder library. | |
| * | |
| * 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 trcHardwarePort.c/.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. | |
| * | |
| * Copyright Percepio AB, 2013. | |
| * www.percepio.com | |
| ******************************************************************************/ | |
| #ifndef TRCUSER_H | |
| #define TRCUSER_H | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| #include "trcKernelPort.h" | |
| #if (USE_TRACEALYZER_RECORDER == 1) | |
| #ifndef USE_SEPARATE_USER_EVENT_BUFFER | |
| #define USE_SEPARATE_USER_EVENT_BUFFER 0 | |
| #endif | |
| /******************************************************************************* | |
| * TRACE_STOP_HOOK - Hook Pointer Data Type | |
| * | |
| * Declares a data type for a call back function that will be invoked whenever | |
| * the recorder is stopped. | |
| ******************************************************************************/ | |
| typedef void (*TRACE_STOP_HOOK)(void); | |
| /******************************************************************************* | |
| * vTraceStopHookPtr | |
| * | |
| * Points to a call back function that is called from vTraceStop(). | |
| ******************************************************************************/ | |
| extern TRACE_STOP_HOOK vTraceStopHookPtr; | |
| /******************************************************************************* | |
| * vTraceInitTraceData | |
| * | |
| * Allocates, if necessary, and initializes the recorder data structure, based | |
| * on the constants in trcConfig.h. | |
| ******************************************************************************/ | |
| void vTraceInitTraceData(void); | |
| /******************************************************************************* | |
| * vTraceSetRecorderData | |
| * | |
| * If custom allocation is used, this function must be called so the recorder | |
| * library knows where to save the trace data. | |
| ******************************************************************************/ | |
| #if (TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_CUSTOM) | |
| void vTraceSetRecorderData(void* pRecorderData); | |
| #endif | |
| /******************************************************************************* | |
| * uiTraceStart | |
| * | |
| * Starts the recorder. The recorder will not be started if an error has been | |
| * indicated using vTraceError, e.g. if any of the Nx constants in trcConfig.h | |
| * has a too small value (NTASK, NQUEUE, etc). | |
| * | |
| * Returns 1 if the recorder was started successfully. | |
| * Returns 0 if the recorder start was prevented due to a previous internal | |
| * error. In that case, check vTraceGetLastError to get the error message. | |
| * Any error message is also presented when opening a trace file. | |
| * | |
| ******************************************************************************/ | |
| uint32_t uiTraceStart(void); | |
| /******************************************************************************* | |
| * vTraceStart | |
| * | |
| * Starts the recorder. The recorder will not be started if an error has been | |
| * indicated using vTraceError, e.g. if any of the Nx constants in trcConfig.h | |
| * has a too small value (NTASK, NQUEUE, etc). | |
| * | |
| * This function is obsolete, but has been saved for backwards compatibility. | |
| * We recommend using uiTraceStart instead. | |
| ******************************************************************************/ | |
| void vTraceStart(void); | |
| /******************************************************************************* | |
| * vTraceStop | |
| * | |
| * Stops the recorder. The recording can be resumed by calling vTraceStart. | |
| * This does not reset the recorder. Use vTraceClear is that is desired. | |
| ******************************************************************************/ | |
| void vTraceStop(void); | |
| /******************************************************************************* | |
| * xTraceGetLastError | |
| * | |
| * Gives the last error message, if any. NULL if no error message is stored. | |
| * Any error message is also presented when opening a trace file. | |
| ******************************************************************************/ | |
| char* xTraceGetLastError(void); | |
| /******************************************************************************* | |
| * vTraceClear | |
| * | |
| * Resets the recorder. Only necessary if a restart is desired - this is not | |
| * needed in the startup initialization. | |
| ******************************************************************************/ | |
| void vTraceClear(void); | |
| /******************************************************************************* | |
| * vTraceClearError | |
| * | |
| * Removes any previous error message generated by recorder calling vTraceError. | |
| * By calling this function, it may be possible to start/restart the trace | |
| * despite errors in the recorder, but there is no guarantee that the trace | |
| * recorder will work correctly in that case, depending on the type of error. | |
| ******************************************************************************/ | |
| void vTraceClearError(int resetErrorMessage); | |
| #if (INCLUDE_ISR_TRACING == 1) | |
| /******************************************************************************* | |
| * vTraceSetISRProperties | |
| * | |
| * Registers an Interrupt Service Routine in the recorder library, This must be | |
| * called before using vTraceStoreISRBegin to store ISR events. This is | |
| * typically called in the startup of the system, before the scheduler is | |
| * started. | |
| * | |
| * Example: | |
| * #define ID_ISR_TIMER1 1 // lowest valid ID is 1 | |
| * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt | |
| * ... | |
| * vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1); | |
| * ... | |
| * void ISR_handler() | |
| * { | |
| * portENTER_CRITICAL(); // Required if nested ISRs are allowed | |
| * vTraceStoreISRBegin(ID_OF_ISR_TIMER1); | |
| * portEXIT_CRITICAL(); | |
| * ... | |
| * portENTER_CRITICAL(); // Required if nested ISRs are allowed | |
| * vTraceStoreISREnd(); | |
| * portEXIT_CRITICAL(); | |
| * } | |
| ******************************************************************************/ | |
| void vTraceSetISRProperties(objectHandleType handle, const char* name, char priority); | |
| /******************************************************************************* | |
| * vTraceStoreISRBegin | |
| * | |
| * Registers the beginning of an Interrupt Service Routine. | |
| * If allowing nested ISRs, this must be called with interrupts disabled. | |
| * | |
| * Example: | |
| * #define ID_ISR_TIMER1 1 // lowest valid ID is 1 | |
| * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt | |
| * ... | |
| * vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1); | |
| * ... | |
| * void ISR_handler() | |
| * { | |
| * portENTER_CRITICAL(); // Required if nested ISRs are allowed | |
| * vTraceStoreISRBegin(ID_OF_ISR_TIMER1); | |
| * portEXIT_CRITICAL(); | |
| * ... | |
| * portENTER_CRITICAL(); // Required if nested ISRs are allowed | |
| * vTraceStoreISREnd(); | |
| * portEXIT_CRITICAL(); | |
| * } | |
| * | |
| ******************************************************************************/ | |
| void vTraceStoreISRBegin(objectHandleType id); | |
| /******************************************************************************* | |
| * vTraceStoreISREnd | |
| * | |
| * Registers the end of an Interrupt Service Routine. | |
| * | |
| * If allowing nested ISRs, this must be called with interrupts disabled. | |
| * | |
| * Example: | |
| * #define ID_ISR_TIMER1 1 // lowest valid ID is 1 | |
| * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt | |
| * ... | |
| * vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1); | |
| * ... | |
| * void ISR_handler() | |
| * { | |
| * portENTER_CRITICAL(); // Required if nested ISRs are allowed | |
| * vTraceStoreISRBegin(ID_OF_ISR_TIMER1); | |
| * portEXIT_CRITICAL(); | |
| * ... | |
| * portENTER_CRITICAL(); // Required if nested ISRs are allowed | |
| * vTraceStoreISREnd(); | |
| * portEXIT_CRITICAL(); | |
| * } | |
| * | |
| ******************************************************************************/ | |
| void vTraceStoreISREnd(void); | |
| #else | |
| /* If not including the ISR recording */ | |
| void vTraceIncreaseISRActive(void); | |
| void vTraceDecreaseISRActive(void); | |
| #define vTraceSetISRProperties(handle, name, priority) | |
| #define vTraceStoreISRBegin(id) vTraceIncreaseISRActive() | |
| #define vTraceStoreISREnd() vTraceDecreaseISRActive() | |
| #endif | |
| /******************************************************************************* | |
| * vvTraceTaskSkipDefaultInstanceFinishedEvents | |
| * | |
| * This is useful if there are implicit Instance Finish Events, such as | |
| * vTaskDelayUntil or xQueueReceive, in a task where an explicit Instance Finish | |
| * Event has been defined. This function tells the recorder that only the | |
| * explicitly defined functions (using vTraceTaskInstanceIsFinished) should be | |
| * treated as Instance Finish Events for this task. The implicit Instance Finish | |
| * Events are thus disregarded for this task. | |
| ******************************************************************************/ | |
| void vTraceTaskSkipDefaultInstanceFinishedEvents(void); | |
| /******************************************************************************* | |
| * vTraceTaskInstanceIsFinished | |
| * | |
| * This defines an explicit Instance Finish Event for the current task. It tells | |
| * the recorder that the current instance of this task is finished at the next | |
| * kernel call of the task, e.g., a taskDelay or a queue receive. This function | |
| * should be called right before the api function call considered to be the end | |
| * of the task instamce, i.e., the Instance Finish Event. | |
| ******************************************************************************/ | |
| void vTraceTaskInstanceIsFinished(void); | |
| /******************************************************************************* | |
| * vTraceGetTraceBuffer | |
| * | |
| * Returns a pointer to the recorder data structure. Use this together with | |
| * uiTraceGetTraceBufferSize if you wish to implement an own store/upload | |
| * solution, e.g., in case a debugger connection is not available for uploading | |
| * the data. | |
| ******************************************************************************/ | |
| void* vTraceGetTraceBuffer(void); | |
| /******************************************************************************* | |
| * uiTraceGetTraceBufferSize | |
| * | |
| * Gets the size of the recorder data structure. For use together with | |
| * vTraceGetTraceBuffer if you wish to implement an own store/upload solution, | |
| * e.g., in case a debugger connection is not available for uploading the data. | |
| ******************************************************************************/ | |
| uint32_t uiTraceGetTraceBufferSize(void); | |
| #if (INCLUDE_USER_EVENTS == 1) | |
| /******************************************************************************* | |
| * xTraceOpenLabel | |
| * | |
| * Creates user event labels for user event channels or for individual events. | |
| * User events can be used to log application events and data for display in | |
| * the visualization tool. A user event is identified by a label, i.e., a string, | |
| * which is stored in the recorder's symbol table. | |
| * When logging a user event, a numeric handle (reference) to this string is | |
| * used to identify the event. This is obtained by calling | |
| * | |
| * xTraceOpenLabel() | |
| * | |
| * whihc adds the string to the symbol table (if not already present) | |
| * and returns the corresponding handle. | |
| * | |
| * This can be used in two ways: | |
| * | |
| * 1. The handle is looked up every time, when storing the user event. | |
| * | |
| * Example: | |
| * vTraceUserEvent(xTraceOpenLabel("MyUserEvent")); | |
| * | |
| * 2. The label is registered just once, with the handle stored in an | |
| * application variable - much like using a file handle. | |
| * | |
| * Example: | |
| * myEventHandle = xTraceOpenLabel("MyUserEvent"); | |
| * ... | |
| * vTraceUserEvent(myEventHandle); | |
| * | |
| * The second option is faster since no lookup is required on each event, and | |
| * therefore recommended for user events that are frequently | |
| * executed and/or located in time-critical code. The lookup operation is | |
| * however fairly fast due to the design of the symbol table. | |
| ******************************************************************************/ | |
| traceLabel xTraceOpenLabel(const char* label); | |
| /****************************************************************************** | |
| * vTraceUserEvent | |
| * | |
| * Basic user event (Standard and Professional Edition only) | |
| * | |
| * Generates a User Event with a text label. The label is created/looked up | |
| * in the symbol table using xTraceOpenLabel. | |
| ******************************************************************************/ | |
| void vTraceUserEvent(traceLabel eventLabel); | |
| /****************************************************************************** | |
| * vTracePrintF | |
| * | |
| * Advanced user events (Professional Edition only) | |
| * | |
| * Generates User Event with formatted text and data, similar to a "printf". | |
| * It is very fast compared to a normal "printf" since this function only | |
| * stores the arguments. The actual formatting is done | |
| * on the host PC when the trace is displayed in the viewer tool. | |
| * | |
| * User Event labels are created using xTraceOpenLabel. | |
| * Example: | |
| * | |
| * traceLabel adc_uechannel = xTraceOpenLabel("ADC User Events"); | |
| * ... | |
| * vTracePrint(adc_uechannel, | |
| * "ADC channel %d: %lf volts", | |
| * ch, (double)adc_reading/(double)scale); | |
| * | |
| * This can be combined into one line, if desired, but this is slower: | |
| * | |
| * vTracePrint(xTraceOpenLabel("ADC User Events"), | |
| * "ADC channel %d: %lf volts", | |
| * ch, (double)adc_reading/(double)scale); | |
| * | |
| * Calling xTraceOpenLabel multiple times will not create duplicate entries, but | |
| * it is of course faster to just do it once, and then keep the handle for later | |
| * use. If you don“t have any data arguments, only a text label/string, it is | |
| * better to use vTraceUserEvent - it is faster. | |
| * | |
| * Format specifiers supported: | |
| * %d - 32 bit signed integer | |
| * %u - 32 bit unsigned integer | |
| * %f - 32 bit float | |
| * %s - string (is copied to the recorder symbol table) | |
| * %hd - 16 bit signed integer | |
| * %hu - 16 bit unsigned integer | |
| * %bd - 8 bit signed integer | |
| * %bu - 8 bit unsigned integer | |
| * %lf - double-precision float (Note! See below...) | |
| * | |
| * Up to 15 data arguments are allowed, with a total size of maximum 32 byte. | |
| * In case this is exceeded, the user event is changed into an error message. | |
| * | |
| * The data is stored in trace buffer, and is packed to allow storing multiple | |
| * smaller data entries in the same 4-byte record, e.g., four 8-bit values. | |
| * A string requires two bytes, as the symbol table is limited to 64K. Storing | |
| * a double (%lf) uses two records, so this is quite costly. Use float (%f) | |
| * unless the higher precision is really necessary. | |
| * | |
| * Note that the double-precision float (%lf) assumes a 64 bit double | |
| * representation. This does not seem to be the case on e.g. PIC24F. | |
| * Before using a %lf argument on a 16-bit MCU, please verify that | |
| * "sizeof(double)" actually gives 8 as expected. If not, use %f instead. | |
| ******************************************************************************/ | |
| void vTracePrintF(traceLabel eventLabel, const char* formatStr, ...); | |
| #if (USE_SEPARATE_USER_EVENT_BUFFER == 1) | |
| UserEventChannel xTraceRegisterChannelFormat(traceLabel channel, traceLabel formatStr); | |
| void vTraceChannelPrintF(UserEventChannel channel, ...); | |
| void vTraceChannelUserEvent(UserEventChannel channel); | |
| #endif | |
| #else | |
| #define vTracePrintF(eventLabel, formatStr, ...); | |
| #define xTraceOpenLabel(label) 0 | |
| #define vTraceUserEvent(eventLabel) | |
| #endif | |
| #else | |
| /* Empty defines for user functions to avoid compiler errors if trace is not to be used */ | |
| #define vTraceInitTraceData() | |
| #define uiTraceStart() (1) // Fake "success", if used when recorder is excluded from build | |
| #define vTraceStart() | |
| #define vTraceStop() | |
| #define vTraceClear() | |
| #define vTraceStartStatusMonitor() | |
| #define vTraceGetTraceBuffer() ((void*)0) | |
| #define uiTraceGetTraceBufferSize() 0 | |
| #define xTraceOpenLabel(label) 0 | |
| #define vTraceUserEvent(eventLabel) | |
| #define vTracePrintF(eventLabel,formatStr,...) | |
| #define vTraceExcludeTaskFromSchedulingTrace(name) | |
| #define vTraceTaskSkipDefaultInstanceFinishedEvents() | |
| #define vTraceSetISRProperties(handle, name, priority) | |
| #define vTraceStoreISRBegin(id) | |
| #define vTraceStoreISREnd() | |
| #define vTraceExcludeTaskFromTrace(handle) | |
| #define vTraceSetQueueName(a, b) | |
| #define vTraceSetMutexName(a, b) | |
| #define vTraceSetSemaphoreName(a, b) | |
| #define vTraceSetEventGroupName(a, b) | |
| #endif | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| #endif |