/******************************************************************************* | |
* 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 |