1 /*******************************************************************************
\r
2 * FreeRTOS+Trace v2.2.3 Recorder Library
\r
3 * Percepio AB, www.percepio.se
\r
6 * The public API of the trace recorder library.
\r
9 * This software is copyright Percepio AB. The recorder library is free for
\r
10 * use together with Percepio products. You may distribute the recorder library
\r
11 * in its original form, including modifications in trcPort.c and trcPort.h
\r
12 * given that these modification are clearly marked as your own modifications
\r
13 * and documented in the initial comment section of these source files.
\r
14 * This software is the intellectual property of Percepio AB and may not be
\r
15 * sold or in other ways commercially redistributed without explicit written
\r
16 * permission by Percepio AB.
\r
19 * The trace tool and recorder library is being delivered to you AS IS and
\r
20 * Percepio AB makes no warranty as to its use or performance. Percepio AB does
\r
21 * not and cannot warrant the performance or results you may obtain by using the
\r
22 * software or documentation. Percepio AB make no warranties, express or
\r
23 * implied, as to noninfringement of third party rights, merchantability, or
\r
24 * fitness for any particular purpose. In no event will Percepio AB, its
\r
25 * technology partners, or distributors be liable to you for any consequential,
\r
26 * incidental or special damages, including any lost profits or lost savings,
\r
27 * even if a representative of Percepio AB has been advised of the possibility
\r
28 * of such damages, or for any claim by any third party. Some jurisdictions do
\r
29 * not allow the exclusion or limitation of incidental, consequential or special
\r
30 * damages, or the exclusion of implied warranties or limitations on how long an
\r
31 * implied warranty may last, so the above limitations may not apply to you.
\r
33 * FreeRTOS+Trace is available as Free Edition and in two premium editions.
\r
34 * You may use the premium features during 30 days for evaluation.
\r
35 * Download FreeRTOS+Trace at http://www.percepio.se/index.php?page=downloads
\r
37 * Copyright Percepio AB, 2012.
\r
39 ******************************************************************************/
\r
44 #include "FreeRTOS.h"
\r
46 #if (configUSE_TRACE_FACILITY == 1)
\r
48 #include "trcBase.h"
\r
54 /*******************************************************************************
\r
57 * Starts the recorder. The recorder will not be started if an error has been
\r
58 * indicated using vTraceError, e.g. if any of the Nx constants in trcConfig.h
\r
59 * has a too small value (NTASK, NQUEUE, etc).
\r
61 * Returns 1 if the recorder was started successfully.
\r
62 * Returns 0 if the recorder start was prevented due to a previous internal
\r
63 * error. In that case, check vTraceGetLastError to get the error message.
\r
64 * Any error message is also presented when opening a trace file in
\r
65 * FreeRTOS+Trace v2.2.2 or later.
\r
66 ******************************************************************************/
\r
67 uint32_t uiTraceStart(void);
\r
69 /*******************************************************************************
\r
72 * Starts the recorder. The recorder will not be started if an error has been
\r
73 * indicated using vTraceError, e.g. if any of the Nx constants in trcConfig.h
\r
74 * has a too small value (NTASK, NQUEUE, etc).
\r
76 * This function is obsolete, but has been saved for backwards compatibility.
\r
77 * We recommend using uiTraceStart instead.
\r
78 ******************************************************************************/
\r
79 void vTraceStart(void);
\r
81 /*******************************************************************************
\r
82 * vTraceStartStatusMonitor
\r
84 * This starts a task to monitor the status of the recorder module.
\r
85 * This task periodically prints a line to the console window, which shows the
\r
86 * recorder status, the number of events recorded and the latest timestamp.
\r
87 * This task calls vTracePortEnd (trcPort.c) when it detects that the recorder
\r
88 * has been stopped. This allows for adding custom actions, e.g., to store the
\r
89 * trace to a file in case a file system is available on the device.
\r
90 ******************************************************************************/
\r
91 void vTraceStartStatusMonitor(void);
\r
93 /*******************************************************************************
\r
96 * Stops the recorder. The recording can be resumed by calling vTraceStart.
\r
97 * This does not reset the recorder. Use vTraceClear is that is desired.
\r
98 ******************************************************************************/
\r
99 void vTraceStop(void);
\r
101 /*******************************************************************************
\r
104 * Resets the recorder. Only necessary if a restart is desired - this is not
\r
105 * needed in the startup initialization.
\r
106 ******************************************************************************/
\r
107 void vTraceClear(void);
\r
109 /*******************************************************************************
\r
110 * vTraceSetQueueName
\r
112 * Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This function should
\r
113 * be called right after creation of the queue/mutex/semaphore. If not using
\r
114 * this function, the queues/mutexes/semaphores will be presented by their
\r
115 * numeric handle only.
\r
118 * actuatorQ = xQueueCreate(3, sizeof(QueueMessage));
\r
119 * vTraceSetQueueName(actuatorQ, "ActuatorQueue");
\r
120 ******************************************************************************/
\r
121 void vTraceSetQueueName(void* queue, const char* name);
\r
123 #if (INCLUDE_ISR_TRACING == 1)
\r
125 /*******************************************************************************
\r
126 * vTraceSetISRProperties
\r
128 * Registers an Interrupt Service Routine in the recorder library, This must be
\r
129 * called before using vTraceStoreISRBegin to store ISR events. This is
\r
130 * typically called in the startup of the system, before the scheduler is
\r
134 * #define ID_ISR_TIMER1 1 // lowest valid ID is 1
\r
135 * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
\r
137 * vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1);
\r
139 * void ISR_handler()
\r
141 * portENTER_CRITICAL(); // Required if nested ISRs are allowed
\r
142 * vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
\r
143 * portEXIT_CRITICAL();
\r
145 * portENTER_CRITICAL(); // Required if nested ISRs are allowed
\r
146 * vTraceStoreISREnd();
\r
147 * portEXIT_CRITICAL();
\r
149 ******************************************************************************/
\r
150 void vTraceSetISRProperties(objectHandleType handle, char* name, char priority);
\r
152 /*******************************************************************************
\r
153 * vTraceStoreISRBegin
\r
155 * Registers the beginning of an Interrupt Service Routine. This must not be
\r
156 * interrupted by another ISR containing recorder library calls, so if allowing
\r
157 * nested ISRs this must be called with interrupts disabled.
\r
160 * #define ID_ISR_TIMER1 1 // lowest valid ID is 1
\r
161 * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
\r
163 * vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1);
\r
165 * void ISR_handler()
\r
167 * portENTER_CRITICAL(); // Required if nested ISRs are allowed
\r
168 * vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
\r
169 * portEXIT_CRITICAL();
\r
171 * portENTER_CRITICAL(); // Required if nested ISRs are allowed
\r
172 * vTraceStoreISREnd();
\r
173 * portEXIT_CRITICAL();
\r
175 ******************************************************************************/
\r
176 void vTraceStoreISRBegin(objectHandleType id);
\r
178 /*******************************************************************************
\r
179 * vTraceStoreISREnd
\r
181 * Registers the end of an Interrupt Service Routine. This must not be
\r
182 * interrupted by another ISR containing recorder library calls, so if allowing
\r
183 * nested ISRs this must be called with interrupts disabled.
\r
186 * #define ID_ISR_TIMER1 1 // lowest valid ID is 1
\r
187 * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
\r
189 * vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1);
\r
191 * void ISR_handler()
\r
193 * portENTER_CRITICAL(); // Required if nested ISRs are allowed
\r
194 * vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
\r
195 * portEXIT_CRITICAL();
\r
197 * portENTER_CRITICAL(); // Required if nested ISRs are allowed
\r
198 * vTraceStoreISREnd();
\r
199 * portEXIT_CRITICAL();
\r
201 ******************************************************************************/
\r
202 void vTraceStoreISREnd(void);
\r
206 /* If not including the ISR recording */
\r
208 #define vTraceSetISRProperties(handle, name, priority)
\r
209 #define vTraceStoreISRBegin(id)
\r
210 #define vTraceStoreISREnd()
\r
214 /*******************************************************************************
\r
215 * vvTraceTaskSkipDefaultInstanceFinishedEvents
\r
217 * This is useful if there are implicit Instance Finish Events, such as
\r
218 * vTaskDelayUntil or xQueueReceive, in a task where an explicit Instance Finish
\r
219 * Event has been defined. This function tells the recorder that only the
\r
220 * explicitly defined functions (using vTraceTaskInstanceIsFinished) should be
\r
221 * treated as Instance Finish Events for this task. The implicit Instance Finish
\r
222 * Events are thus disregarded for this task.
\r
223 ******************************************************************************/
\r
224 void vTraceTaskSkipDefaultInstanceFinishedEvents(void);
\r
226 /*******************************************************************************
\r
227 * vTraceTaskInstanceIsFinished
\r
229 * This defines an explicit Instance Finish Event for the current task. It tells
\r
230 * the recorder that the current instance of this task is finished at the next
\r
231 * kernel call of the task, e.g., a taskDelay or a queue receive. This function
\r
232 * should be called right before the api function call considered to be the end
\r
233 * of the task instamce, i.e., the Instance Finish Event.
\r
234 ******************************************************************************/
\r
235 void vTraceTaskInstanceIsFinished(void);
\r
237 /*******************************************************************************
\r
238 * vTraceGetTraceBuffer
\r
240 * Returns a pointer to the recorder data structure. Use this together with
\r
241 * uiTraceGetTraceBufferSize if you wish to implement an own store/upload
\r
242 * solution, e.g., in case a debugger connection is not available for uploading
\r
244 ******************************************************************************/
\r
245 void* vTraceGetTraceBuffer(void);
\r
247 /*******************************************************************************
\r
248 * uiTraceGetTraceBufferSize
\r
250 * Gets the size of the recorder data structure. For use together with
\r
251 * vTraceGetTraceBuffer if you wish to implement an own store/upload solution,
\r
252 * e.g., in case a debugger connection is not available for uploading the data.
\r
253 ******************************************************************************/
\r
254 uint32_t uiTraceGetTraceBufferSize(void);
\r
256 #if (INCLUDE_USER_EVENTS == 1)
\r
258 /*******************************************************************************
\r
261 * Creates user event labels for user event channels or for individual events.
\r
262 * User events can be used to log application events and data for display in
\r
263 * the visualization tool. A user event is identified by a label, i.e., a string,
\r
264 * which is stored in the recorder's symbol table.
\r
265 * When logging a user event, a numeric handle (reference) to this string is
\r
266 * used to identify the event. This is obtained by calling
\r
268 * xTraceOpenLabel()
\r
270 * whihc adds the string to the symbol table (if not already present)
\r
271 * and returns the corresponding handle.
\r
273 * This can be used in two ways:
\r
275 * 1. The handle is looked up every time, when storing the user event.
\r
278 * vTraceUserEvent(xTraceOpenLabel("MyUserEvent"));
\r
280 * 2. The label is registered just once, with the handle stored in an
\r
281 * application variable - much like using a file handle.
\r
284 * myEventHandle = xTraceOpenLabel("MyUserEvent");
\r
286 * vTraceUserEvent(myEventHandle);
\r
288 * The second option is faster since no lookup is required on each event, and
\r
289 * therefore recommended for user events that are frequently
\r
290 * executed and/or located in time-critical code. The lookup operation is
\r
291 * however fairly fast due to the design of the symbol table.
\r
292 ******************************************************************************/
\r
293 traceLabel xTraceOpenLabel(char* label);
\r
295 /******************************************************************************
\r
298 * Basic user event (Standard and Professional Edition only)
\r
300 * Generates a User Event with a text label. The label is created/looked up
\r
301 * in the symbol table using xTraceOpenLabel.
\r
302 ******************************************************************************/
\r
303 void vTraceUserEvent(traceLabel eventLabel);
\r
305 /******************************************************************************
\r
308 * Advanced user events (Professional Edition only)
\r
310 * Generates User Event with formatted text and data, similar to a "printf".
\r
311 * It is very fast compared to a normal "printf" since this function only
\r
312 * stores the arguments. The actual formatting is done
\r
313 * on the host PC when the trace is displayed in the viewer tool.
\r
315 * User Event labels are created using xTraceOpenLabel.
\r
318 * traceLabel adc_uechannel = xTraceOpenLabel("ADC User Events");
\r
320 * vTracePrint(adc_uechannel,
\r
321 * "ADC channel %d: %lf volts",
\r
322 * ch, (double)adc_reading/(double)scale);
\r
324 * This can be combined into one line, if desired, but this is slower:
\r
326 * vTracePrint(xTraceOpenLabel("ADC User Events"),
\r
327 * "ADC channel %d: %lf volts",
\r
328 * ch, (double)adc_reading/(double)scale);
\r
330 * Calling xTraceOpenLabel multiple times will not create duplicate entries, but
\r
331 * it is of course faster to just do it once, and then keep the handle for later
\r
332 * use. If you donĀ“t have any data arguments, only a text label/string, it is
\r
333 * better to use vTraceUserEvent - it is faster.
\r
335 * Format specifiers supported:
\r
336 * %d - 32 bit signed integer
\r
337 * %u - 32 bit unsigned integer
\r
338 * %f - 32 bit float
\r
339 * %s - string (is copied to the recorder symbol table)
\r
340 * %hd - 16 bit signed integer
\r
341 * %hu - 16 bit unsigned integer
\r
342 * %bd - 8 bit signed integer
\r
343 * %bu - 8 bit unsigned integer
\r
344 * %lf - double-precision float
\r
346 * Up to 15 data arguments are allowed, with a total size of maximum 32 byte.
\r
347 * In case this is exceeded, the user event is changed into an error message.
\r
349 * The data is stored in trace buffer, and is packed to allow storing multiple
\r
350 * smaller data entries in the same 4-byte record, e.g., four 8-bit values.
\r
351 * A string requires two bytes, as the symbol table is limited to 64K. Storing a
\r
352 * double (%lf) uses two records, so this is quite costly. Use float (%f) unless
\r
353 * the higher precision is really necessary.
\r
354 ******************************************************************************/
\r
355 void vTracePrintF(traceLabel eventLabel, const char* formatStr, ...);
\r
359 #define vTracePrintF(eventLabel, formatStr, ...);
\r
360 #define xTraceOpenLabel(label) 0
\r
361 #define vTraceUserEvent(eventLabel)
\r
365 /******************************************************************************
\r
366 * vTraceExcludeTask
\r
368 * Excludes a task from the recording using a flag in the Object Property Table.
\r
369 * This can be useful if some irrelevant task is very frequent and is "eating
\r
370 * up the buffer". This should be called the task has been created, but
\r
371 * before starting the FreeRTOS scheduler.
\r
372 *****************************************************************************/
\r
373 void vTraceExcludeTaskFromSchedulingTrace(const char* name);
\r
381 #include "trcPort.h"
\r
383 #define vTraceInit()
\r
384 #define vTraceStart()
\r
385 #define vTraceStop()
\r
386 #define vTraceClear()
\r
387 #define vTraceGetTraceBuffer() ((void*)0)
\r
388 #define uiTraceGetTraceBufferSize() 0
\r
389 #define xTraceOpenLabel(label) 0
\r
390 #define vTraceUserEvent(eventLabel)
\r
391 #define vTracePrintF(eventLabel,formatStr,...)
\r
392 #define vTraceExcludeTaskFromSchedulingTrace(name)
\r
393 #define vTraceSetQueueName(queue, name)
\r
394 #define vTraceTaskSkipDefaultInstanceFinishedEvents()
\r
395 #define vTraceSetISRProperties(handle, name, priority)
\r
396 #define vTraceStoreISRBegin(id)
\r
397 #define vTraceStoreISREnd()
\r