1 /*
2  * Trace Recorder for Tracealyzer v4.10.3
3  * Copyright 2023 Percepio AB
4  * www.percepio.com
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #ifndef TRC_RECORDER_H
10 #define TRC_RECORDER_H
11 
12 /**
13  * @file
14  *
15  * @brief The public API of the Percepio trace recorder.
16  */
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /**
23  * @brief Trace Recorder APIs
24  * @defgroup trace_recorder_apis Trace Recorder APIs
25  * @{
26  * @}
27  */
28 
29 #define TRC_ACKNOWLEDGED (0xABC99123)
30 
31 #include <trcDefines.h>
32 #include <trcConfig.h>
33 #include <trcKernelPortConfig.h>
34 
35 /* If TRC_CFG_RECORDER_MODE is not defined we assume there is no support
36  * for the classic snapshot mode and default to streaming mode where
37  * the new RingBuffer snapshot mode provides snapshot functionality.
38  */
39 #ifndef TRC_CFG_RECORDER_MODE
40 #define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING
41 #endif
42 
43 /* Some types may be defined differently based on TRC_CFG_RECORDER_MODE */
44 #include <trcTypes.h>
45 
46 #ifndef TRC_CFG_TEST_MODE
47 #define TRC_CFG_TEST_MODE 0
48 #endif
49 
50 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
51 #include <trcSnapshotConfig.h>
52 #include <trcKernelPortSnapshotConfig.h>
53 
54 /* Calls xTraceError if the _assert condition is false. For void functions,
55 where no return value is to be provided. */
56 #define TRC_ASSERT_VOID(_assert, _err) if (! (_assert)){ prvTraceError(_err); return; }
57 
58 /* Calls xTraceError if the _assert condition is false. For non-void functions,
59 where a return value is to be provided. */
60 #define TRC_ASSERT_RET(_assert, _err, _return) if (! (_assert)){ prvTraceError(_err); return _return; }
61 
62 typedef uint8_t traceUBChannel;
63 typedef uint8_t traceObjectClass;
64 
65 #undef traceHandle
66 #if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
67 typedef uint16_t traceHandle;
68 #else /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
69 typedef uint8_t traceHandle;
70 #endif /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
71 
72 #undef TraceISRHandle_t
73 #define TraceISRHandle_t traceHandle
74 
75 #include <trcHardwarePort.h>
76 #include <trcKernelPort.h>
77 
78 /* Not yet available in snapshot mode */
79 #define xTracePrintFormat0(_c, _f)
80 #define xTracePrintFormat1(_c, _f, _p1)
81 #define xTracePrintFormat2(_c, _f, _p1, _p2)
82 #define xTracePrintFormat3(_c, _f, _p1, _p2, _p3)
83 #define xTracePrintFormat4(_c, _f, _p1, _p2, _p3, _p4)
84 #define vTraceConsoleChannelPrintF(fmt, ...) (void)
85 #define xTraceConsoleChannelPrintF(fmt, ...) (void)
86 #define prvTraceStoreEvent_None(...)
87 #define prvTraceStoreEvent_Handle(...)
88 #define prvTraceStoreEvent_Param(...)
89 #define prvTraceStoreEvent_HandleParam(...)
90 #define prvTraceStoreEvent_ParamParam(...)
91 #define prvTraceStoreEvent_HandleParamParam(...)
92 #define prvTraceStoreEvent_ParamParamParam(...)
93 
94 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) */
95 
96 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
97 #include <trcStreamingConfig.h>
98 #include <trcKernelPortStreamingConfig.h>
99 
100 /* Unless specified in trcConfig.h we assume this is a single core target */
101 #ifndef TRC_CFG_CORE_COUNT
102 #define TRC_CFG_CORE_COUNT 1
103 #endif
104 
105 /* Unless specified in trcConfig.h we assume this is a single core target */
106 #ifndef TRC_CFG_GET_CURRENT_CORE
107 #define TRC_CFG_GET_CURRENT_CORE() 0
108 #endif
109 
110 /* Unless specified in trcConfig.h or trcKernelPortConfig.h we assume
111  * GCC statement expressions aren't supported. */
112 #ifndef TRC_CFG_USE_GCC_STATEMENT_EXPR
113 #define TRC_CFG_USE_GCC_STATEMENT_EXPR 0
114 #endif
115 
116 /* Backwards compatibility */
117 #undef traceHandle
118 #define traceHandle TraceISRHandle_t
119 
120 /* Maximum event size */
121 #define TRC_MAX_BLOB_SIZE (16UL * sizeof(TraceUnsignedBaseType_t))
122 
123 /* Platform name length */
124 #define TRC_PLATFORM_CFG_LENGTH 8UL
125 
126 /* Header size */
127 #define TRC_HEADER_BUFFER_SIZE (sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint8_t) + (sizeof(char) * (TRC_PLATFORM_CFG_LENGTH)))
128 
129 typedef struct TraceHeaderBuffer	/* Aligned */
130 {
131 	uint8_t buffer[TRC_HEADER_BUFFER_SIZE];
132 } TraceHeaderBuffer_t;
133 
134 #include <trcHardwarePort.h>
135 #include <trcKernelPort.h>
136 #include <trcString.h>
137 #include <trcStaticBuffer.h>
138 #include <trcError.h>
139 #include <trcEvent.h>
140 #include <trcEventBuffer.h>
141 #include <trcMultiCoreEventBuffer.h>
142 #include <trcTimestamp.h>
143 #include <trcEntryTable.h>
144 #include <trcStreamPort.h>
145 #include <trcISR.h>
146 #include <trcTask.h>
147 #include <trcObject.h>
148 #include <trcPrint.h>
149 #include <trcHeap.h>
150 #include <trcExtension.h>
151 #include <trcUtility.h>
152 #include <trcStackMonitor.h>
153 #include <trcInternalEventBuffer.h>
154 #include <trcDiagnostics.h>
155 #include <trcAssert.h>
156 #include <trcRunnable.h>
157 #include <trcDependency.h>
158 #include <trcProcess.h>
159 #include <trcThread.h>
160 
161 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
162 
163 /* These includes offer functionality for Streaming mode only, but they are included here in order to avoid compilation errors */
164 #include <trcInterval.h>
165 #include <trcStateMachine.h>
166 #include <trcCounter.h>
167 
168 #if (TRC_USE_TRACEALYZER_RECORDER == 1)
169 
170 /******************************************************************************/
171 /*** Common API - both Snapshot and Streaming mode ****************************/
172 /******************************************************************************/
173 
174 /**
175  * @brief
176  *
177  * Initializes the recorder data.
178  * xTraceInitialize() or xTraceEnable(...) must be called before any attempts
179  * at adding trace data/information. xTraceInitialize() can be called before
180  * timestamp source is initialized since timestamps aren't used until
181  * xTraceEnable(...) is called.
182  *
183  * See xTraceEnable(...) for more information.
184  *
185  * @retval TRC_FAIL Failure
186  * @retval TRC_SUCCESS Success
187  */
188 traceResult xTraceInitialize(void);
189 
190 /**
191  * @brief
192  *
193  * This function enables tracing.
194  * To use the trace recorder, the startup must call xTraceInitialize() or
195  * xTraceEnable(...) before any RTOS calls are made (including "create" calls).
196  * This function should only be called after the timestamp source is properly
197  * initialized. If kernel services that generate trace data are called before that,
198  * an earlier call to xTraceInitialize() is necessary. Then call xTraceEnable(...)
199  * once the timestamp source is initialized.
200  *
201  * Three start options are provided:
202  *
203  * 	TRC_START: Starts the tracing directly. In snapshot mode this allows for
204  * 	starting the trace at any point in your code, assuming xTraceInitialize()
205  * 	has been called in the startup. Can also be used for streaming without
206  * 	Tracealyzer control, e.g. to a local flash file system (assuming such a
207  * 	"stream port", see trcStreamPort.h).
208  *
209  * 	TRC_START_AWAIT_HOST: For streaming mode only. Initializes the trace recorder
210  * 	if necessary and waits for a Start command from Tracealyzer ("Start Recording"
211  * 	button). This call is intentionally blocking! By calling xTraceEnable with
212  * 	this option from the startup code, you start tracing at this point and capture
213  * 	the early events.
214  *
215  * 	TRC_START_FROM_HOST: For streaming mode only. Initializes the trace recorder
216  * 	if necessary and creates a task that waits for a Start command from
217  * 	Tracealyzer ("Start Recording" button). This call is not blocking.
218  *
219  * @example Usage examples
220  *
221  * 	Snapshot trace, from startup:
222  * 		<board init>
223  * 		xTraceEnable(TRC_START); // Will call xTraceInitialize()
224  * 		<RTOS init>
225  *
226  * 	Snapshot trace, from a later point:
227  * 		<board init>
228  * 		xTraceInitialize();
229  * 		<RTOS init>
230  * 		...
231  * 		xTraceEnable(TRC_START); // e.g., in task context, at some relevant event
232  *
233  * 	Streaming trace, from startup (can only be used with certain stream ports):
234  *		<board startup>
235  *		xTraceInitialize();
236  *		<RTOS startup>
237  * 		xTraceEnable(TRC_START);
238  *
239  * 	Streaming trace, from startup:
240  *		<board init>
241  *		xTraceEnable(TRC_START_AWAIT_HOST); // Blocks!
242  *		<RTOS init>
243  *
244  * 	Streaming trace, from a later point:
245  *		<board startup>
246  *		xTraceInitialize();
247  *		<RTOS startup>
248  * 		xTraceEnable(TRC_START);
249  *
250  * 	Streaming trace, system executes normally until host starts tracing:
251  *		<board startup>
252  *		xTraceInitialize();
253  *		<RTOS startup>
254  *		xTraceEnable(TRC_START_FROM_HOST)
255  *
256  * @param[in] uiStartOption Start option.
257  *
258  * @retval TRC_FAIL Failure
259  * @retval TRC_SUCCESS Success
260  */
261 traceResult	xTraceEnable(uint32_t uiStartOption);
262 
263 /**
264  * @brief Disables tracing.
265  *
266  * @retval TRC_FAIL Failure
267  * @retval TRC_SUCCESS Success
268  */
269 traceResult xTraceDisable(void);
270 
271 /**
272  * @brief
273  *
274  * For snapshot mode only: Sets the "filter group" to assign when creating
275  * RTOS objects, such as tasks, queues, semaphores and mutexes. This together
276  * with vTraceSetFilterMask allows you to control what events that are recorded,
277  * based on the objects they refer to.
278  *
279  * There are 16 filter groups named FilterGroup0 .. FilterGroup15.
280  *
281  * Note: We don't recommend filtering out the Idle task, so make sure to call
282  * vTraceSetFilterGroup just before initializing the RTOS, in order to assign
283  * such "default" objects to the right Filter Group (typically group 0).
284  *
285  * Example:
286  *
287  *		// Assign tasks T1 to FilterGroup0 (default)
288  *		<Create Task T1>
289  *
290  *		// Assign Q1 and Q2 to FilterGroup1
291  *		vTraceSetFilterGroup(FilterGroup1);
292  *		<Create Queue Q1>
293  *		<Create Queue Q2>
294  *
295  *		// Assigns Q3 to FilterGroup2
296  *		vTraceSetFilterGroup(FilterGroup2);
297  *		<Create Queue Q3>
298  *
299  *		// Only include FilterGroup0 and FilterGroup2, exclude FilterGroup1 (Q1 and Q2) from the trace
300  *		vTraceSetFilterMask( FilterGroup0 | FilterGroup2 );
301  *
302  *		// Assign the default RTOS objects (e.g. Idle task) to FilterGroup0
303  *		vTraceSetFilterGroup(FilterGroup0);
304  *		<Start the RTOS scheduler>
305  *
306  * Note that you may define your own names for the filter groups using
307  * preprocessor definitions, to make the code easier to understand.
308  *
309  * Example:
310  *
311  *		#define BASE FilterGroup0
312  *		#define USB_EVENTS FilterGroup1
313  *		#define CAN_EVENTS FilterGroup2
314  *
315  * Note that filtering per event type (regardless of object) is also available
316  * in trcKernelPortConfig.h for certain kernels.
317  *
318  * @param[in] filterGroup Filter group
319  */
320 void vTraceSetFilterGroup(uint16_t filterGroup);
321 
322 /**
323  * @brief
324  *
325  * For snapshot mode only: Sets the "filter mask" that is used to filter
326  * the events by object. This can be used to reduce the trace data rate, i.e.,
327  * if your streaming interface is a bottleneck or if you want longer snapshot
328  * traces without increasing the buffer size.
329  *
330  * Note: There are two kinds of filters in the recorder. The other filter type
331  * excludes all events of certain kinds (e.g., OS ticks). See trcConfig.h.
332  *
333  * The filtering is based on bitwise AND with the Filter Group ID, assigned
334  * to RTOS objects such as tasks, queues, semaphores and mutexes.
335  * This together with vTraceSetFilterGroup allows you to control what
336  * events that are recorded, based on the objects they refer to.
337  *
338  * See example for vTraceSetFilterGroup.
339  *
340  * @param[in] filterMask Filter mask
341  */
342 void vTraceSetFilterMask(uint16_t filterMask);
343 
344 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
345 
346 #include <stdarg.h>
347 
348 /**
349  * @brief Returns lower 16 bits of a value
350  *
351  * @param[in] value The starting value
352  */
353 #define TRACE_GET_LOW16(value) ((uint16_t)((value) & 0x0000FFFF))
354 
355 /**
356  * @brief Returns upper 16 bits
357  *
358  * @param[in] value The starting value
359  */
360 #define TRACE_GET_HIGH16(value) ((uint16_t)(((value) >> 16) & 0x0000FFFF))
361 
362 /**
363  * @brief Sets lower 16 bits
364  *
365  * @param[in] current The starting value
366  * @param[in] value The value to set
367  */
368 #define TRACE_SET_LOW16(current, value)  (((current) & 0xFFFF0000) | (value))
369 
370 /**
371  * @brief Sets upper 16 bits
372  *
373  * @param[in] current The starting value
374  * @param[in] value The value to set
375  */
376 #define TRACE_SET_HIGH16(current, value) (((current) & 0x0000FFFF) | (((uint32_t)(value)) << 16))
377 
378 #if defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
379 /**
380  * @brief Adds a task to the stack monitor
381  *
382  * @param[in] task The task
383  */
384 void prvAddTaskToStackMonitor(void* task);
385 
386 /**
387  * @brief Remove a task from the stack monitor
388  *
389  * @param[in] task The task
390  */
391 void prvRemoveTaskFromStackMonitor(void* task);
392 
393 /**
394  * @brief Reports on the current stack usage
395  */
396 void prvReportStackUsage(void);
397 
398 #else /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
399 
400 #define prvAddTaskToStackMonitor(task)
401 #define prvRemoveTaskFromStackMonitor(task)
402 #define prvReportStackUsage()
403 
404 #endif /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
405 
406 /**
407  * @internal Deprecated - Registers an ISR
408  */
409 traceHandle xTraceSetISRProperties(const char* szName, uint8_t uiPriority);
410 
411 /**
412  * @brief
413  *
414  * Registers an ISR.
415  *
416  * Example:
417  *	 #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
418  *	 ...
419  *	 TraceISRHandle_t Timer1Handle;
420  *	 xTraceISRRegister("ISRTimer1", PRIO_ISR_TIMER1, &Timer1Handle);
421  *
422  * @param[in] szName ISR name
423  * @param[in] uiPriority ISR priority
424  * @param[in] pxISRHandle
425  *
426  * @retval TRC_FAIL Failure
427  * @retval TRC_SUCCESS Success
428  */
429 traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t* pxISRHandle);
430 
431 /**
432  * @brief
433  *
434  * Registers the beginning of an Interrupt Service Routine, using a TraceISRHandle_t
435  * provided by xTraceISRRegister.
436  *
437  * Example:
438  *	 #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
439  *	 ...
440  *	 TraceISRHandle_t Timer1Handle;
441  *	 xTraceISRRegister("ISRTimer1", PRIO_ISR_TIMER1, &Timer1Handle);
442  *	 ...
443  *	 void ISR_handler()
444  *	 {
445  *		 xTraceISRBegin(Timer1Handle);
446  *		 ...
447  *		 xTraceISREnd(0);
448  *	 }
449  *
450  * @param[in] xHandle Handle for the previously registered ISR
451  *
452  * @retval TRC_FAIL Failure
453  * @retval TRC_SUCCESS Success
454  */
455 traceResult xTraceISRBegin(TraceISRHandle_t xHandle);
456 
457 #define vTraceStoreISRBegin(__handle) (void)xTraceISRBegin((TraceISRHandle_t)(__handle))
458 
459 /**
460  * @brief
461  *
462  * Registers the end of an Interrupt Service Routine.
463  *
464  * The parameter pendingISR indicates if the interrupt has requested a
465  * task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the
466  * interrupt is assumed to return to the previous context.
467  *
468  * Example:
469  *	 #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
470  *	 ...
471  *	 TraceISRHandle_t Timer1Handle;
472  *	 xTraceISRRegister("ISRTimer1", PRIO_ISR_TIMER1, &Timer1Handle);
473  *	 ...
474  *	 void ISR_handler()
475  *	 {
476  *		 xTraceISRBegin(Timer1Handle);
477  *		 ...
478  *		 xTraceISREnd(0);
479  *	 }
480  *
481  * @param[in] pendingISR Flag that indicates whether an ISR is pending
482  *
483  * @retval TRC_FAIL Failure
484  * @retval TRC_SUCCESS Success
485  */
486 traceResult xTraceISREnd(int pendingISR);
487 
488 #define vTraceStoreISREnd(__pendingISR) (void)xTraceISREnd(__pendingISR)
489 
490 /**
491  * @brief Query if recorder is enabled
492  *
493  * @retval 1 if recorder is enabled
494  * @retval 0 if recorder is disabled
495  */
496 uint32_t xTraceIsRecorderEnabled(void);
497 
498 /**
499  * @brief
500  *
501  * @retval 1 if recorder is initialized
502  * @retval 0 if recorder isn't initialized
503  */
504 uint32_t xTraceIsRecorderInitialized(void);
505 
506 /**
507  * @brief
508  *
509  * Creates an event that ends the current task instance at this very instant.
510  * This makes the viewer to splits the current fragment at this point and begin
511  * a new actor instance, even if no task-switch has occurred.
512  *
513  * @retval TRC_FAIL Failure
514  * @retval TRC_SUCCESS Success
515  */
516 traceResult xTraceTaskInstanceFinishedNow(void);
517 
518 /**
519  * @brief
520  *
521  * Marks the current "task instance" as finished on the next kernel call.
522  *
523  * If that kernel call is blocking, the instance ends after the blocking event
524  * and the corresponding return event is then the start of the next instance.
525  * If the kernel call is not blocking, the viewer instead splits the current
526  * fragment right before the kernel call, which makes this call the first event
527  * of the next instance.
528  *
529  * @retval TRC_FAIL Failure
530  * @retval TRC_SUCCESS Success
531  */
532 traceResult xTraceTaskInstanceFinishedNext(void);
533 
534 /**
535  * @brief Registers a string and returns a handle that can be used when tracing
536  *
537  * @param[in] label Label
538  * @param[out] pxString String handle
539  *
540  * @retval TRC_FAIL Failure
541  * @retval TRC_SUCCESS Success
542  */
543 traceResult xTraceStringRegister(const char* label, TraceStringHandle_t* pxString);
544 
545 /**
546  * @brief Registers a string and returns a handle that can be used when tracing
547  *
548  * @deprecated Backwards compatibility
549  *
550  * @param[in] name Name.
551  *
552  * @return TraceStringHandle_t String handle
553  */
554 TraceStringHandle_t xTraceRegisterString(const char* name);
555 
556 #if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
557 /**
558  * @brief
559  *
560  * Generates "User Events", with formatted text and data, similar to a "printf".
561  * User Events can be used for very efficient logging from your application code.
562  * It is very fast since the actual string formatting is done on the host side,
563  * when the trace is displayed. The execution time is just some microseconds on
564  * a 32-bit MCU.
565  *
566  * User Events are shown as yellow labels in the main trace view of $PNAME.
567  *
568  * An advantage of User Events is that data can be plotted in the "User Event
569  * Signal Plot" view, visualizing any data you log as User Events, discrete
570  * states or control system signals (e.g. system inputs or outputs).
571  *
572  * You may group User Events into User Event Channels. The yellow User Event
573  * labels show the logged string, preceded by the channel name within brackets.
574  *
575  * Example:
576  *
577  *  "[MyChannel] Hello World!"
578  *
579  * The User Event Channels are shown in the View Filter, which makes it easy to
580  * select what User Events you wish to display. User Event Channels are created
581  * using xTraceStringRegister().
582  *
583  * Example:
584  *
585  *	 TraceStringHandle_t adc_uechannel;
586  *	 xTraceStringRegister("ADC User Events", &adc_uechannel);
587  *	 ...
588  *	 xTracePrintF(adc_uechannel,
589  *				 "ADC channel %d: %d volts",
590  *				 ch, adc_reading);
591  *
592  * The following format specifiers are supported in both modes:
593  * %d - signed integer.
594  * %u - unsigned integer.
595  * %X - hexadecimal, uppercase.
596  * %x - hexadecimal, lowercase.
597  * %s - string (see comment below)
598  *
599  * For integer formats (%d, %u, %x, %X) you may also use width and padding.
600  * If using -42 as data argument, two examples are:
601  *    "%05d" -> "-0042"
602  *     "%5d" -> "  -42".
603  *
604  * String arguments are supported in both snapshot and streaming, but in streaming
605  * mode you need to use xTraceStringRegister and use the returned TraceStringHandle_t as
606  * the argument. In snapshot you simply provide a char* as argument.
607  *
608  * Snapshot: xTracePrintF(myChn, "my string: %s", str);
609  * Streaming: xTracePrintF(myChn, "my string: %s", strTraceString);
610  *
611  * In snapshot mode you can specify 8-bit or 16-bit arguments to reduce RAM usage:
612  *     %hd -> 16 bit (h) signed integer (d).
613  *     %bu -> 8 bit (b) unsigned integer (u).
614  *
615  * However, in streaming mode all data arguments are assumed to be 32 bit wide.
616  * Width specifiers (e.g. %hd) are accepted but ignored (%hd treated like %d).
617  *
618  * The maximum event size also differs between the modes. In streaming this is
619  * limited by a maximum payload size of 52 bytes, including format string and
620  * data arguments. So if using one data argument, the format string is limited
621  * to 48 byte, etc. If this is exceeded,  the format string is truncated and you
622  * get a warning in Tracealyzer.
623  *
624  * In snapshot mode you are limited to maximum 15 arguments, that must not exceed
625  * 32 bytes in total (not counting the format string). If exceeded, the recorder
626  * logs an internal error (displayed when opening the trace) and stops recording.
627  *
628  * @param[in] chn Channel.
629  * @param[in] fmt Formatting.
630  * @param[in] ...
631  *
632  * @retval TRC_FAIL Failure
633  * @retval TRC_SUCCESS Success
634  */
635 traceResult xTracePrintF(TraceStringHandle_t chn, const char* fmt, ...);
636 #else
637 #define xTracePrintF(chn, fmt, ...) ((void)(chn), (void)(fmt), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
638 #endif
639 
640 #if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
641 /**
642  * @brief
643  *
644  * xTracePrintF variant that accepts a va_list.
645  * See xTracePrintF documentation for further details.
646  *
647  * @param[in] eventLabel
648  * @param[in] formatStr
649  * @param[in] vl
650  *
651  * @retval TRC_FAIL Failure
652  * @retval TRC_SUCCESS Success
653  */
654 traceResult xTraceVPrintF(TraceStringHandle_t eventLabel, const char* formatStr, va_list vl);
655 #else
656 #define xTraceVPrintF(chn, formatStr, vl) ((void)(chn), (void)(formatStr), (void)(vl), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
657 #endif
658 
659 #if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
660 /**
661  * @brief A faster version of xTracePrintF, that only allows for logging a string.
662  *
663  * Example:
664  *
665  *	 TraceStringHandle_t chn;
666  *	 xTraceStringRegister("MyChannel", &chn);
667  *	 ...
668  *	 xTracePrint(chn, "Hello World!");
669  *
670  * @param[in] chn Channel.
671  * @param[in] str String.
672  *
673  * @retval TRC_FAIL Failure
674  * @retval TRC_SUCCESS Success
675  */
676 traceResult xTracePrint(TraceStringHandle_t chn, const char* str);
677 #else
678 #define xTracePrint(chn, str) ((void)(chn), (void)(str), TRC_SUCCESS)
679 #endif
680 
681 /******************************************************************************/
682 /*** Extended API for Snapshot mode *******************************************/
683 /******************************************************************************/
684 
685 /**
686  * @brief Trace stop callback type.
687  */
688 typedef void(*TRACE_STOP_HOOK)(void);
689 
690 /**
691  * @brief Sets a function to be called when the recorder is stopped.
692  *
693  * @note Snapshot mode only!
694  *
695  * @param[in] stopHookFunction
696  */
697 void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction);
698 
699 /**
700  * @brief
701  *
702  * Resets the recorder.
703  *
704  * Only necessary if a restart is desired - this is not
705  * needed in the startup initialization.
706  *
707  * @note Snapshot mode only!
708  */
709 void vTraceClear(void);
710 
711 /*****************************************************************************/
712 /*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/
713 /*****************************************************************************/
714 
715 #define TRC_UNUSED
716 
717 #ifndef TRC_CFG_INCLUDE_OBJECT_DELETE
718 #define TRC_CFG_INCLUDE_OBJECT_DELETE 0
719 #endif
720 
721 #ifndef TRC_CFG_INCLUDE_READY_EVENTS
722 #define TRC_CFG_INCLUDE_READY_EVENTS 1
723 #endif
724 
725 #ifndef TRC_CFG_INCLUDE_OSTICK_EVENTS
726 #define TRC_CFG_INCLUDE_OSTICK_EVENTS 0
727 #endif
728 
729 /* This macro will create a task in the object table */
730 #undef trcKERNEL_HOOKS_TASK_CREATE
731 #define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, pxTCB) \
732 	if ((pxTCB) != 0) \
733 	{ \
734 		TRACE_SET_OBJECT_NUMBER(TASK, pxTCB); \
735 		TRACE_SET_OBJECT_FILTER(TASK, pxTCB, CurrentFilterGroup); \
736 		prvTraceSetObjectName(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_NAME(pxTCB)); \
737 		prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
738 		if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
739 			if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
740 				prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
741 	} \
742 	else \
743 	{ \
744 		/* pxTCB is null */ \
745 		if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
746 		{ \
747 			prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, 0); \
748 		} \
749 	}
750 
751 /* This macro will remove the task and store it in the event buffer */
752 #undef trcKERNEL_HOOKS_TASK_DELETE
753 #define trcKERNEL_HOOKS_TASK_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, pxTCB) \
754 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
755 		if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
756 			prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
757 	prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
758 	prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
759 	prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
760 	prvTraceSetObjectState(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TASK_STATE_INSTANCE_NOT_ACTIVE); \
761 	prvTraceFreeObjectHandle(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
762 
763 
764 /* This macro will setup a task in the object table */
765 #undef trcKERNEL_HOOKS_OBJECT_CREATE
766 #define trcKERNEL_HOOKS_OBJECT_CREATE(SERVICE, CLASS, pxObject) \
767 	TRACE_SET_OBJECT_NUMBER(CLASS, pxObject); \
768 	TRACE_SET_OBJECT_FILTER(CLASS, pxObject, CurrentFilterGroup); \
769 	prvMarkObjectAsUsed(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject),  TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));\
770 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
771 		if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
772 			prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
773 	prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), 0);
774 
775 /* This macro will setup a task in the object table */
776 #undef trcKERNEL_HOOKS_OBJECT_CREATE_FAILED
777 #define trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(SERVICE, TRACE_CLASS)\
778 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
779 	{ \
780 		prvTraceStoreKernelCall(SERVICE, TRACE_CLASS, 0); \
781 	}
782 
783 /* This macro will remove the object and store it in the event buffer */
784 #undef trcKERNEL_HOOKS_OBJECT_DELETE
785 #define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, CLASS, pxObject) \
786 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
787 		if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
788 			prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
789 	prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
790 	prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
791 	prvTraceFreeObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
792 
793 /* This macro will create a call to a kernel service with a certain result, with an object as parameter */
794 #undef trcKERNEL_HOOKS_KERNEL_SERVICE
795 #define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, CLASS, pxObject) \
796 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
797 		if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
798 			prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
799 
800 /* This macro will create a call to a kernel service with a certain result, with a null object as parameter */
801 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT
802 #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT(SERVICE, TRACECLASS) \
803 	if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
804 		prvTraceStoreKernelCall(SERVICE, TRACECLASS, 0);
805 
806 /* This macro will create a call to a kernel service with a certain result, with an object as parameter */
807 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM
808 #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(SERVICE, CLASS, pxObject, param) \
809 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
810 		if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
811 			prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param);
812 
813 /* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */
814 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM
815 #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM(SERVICE, TRACECLASS, param) \
816 	if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
817 		prvTraceStoreKernelCallWithParam(SERVICE, TRACECLASS, 0, param);
818 
819 /* This macro will create a call to a kernel service with a certain result, with an object as parameter */
820 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY
821 #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(SERVICE, param) \
822 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
823 		prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param);
824 
825 /* This macro will create a call to a kernel service with a certain result, with an object as parameter */
826 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR
827 #define trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(SERVICE, CLASS, pxObject) \
828 	if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
829 		prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
830 
831 /* This macro will create a call to a kernel service with a certain result, with a null object as parameter */
832 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR
833 #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR(SERVICE, TRACECLASS) \
834 	prvTraceStoreKernelCall(SERVICE, TRACECLASS, 0);
835 
836 /* This macro will create a call to a kernel service with a certain result, with an object as parameter */
837 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR
838 #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(SERVICE, CLASS, pxObject, param) \
839 	if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
840 		prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param);
841 
842 /* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */
843 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR
844 #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR(SERVICE, TRACECLASS, param) \
845 	prvTraceStoreKernelCallWithParam(SERVICE, TRACECLASS, 0, param);
846 
847 /* This macro will create a call to a kernel service with a certain result, with an object as parameter */
848 #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR
849 #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR(SERVICE, param) \
850 	prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param);
851 
852 /* This macro will set the state for an object */
853 #undef trcKERNEL_HOOKS_SET_OBJECT_STATE
854 #define trcKERNEL_HOOKS_SET_OBJECT_STATE(CLASS, pxObject, STATE) \
855 	prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint8_t)STATE);
856 
857 /* This macro will flag a certain task as a finished instance */
858 #undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED
859 #define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \
860 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
861 		prvTraceSetTaskInstanceFinished(TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()));
862 
863 #if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
864 /* This macro will create an event to indicate that a task became Ready */
865 #undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
866 #define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) \
867 	if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
868 		prvTraceStoreTaskReady(TRACE_GET_TASK_NUMBER(pxTCB));
869 #else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
870 #undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
871 #define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB)
872 #endif /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
873 
874 /* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */
875 #undef trcKERNEL_HOOKS_INCREMENT_TICK
876 #define trcKERNEL_HOOKS_INCREMENT_TICK() \
877 	{ \
878 		extern uint32_t uiTraceTickCount; \
879 		uiTraceTickCount++; \
880 		prvTracePortGetTimeStamp(0); \
881 	}
882 
883 #if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)
884 /* This macro will create an event indicating that the OS tick count has increased */
885 #undef trcKERNEL_HOOKS_NEW_TIME
886 #define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue) \
887 	prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue);
888 #else /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/
889 #undef trcKERNEL_HOOKS_NEW_TIME
890 #define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue)
891 #endif /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/
892 
893 /* This macro will create a task switch event to the currently executing task */
894 #undef trcKERNEL_HOOKS_TASK_SWITCH
895 #define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \
896 	if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
897 		prvTraceStoreTaskswitch(TRACE_GET_TASK_NUMBER(pxTCB));
898 
899 /* This macro will create an event to indicate that the task has been suspended */
900 #undef trcKERNEL_HOOKS_TASK_SUSPEND
901 #define trcKERNEL_HOOKS_TASK_SUSPEND(SERVICE, pxTCB) \
902 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
903 		if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
904 			prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
905 	prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB));
906 
907 /* This macro will create an event to indicate that a task has called a wait/delay function */
908 #undef trcKERNEL_HOOKS_TASK_DELAY
909 #define trcKERNEL_HOOKS_TASK_DELAY(SERVICE, pxTCB, xValue) \
910 	if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
911 	{ \
912 		prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); \
913 		prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); \
914 	}
915 
916 /* This macro will create an event to indicate that a task has gotten its priority changed */
917 #undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE
918 #define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(SERVICE, pxTCB, uxNewPriority) \
919 	if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
920 	{ \
921 		prvTraceStoreKernelCallWithParam(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), prvTraceGetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)));\
922 		prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), (uint8_t)uxNewPriority); \
923 	}
924 
925 /* This macro will create an event to indicate that the task has been resumed */
926 #undef trcKERNEL_HOOKS_TASK_RESUME
927 #define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \
928 	if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
929 		if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
930 			prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
931 
932 /* This macro will create an event to indicate that the task has been resumed from ISR */
933 #undef trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR
934 #define trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(SERVICE, pxTCB) \
935 	if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
936 		prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
937 
938 #if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
939 /**
940  * @brief Dynamically enables ready events
941  *
942  * @param[in] flag Flag
943  */
944 void prvTraceSetReadyEventsEnabled(uint32_t flag);
945 
946 /**
947  * @brief Stores a Task Ready event
948  *
949  * @param[in] handle Task handle
950  */
951 void prvTraceStoreTaskReady(traceHandle handle);
952 #else
953 #define prvTraceSetReadyEventsEnabled(status) (void)status;
954 #endif
955 
956 /**
957  * @brief Stores a Low Power mode event
958  *
959  * @param[in] flag Flag
960  */
961 void prvTraceStoreLowPower(uint32_t flag);
962 
963 /**
964  * @brief Stores a Task Switch event
965  *
966  * @param[in] task_handle Task
967  */
968 void prvTraceStoreTaskswitch(traceHandle task_handle);
969 
970 #if (TRC_CFG_SCHEDULING_ONLY == 0)
971 
972 /**
973  * @brief Stores a Kernel Service call event with an Object handle parameter
974  *
975  * @param[in] eventcode Event code
976  * @param[in] objectClass Object class
977  * @param[in] objectNumber Object handle
978  */
979 void prvTraceStoreKernelCall(uint32_t eventcode, traceObjectClass objectClass, uint32_t objectNumber);
980 
981 /**
982  * @brief Stores a Kernel Service call event with only a numeric parameter
983  *
984  * @param[in] evtcode Event code
985  * @param[in] param Parameter
986  */
987 void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param);
988 
989 /**
990  * @brief Stores a Kernel Service call event with an Object handle and a numeric parameter
991  *
992  * @param[in] evtcode Event code
993  * @param[in] objectClass Object class
994  * @param[in] objectNumber Object handle
995  * @param[in] param Parameter
996  */
997 void prvTraceStoreKernelCallWithParam(uint32_t evtcode, traceObjectClass objectClass,
998 									uint32_t objectNumber, uint32_t param);
999 #else
1000 
1001 #define prvTraceStoreKernelCall(eventcode, objectClass, byteParam) {}
1002 #define prvTraceStoreKernelCallWithNumericParamOnly(evtcode, param) {}
1003 #define prvTraceStoreKernelCallWithParam(evtcode, objectClass, objectNumber, param) {}
1004 
1005 #endif
1006 
1007 /**
1008  * @brief Flags a task instance as finished
1009  *
1010  * @param[in] handle Task handle
1011  */
1012 void prvTraceSetTaskInstanceFinished(traceHandle handle);
1013 
1014 /**
1015  * @brief Set priority
1016  *
1017  * @param[in] objectclass Object class
1018  * @param[in] id Object handle
1019  * @param[in] value Value
1020  */
1021 void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value);
1022 
1023 /**
1024  * @brief Get priority
1025  *
1026  * @param[in] objectclass Object class
1027  * @param[in] id Object handle
1028  *
1029  * @return uint8_t Value
1030  */
1031 uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id);
1032 
1033 /**
1034  * @brief Set object state
1035  *
1036  * @param[in] objectclass Object class
1037  * @param[in] id Object handle
1038  * @param[in] value Value
1039  */
1040 void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value);
1041 
1042 /**
1043  * @brief Mark object as used
1044  *
1045  * @param[in] objectclass Object class
1046  * @param[in] handle Object handle
1047  */
1048 void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle);
1049 
1050 /**
1051  * @brief Stores the name of an object because it is being deleted
1052  *
1053  * @param[in] evtcode Event code
1054  * @param[in] handle Object handle
1055  * @param[in] objectclass Object class
1056  */
1057 void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle,
1058 										traceObjectClass objectclass);
1059 
1060 /**
1061  * @brief Stores the property of an object because it is being deleted
1062  *
1063  * @param[in] evtcode Event code
1064  * @param[in] handle Object handle
1065  * @param[in] objectclass Object class
1066  */
1067 void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle,
1068 											 traceObjectClass objectclass);
1069 
1070 /* Internal constants for task state */
1071 #define TASK_STATE_INSTANCE_NOT_ACTIVE 0
1072 #define TASK_STATE_INSTANCE_ACTIVE 1
1073 
1074 
1075 #if (TRC_CFG_INCLUDE_ISR_TRACING == 0)
1076 
1077 #undef vTraceSetISRProperties
1078 #define vTraceSetISRProperties(handle, name, priority) (void)(handle), (void)(name), (void)(priority) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
1079 
1080 #undef vTraceStoreISRBegin
1081 #define vTraceStoreISRBegin(x) (void)(x)
1082 
1083 #undef vTraceStoreISREnd
1084 #define vTraceStoreISREnd(x) (void)(x)
1085 
1086 #undef xTraceSetISRProperties
1087 #define xTraceSetISRProperties(name, priority) ((void)(name), (void)(priority), (traceHandle)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
1088 
1089 #endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/
1090 
1091 /**
1092  * @brief
1093  *
1094  * Returns a pointer to the recorder data structure. Use this together with
1095  * uiTraceGetTraceBufferSize if you wish to implement an own store/upload
1096  * solution, e.g., in case a debugger connection is not available for uploading
1097  * the data.
1098  *
1099  * @return void* Buffer pointer
1100  */
1101 void* xTraceGetTraceBuffer(void);
1102 
1103 /**
1104  * @brief
1105  *
1106  * Gets the size of the recorder data structure. For use together with
1107  * xTraceGetTraceBuffer if you wish to implement an own store/upload solution,
1108  * e.g., in case a debugger connection is not available for uploading the data.
1109  *
1110  * @return uint32_t Buffer size
1111  */
1112 uint32_t uiTraceGetTraceBufferSize(void);
1113 
1114 #if (TRC_CFG_SCHEDULING_ONLY == 1)
1115 #undef TRC_CFG_INCLUDE_USER_EVENTS
1116 #define TRC_CFG_INCLUDE_USER_EVENTS 0
1117 #endif /*(TRC_CFG_SCHEDULING_ONLY == 1)*/
1118 
1119 #if ((TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
1120 
1121 /**
1122  * @brief Register a channel and fixed format string for use with the separate User Event Buffer functions
1123  *
1124  * @param[in] channel Channel name handle
1125  * @param[in] formatStr Format string that will be used for all events on this channel
1126  *
1127  * @return traceUBChannel Channel handle
1128  */
1129 traceUBChannel xTraceRegisterUBChannel(TraceStringHandle_t channel, TraceStringHandle_t formatStr);
1130 
1131 /**
1132  * @brief Creates a User Event using the channel, previously set format string and data parameters
1133  *
1134  * @param[in] channel Channel
1135  * @param[in] ...
1136  */
1137 void vTraceUBData(traceUBChannel channel, ...);
1138 
1139 /**
1140  * @brief Creates a User Event using the channel and previously set string
1141  *
1142  * @param[in] channel Channel
1143  */
1144 void vTraceUBEvent(traceUBChannel channel);
1145 #else
1146 #define xTraceRegisterChannelFormat(eventLabel, formatStr) ((void)(eventLabel), (void)(formatStr), 0)
1147 #define vTraceUBData(label, ...) (void)(label)
1148 #endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/
1149 
1150 #define NEventCodes 0x100
1151 
1152 /* Our local critical sections for the recorder */
1153 #define trcCRITICAL_SECTION_BEGIN() {TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++;}
1154 #define trcCRITICAL_SECTION_END() {recorder_busy--; TRACE_EXIT_CRITICAL_SECTION();}
1155 
1156 #if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M)
1157 	#define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY TRACE_ALLOC_CRITICAL_SECTION
1158 	#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_BEGIN
1159 	#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_END
1160 #else
1161 	#define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY() {}
1162 	#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY() recorder_busy++;
1163 	#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--;
1164 #endif
1165 
1166 /**
1167  * @brief Object handle stack struct.
1168  *
1169  * This data-structure is used to provide a mechanism for 1-byte trace object
1170  * handles. This way, only 1 byte is necessary instead of 4 bytes (a pointer)
1171  * when storing a reference to an object. This allows for up to 255 objects of
1172  * each object class active at any given moment. There can be more "historic"
1173  * objects, that have been deleted - that number is only limited by the size of
1174  * the symbol table.
1175  *
1176  * Note that handle zero (0) is not used, it is a code for an invalid handle.
1177  *
1178  * This data structure keeps track of the FREE handles, not the handles in use.
1179  * This data structure contains one stack per object class. When a handle is
1180  * allocated to an object, the next free handle is popped from the stack. When
1181  * a handle is released (on object delete), it is pushed back on the stack.
1182  * Note that there is no initialization code that pushed the free handles
1183  * initially, that is not necessary due to the following optimization:
1184  *
1185  * The stack of handles (objectHandles) is initially all zeros. Since zero
1186  * is not a valid handle, that is a signal of additional handles needed.
1187  * If a zero is received when popping a new handle, it is replaced by the
1188  * index of the popped handle instead.
1189  */
1190 typedef struct
1191 {
1192 	uint16_t indexOfNextAvailableHandle[ TRACE_NCLASSES ]; /**< For each object class, the index of the next handle to allocate */
1193 	uint16_t lowestIndexOfClass[ TRACE_NCLASSES ]; /**< The lowest index of this class (constant) */
1194 	uint16_t highestIndexOfClass[ TRACE_NCLASSES ]; /**< The highest index of this class (constant) */
1195 	uint16_t handleCountWaterMarksOfClass[ TRACE_NCLASSES ]; /**< The highest use count for this class (for statistics) */
1196 	traceHandle objectHandles[ TRACE_KERNEL_OBJECT_COUNT ]; /**< The free object handles - a set of stacks within this array */
1197 } objectHandleStackType;
1198 
1199 extern objectHandleStackType objectHandleStacks;
1200 
1201 /**
1202  * @brief Object property table struct
1203  *
1204  * The Object Table contains name and other properties of the objects (tasks,
1205  * queues, mutexes, etc). The below data structures defines the properties of
1206  * each object class and are used to cast the byte buffer into a cleaner format.
1207  *
1208  * The values in the object table are continuously overwritten and always
1209  * represent the current state. If a property is changed during runtime, the OLD
1210  * value should be stored in the trace buffer, not the new value (since the new
1211  * value is found in the Object Property Table).
1212  *
1213  * For close events this mechanism is the old names are stored in the symbol
1214  * table), for "priority set" (the old priority is stored in the event data)
1215  * and for "isActive", where the value decides if the task switch event type
1216  * should be "new" or "resume".
1217  */
1218 typedef struct
1219 {
1220 	/* = NCLASSES */
1221 	uint32_t NumberOfObjectClasses; /**< */
1222 	uint32_t ObjectPropertyTableSizeInBytes; /**<  */
1223 
1224 	/* This is used to calculate the index in the dynamic object table
1225 	(handle - 1 - nofStaticObjects = index)*/
1226 #if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
1227 	traceHandle NumberOfObjectsPerClass[2*((TRACE_NCLASSES+1)/2)]; /** */
1228 #else
1229 	traceHandle NumberOfObjectsPerClass[4*((TRACE_NCLASSES+3)/4)]; /** */
1230 #endif
1231 	/* Allocation size rounded up to the closest multiple of 4 */
1232 	uint8_t NameLengthPerClass[ 4*((TRACE_NCLASSES+3)/4) ]; /**< */
1233 
1234 	/* Allocation size rounded up to the closest multiple of 2 */
1235 	uint8_t TotalPropertyBytesPerClass[ 4*((TRACE_NCLASSES+3)/4) ]; /**< */
1236 
1237 	/* */
1238 	uint16_t StartIndexOfClass[ 2*((TRACE_NCLASSES+1)/2) ]; /**< */
1239 
1240 	/* The actual handles issued, should be Initiated to all zeros */
1241 	uint8_t objbytes[ 4*((TRACE_OBJECT_TABLE_SIZE+3)/4) ]; /**< */
1242 } ObjectPropertyTableType;
1243 
1244 /**
1245  * @brief Symbol table structure
1246  */
1247 typedef struct
1248 {
1249 	/* = SYMBOL_HISTORY_TABLE_SIZE_IN_BYTES */
1250 	uint32_t symTableSize; /**< */
1251 
1252 	/* Entry 0 is reserved. Any reference to entry 0 implies NULL*/
1253 	uint32_t nextFreeSymbolIndex; /**< */
1254 
1255 	/* Size rounded up to closest multiple of 4, to avoid alignment issues*/
1256 	uint8_t symbytes[4*(((TRC_CFG_SYMBOL_TABLE_SIZE)+3)/4)]; /**< */
1257 
1258 	/* Used for lookups - Up to 64 linked lists within the symbol table
1259 	connecting all entries with the same 6 bit checksum.
1260 	This field holds the current list heads. Should be initiated to zeros */
1261 	uint16_t latestEntryOfChecksum[64]; /**< */
1262 } symbolTableType;
1263 
1264 
1265 /*******************************************************************************
1266  * The data structures of the different events, all 4 bytes long
1267  ******************************************************************************/
1268 
1269 typedef struct
1270 {
1271 	uint8_t type;
1272 	uint8_t objHandle;
1273 	uint16_t dts;	/* differential timestamp - time since last event */
1274 } TSEvent, TREvent;
1275 
1276 typedef struct
1277 {
1278 	uint8_t type;
1279 	uint8_t dummy;
1280 	uint16_t dts;	/* differential timestamp - time since last event */
1281 } LPEvent;
1282 
1283 typedef struct
1284 {
1285 	uint8_t type;
1286 	uint8_t objHandle;
1287 	uint16_t dts;	/* differential timestamp - time since last event */
1288 } KernelCall;
1289 
1290 typedef struct
1291 {
1292 	uint8_t type;
1293 	uint8_t objHandle;
1294 	uint8_t param;
1295 	uint8_t dts;	/* differential timestamp - time since last event */
1296 } KernelCallWithParamAndHandle;
1297 
1298 typedef struct
1299 {
1300 	uint8_t type;
1301 	uint8_t dts;	/* differential timestamp - time since last event */
1302 	uint16_t param;
1303 } KernelCallWithParam16;
1304 
1305 typedef struct
1306 {
1307 	uint8_t type;
1308 	uint8_t objHandle;		/* the handle of the closed object */
1309 	uint16_t symbolIndex;	/* the name of the closed object */
1310 } ObjCloseNameEvent;
1311 
1312 typedef struct
1313 {
1314 	uint8_t type;
1315 	uint8_t arg1;
1316 	uint8_t arg2;
1317 	uint8_t arg3;
1318 } ObjClosePropEvent;
1319 
1320 typedef struct
1321 {
1322 	uint8_t type;
1323 	uint8_t unused1;
1324 	uint8_t unused2;
1325 	uint8_t dts;
1326 } TaskInstanceStatusEvent;
1327 
1328 typedef struct
1329 {
1330 	uint8_t type;
1331 	uint8_t dts;
1332 	uint16_t payload;		 /* the name of the user event */
1333 } UserEvent;
1334 
1335 typedef struct
1336 {
1337 	uint8_t type;
1338 
1339 	/* 8 bits extra for storing DTS, if it does not fit in ordinary event
1340 	(this one is always MSB if used) */
1341 	uint8_t xts_8;
1342 
1343 	/* 16 bits extra for storing DTS, if it does not fit in ordinary event. */
1344 	uint16_t xts_16;
1345 } XTSEvent;
1346 
1347 typedef struct
1348 {
1349 	uint8_t type;
1350 
1351 	uint8_t xps_8;
1352 	uint16_t xps_16;
1353 } XPSEvent;
1354 
1355 typedef struct{
1356 	uint8_t type;
1357 	uint8_t dts;
1358 	uint16_t size;
1359 } MemEventSize;
1360 
1361 typedef struct{
1362 	uint8_t type;
1363 	uint8_t addr_high;
1364 	uint16_t addr_low;
1365 } MemEventAddr;
1366 
1367 /*******************************************************************************
1368  * The separate user event buffer structure. Can be enabled in trcConfig.h.
1369  ******************************************************************************/
1370 
1371 #if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
1372 typedef struct
1373 {
1374 	TraceStringHandle_t name;
1375 	TraceStringHandle_t defaultFormat;
1376 } ChannelFormatPair;
1377 
1378 typedef struct
1379 {
1380 	uint16_t bufferID;
1381 	uint16_t version;
1382 	uint32_t wraparoundCounter;
1383 	uint32_t numberOfSlots;
1384 	uint32_t nextSlotToWrite;
1385 	uint8_t numberOfChannels;
1386 	uint8_t padding1;
1387 	uint8_t padding2;
1388 	uint8_t padding3;
1389 	ChannelFormatPair channels[(TRC_CFG_UB_CHANNELS)+1];
1390 	uint8_t channelBuffer[((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) + 3) & 0xFFFFFFFC]; /* 1 byte per slot, with padding for 4 byte alignment */
1391 	uint8_t dataBuffer[(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) * 4]; /* 4 bytes per slot */
1392 
1393 } UserEventBuffer;
1394 #endif /* (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) */
1395 
1396 /*******************************************************************************
1397  * The main data structure, read by Tracealyzer from the RAM dump
1398  ******************************************************************************/
1399 
1400 typedef struct
1401 {
1402 	volatile uint8_t startmarker0; /* Volatile is important, see init code. */
1403 	volatile uint8_t startmarker1;
1404 	volatile uint8_t startmarker2;
1405 	volatile uint8_t startmarker3;
1406 	volatile uint8_t startmarker4;
1407 	volatile uint8_t startmarker5;
1408 	volatile uint8_t startmarker6;
1409 	volatile uint8_t startmarker7;
1410 	volatile uint8_t startmarker8;
1411 	volatile uint8_t startmarker9;
1412 	volatile uint8_t startmarker10;
1413 	volatile uint8_t startmarker11;
1414 
1415 	/* Used to determine Kernel and Endianess */
1416 	uint16_t version;
1417 
1418 	/* Currently 7 */
1419 	uint8_t minor_version;
1420 
1421 	/* This should be 0 if lower IRQ priority values implies higher priority
1422 	levels, such as on ARM Cortex M. If the opposite scheme is used, i.e.,
1423 	if higher IRQ priority values means higher priority, this should be 1. */
1424 	uint8_t irq_priority_order;
1425 
1426 	/* sizeof(RecorderDataType) - just for control */
1427 	uint32_t filesize;
1428 
1429 	/* Current number of events recorded */
1430 	uint32_t numEvents;
1431 
1432 	/* The buffer size, in number of event records */
1433 	uint32_t maxEvents;
1434 
1435 	/* The event buffer index, where to write the next event */
1436 	uint32_t nextFreeIndex;
1437 
1438 	/* 1 if the buffer is full, 0 otherwise */
1439 	uint32_t bufferIsFull;
1440 
1441 	/* The frequency of the clock/timer/counter used as time base */
1442 	uint32_t frequency;
1443 
1444 	/* The absolute timestamp of the last stored event, in the native
1445 	timebase, modulo frequency! */
1446 	uint32_t absTimeLastEvent;
1447 
1448 	/* The number of seconds in total - lasts for 136 years */
1449 	uint32_t absTimeLastEventSecond;
1450 
1451 	/* 1 if the recorder has been started, 0 if not yet started or stopped.
1452 	This is a 32 bit variable due to alignment issues. */
1453 	uint32_t recorderActive;
1454 
1455 	/* If > 0, tells the maximum time between two traced ISRs that execute
1456 	back-to-back. If the time between vTraceStoreISREnd and a directly
1457 	following vTraceISRBegin is above isrTailchainingThreshold, we assume a
1458 	return to the previous context in between the ISRs, otherwise we assume
1459 	the have executed back-to-back and don't show any fragment of the previous
1460 	context in between. */
1461 	uint32_t isrTailchainingThreshold;
1462 
1463 	/* The maximum amount of heap memory that was allocated */
1464 	uint32_t heapMemMaxUsage;
1465 
1466 	/* The amount of heap memory used */
1467 	uint32_t heapMemUsage;
1468 
1469 	/* 0xF0F0F0F0 - for control only */
1470 	int32_t debugMarker0;
1471 
1472 	/* Set to value of TRC_CFG_USE_16BIT_OBJECT_HANDLES */
1473 	uint32_t isUsing16bitHandles;
1474 
1475 	/* The Object Property Table holds information about currently active
1476 	tasks, queues, and other recorded objects. This is updated on each
1477 	create call and includes object name and other properties. */
1478 	ObjectPropertyTableType ObjectPropertyTable;
1479 
1480 	/* 0xF1F1F1F1 - for control only */
1481 	int32_t debugMarker1;
1482 
1483 	/* The Symbol Table stores strings for User Events and is also used to
1484 	store names of deleted objects, which still may be in the trace but no
1485 	longer are available. */
1486 	symbolTableType SymbolTable;
1487 
1488 	/* For inclusion of float support, and for endian detection of floats.
1489 	The value should be (float)1 or (uint32_t)0 */
1490 #if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1)
1491 	float exampleFloatEncoding;
1492 #else
1493 	uint32_t exampleFloatEncoding;
1494 #endif
1495 	/* This is non-zero if an internal error occurred in the recorder, e.g., if
1496 	one of the Nxxx constants was too small. The systemInfo string will then
1497 	contain an error message that is displayed when attempting to view the
1498 	trace file. */
1499 	uint32_t internalErrorOccured;
1500 
1501 	/* 0xF2F2F2F2 - for control only */
1502 	int32_t debugMarker2;
1503 
1504 	/* Error messages from the recorder. */
1505 	char systemInfo[80];
1506 
1507 	/* 0xF3F3F3F3 - for control only */
1508 	int32_t debugMarker3;
1509 
1510 	/* The event data, in 4-byte records */
1511 	uint8_t eventData[ (TRC_CFG_EVENT_BUFFER_SIZE) * 4 ];
1512 
1513 #if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
1514 	UserEventBuffer userEventBuffer;
1515 #endif
1516 
1517 	/* This should always be 0 */
1518 	uint32_t endOfSecondaryBlocks;
1519 
1520 	uint8_t endmarker0;
1521 	uint8_t endmarker1;
1522 	uint8_t endmarker2;
1523 	uint8_t endmarker3;
1524 	uint8_t endmarker4;
1525 	uint8_t endmarker5;
1526 	uint8_t endmarker6;
1527 	uint8_t endmarker7;
1528 	uint8_t endmarker8;
1529 	uint8_t endmarker9;
1530 	uint8_t endmarker10;
1531 	uint8_t endmarker11;
1532 } RecorderDataType;
1533 
1534 extern RecorderDataType* RecorderDataPtr;
1535 
1536 /* Internal functions */
1537 
1538 /**
1539  * @brief Signals a trace error
1540  *
1541  * @param[in] msg Message
1542  */
1543 void prvTraceError(const char* msg);
1544 
1545 /**
1546  * @brief
1547  *
1548  * Returns the current time based on the HWTC macros which provide a hardware
1549  * isolation layer towards the hardware timer/counter.
1550  *
1551  * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue
1552  * or the trace recorder library. Typically you should not need to change
1553  * the code of prvTracePortGetTimeStamp if using the HWTC macros.
1554  *
1555  * @param[out] puiTimestamp Timestamp
1556  */
1557 void prvTracePortGetTimeStamp(uint32_t *puiTimestamp);
1558 
1559 /**
1560  * @brief Reserve an object handle
1561  *
1562  * @param[in] objectclass Object class
1563  *
1564  * @return traceHandle
1565  */
1566 traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass);
1567 
1568 /**
1569  * @brief Free an object handle
1570  *
1571  * @param[in] objectclass Object class
1572  * @param[in] handle Handle
1573  */
1574 void prvTraceFreeObjectHandle(traceObjectClass objectclass,
1575 							traceHandle handle);
1576 
1577 /* Private function. Use the public functions in trcKernelPort.h */
1578 
1579 /**
1580  * @brief Set the object name
1581  *
1582  * @param[in] objectclass Object class
1583  * @param[in] handle Handle
1584  * @param[in] name Name
1585  */
1586 void prvTraceSetObjectName(traceObjectClass objectclass,
1587 							traceHandle handle,
1588 							const char* name);
1589 
1590 /* Internal macros */
1591 
1592 #define TRACE_PROPERTY_NAME_GET(objectclass, objecthandle) \
1593 	(const char*)(& RecorderDataPtr->ObjectPropertyTable.objbytes \
1594 	[uiIndexOfObject(objecthandle, objectclass)])
1595 
1596 #define TRACE_PROPERTY_OBJECT_STATE(objectclass, handle) \
1597 	RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
1598 	+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass]]
1599 
1600 #define TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle) \
1601 	RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
1602 	+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass] + 1]
1603 
1604 /* DEBUG ASSERTS */
1605 #if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0
1606 #define TRACE_ASSERT(eval, msg, defRetVal) \
1607 	if (!(eval)) \
1608 	{ \
1609 		prvTraceError("TRACE_ASSERT: " msg); \
1610 		return defRetVal; \
1611 	}
1612 #else
1613 #define TRACE_ASSERT(eval, msg, defRetVal)
1614 #endif
1615 
1616 typedef RecorderDataType TraceRecorderData_t;
1617 
1618 #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/
1619 
1620 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
1621 
1622 #ifndef TRC_EXTERNAL_BUFFERS
1623 #define TRC_EXTERNAL_BUFFERS 0
1624 #endif
1625 
1626 typedef struct TraceRecorderData	/* Aligned */
1627 {
1628 	uint32_t uiSessionCounter;
1629 	uint32_t uiRecorderEnabled;
1630 	TraceUnsignedBaseType_t uxTraceSystemStates[TRC_CFG_CORE_COUNT];
1631 	uint32_t reserved;								/* alignment */
1632 
1633 	TraceAssertData_t xAssertBuffer;				/* aligned */
1634 	TraceEntryIndexTable_t xEntryIndexTableBuffer;	/* aligned */
1635 #if (TRC_EXTERNAL_BUFFERS == 0)
1636 	TraceHeaderBuffer_t xHeaderBuffer;				/* aligned */
1637 	TraceEntryTable_t xEntryTable;					/* aligned */
1638 	TraceTimestampData_t xTimestampBuffer;			/* aligned */
1639 #endif
1640 	TraceStreamPortBuffer_t xStreamPortBuffer;		/* verify alignment in xTraceInitialize() */
1641 	TraceStaticBufferTable_t xStaticBufferBuffer;	/* aligned */
1642 	TraceEventDataTable_t xEventDataBuffer;			/* verify alignment in xTraceInitialize() */
1643 	TracePrintData_t xPrintBuffer;					/* aligned */
1644 	TraceErrorData_t xErrorBuffer;					/* aligned */
1645 	TraceISRData_t xISRBuffer;						/* aligned */
1646 	TraceKernelPortDataBuffer_t xKernelPortBuffer;	/* verify alignment in xTraceInitialize() */
1647 	TraceTaskData_t xTaskInfoBuffer;				/* aligned */
1648 	TraceStackMonitorData_t xStackMonitorBuffer;	/* aligned */
1649 	TraceDiagnosticsData_t xDiagnosticsBuffer;		/* aligned */
1650 	TraceExtensionData_t xExtensionBuffer;			/* aligned */
1651 	TraceCounterData_t xCounterBuffer;				/* aligned */
1652 } TraceRecorderData_t;
1653 
1654 extern TraceRecorderData_t* pxTraceRecorderData;
1655 extern uint32_t RecorderInitialized;
1656 
1657 /**
1658  * @brief Initializes the header data
1659  *
1660  * @param[in] pxBuffer Pointer to header buffer
1661  *
1662  * @retval TRC_FAIL Failure
1663  * @retval TRC_SUCCESS Success
1664  */
1665 traceResult xTraceHeaderInitialize(TraceHeaderBuffer_t* pxBuffer);
1666 
1667 /**
1668  * @brief Query if recorder is enabled
1669  *
1670  * @retval Non-zero Recorder enabled
1671  * @retval 0 Recorder not enabled
1672  */
1673 #define xTraceIsRecorderEnabled() (xTraceIsRecorderInitialized() && pxTraceRecorderData->uiRecorderEnabled)
1674 
1675 /**
1676  * @brief Query if recorder initialized
1677  *
1678  * @retval Non-zero Recorder initialized
1679  * @retval 0 Recorder not initialized
1680  */
1681 #define xTraceIsRecorderInitialized() xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_CORE)
1682 
1683 /**
1684  * @brief Flag component as initialized
1685  *
1686  * @param[in] uiComponentBit Component bit
1687  *
1688  * @retval TRC_FAIL Failure
1689  * @retval TRC_SUCCESS Success
1690  */
1691 #define xTraceSetComponentInitialized(uiComponentBit) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(RecorderInitialized |= (uiComponentBit), TRC_SUCCESS)
1692 
1693 /**
1694  * @brief Query if component is initialized
1695  *
1696  * @param[in] uiComponentBit Component bit
1697  *
1698  * @retval Non-zero Component initialized
1699  * @retval 0 Component not initialized
1700  */
1701 #define xTraceIsComponentInitialized(uiComponentBit) (RecorderInitialized & (uiComponentBit))
1702 
1703 /**
1704  * @brief Set the trace state
1705  *
1706  * @param[in] uiState State
1707  *
1708  * @retval TRC_FAIL Failure
1709  * @retval TRC_SUCCESS Success
1710  */
1711 #define xTraceStateSet(uxState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceRecorderData->uxTraceSystemStates[TRC_CFG_GET_CURRENT_CORE()] = (uxState), TRC_SUCCESS)
1712 
1713 /**
1714  * @brief Query the trace state
1715  *
1716  * @param[out] puiState State
1717  *
1718  * @retval TRC_FAIL Failure
1719  * @retval TRC_SUCCESS Success
1720  */
1721 #define xTraceStateGet(puxState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puxState) = pxTraceRecorderData->uxTraceSystemStates[TRC_CFG_GET_CURRENT_CORE()], TRC_SUCCESS)
1722 
1723 /**
1724  * @brief Call this function periodically
1725  *
1726  * @retval TRC_FAIL Failure
1727  * @retval TRC_SUCCESS Success
1728  */
1729 traceResult xTraceTzCtrl(void);
1730 
1731 /******************************************************************************/
1732 /*** INTERNAL STREAMING FUNCTIONS *********************************************/
1733 /******************************************************************************/
1734 
1735 /**
1736  * @brief Stores an event without parameters
1737  *
1738  * @param[in] _eventID Event id
1739  */
1740 #define prvTraceStoreEvent_None(_eventID) xTraceEventCreate0(_eventID)
1741 
1742 /**
1743  * @brief Stores an event with a handle parameter
1744  *
1745  * @param[in] _eventID Event id
1746  * @param[in] _handle Handle
1747  */
1748 #define prvTraceStoreEvent_Handle(_eventID, _handle) xTraceEventCreate1(_eventID, (TraceUnsignedBaseType_t)(_handle))
1749 
1750 /**
1751  * @brief Stores an event with one parameter
1752  *
1753  * @param[in] _eventID Event id
1754  * @param[in] _param1 Param
1755  */
1756 #define prvTraceStoreEvent_Param(_eventID, _param1)  xTraceEventCreate1(_eventID, (TraceUnsignedBaseType_t)(_param1))
1757 
1758 /**
1759  * @brief Stores an event with a handle and one parameter
1760  *
1761  * @param[in] _eventID Event id
1762  * @param[in] _handle Handle
1763  * @param[in] _param1 Param
1764  */
1765 #define prvTraceStoreEvent_HandleParam(_eventID, _handle, _param1) xTraceEventCreate2(_eventID, (TraceUnsignedBaseType_t)(_handle), (TraceUnsignedBaseType_t)(_param1))
1766 
1767 /**
1768  * @brief Stores an event with two parameters
1769  *
1770  * @param[in] _eventID Event id
1771  * @param[in] _param1 Param 1
1772  * @param[in] _param2 Param 2
1773  */
1774 #define prvTraceStoreEvent_ParamParam(_eventID, _param1, _param2) xTraceEventCreate2(_eventID, (TraceUnsignedBaseType_t)(_param1), (TraceUnsignedBaseType_t)(_param2))
1775 
1776 /**
1777  * @brief Stores an event with a handle and two parameters
1778  *
1779  * @param[in] _eventID Event id
1780  * @param[in] _handle Handle
1781  * @param[in] _param1 Param 1
1782  * @param[in] _param2 Param 2
1783  */
1784 #define prvTraceStoreEvent_HandleParamParam(_eventID, _handle, _param1, _param2) xTraceEventCreate3(_eventID, (TraceUnsignedBaseType_t)(_handle), (TraceUnsignedBaseType_t)(_param1), (TraceUnsignedBaseType_t)(_param2))
1785 
1786 /**
1787  * @brief Stores an event with three parameters
1788  *
1789  * @param[in] _eventID Event id
1790  * @param[in] _param1 Param 1
1791  * @param[in] _param2 Param 2
1792  * @param[in] _param3 Param 3
1793  */
1794 #define prvTraceStoreEvent_ParamParamParam(_eventID, _param1, _param2, _param3) xTraceEventCreate3(_eventID, (TraceUnsignedBaseType_t)(_param1), (TraceUnsignedBaseType_t)(_param2), (TraceUnsignedBaseType_t)(_param3))
1795 
1796 /**
1797  * @brief Snapshot mode only. Trace stop hook.
1798  *
1799  * @param[in] x
1800  */
1801 #define vTraceSetStopHook(x) (void)(x)
1802 
1803 /**
1804  * @brief Snapshot mode only. Initialize timestamps.
1805  */
1806 #define vTraceInitTimestamps()
1807 
1808 #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
1809 
1810 #if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
1811 /**
1812  * @brief Set the recorder data buffer
1813  *
1814  * @param[in] pxBuffer Pointer to the recorder data buffer
1815  *
1816  * @retval TRC_FAIL Failure
1817  * @retval TRC_SUCCESS Success
1818  */
1819 traceResult xTraceSetBuffer(TraceRecorderData_t *pxBuffer);
1820 #else
1821 #define xTraceSetBuffer(p) (TRC_SUCCESS)
1822 #endif
1823 
1824 /**
1825  * @brief Retrieve the event buffer and event buffer size
1826  *
1827  * @param[out] ppvBuffer Pointer where event buffer pointer will be written
1828  * @param[out] puiSize Event buffer size
1829  *
1830  * @retval TRC_FAIL Failure
1831  * @retval TRC_SUCCESS Success
1832  */
1833 traceResult xTraceGetEventBuffer(void** ppvBuffer, TraceUnsignedBaseType_t * puiSize);
1834 
1835 #else /* when TRC_USE_TRACEALYZER_RECORDER == 0 */
1836 
1837 #define xTraceInitialize() (TRC_SUCCESS)
1838 #define xTraceEnable(x) ((void)(x), TRC_SUCCESS)
1839 #define xTraceDisable() (TRC_SUCCESS)
1840 
1841 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
1842 #define xTraceStringRegister(x, y) ((void)(x), (void)y, TRC_SUCCESS) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
1843 #define xTracePrint(chn, ...) ((void)(chn), TRC_SUCCESS)
1844 #define xTracePrintF(chn, fmt, ...) ((void)(chn), (void)(fmt), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
1845 #define xTraceVPrintF(chn, formatStr, vl) ((void)(chn), (void)(formatStr), (void)(vl), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
1846 #define xTraceTaskInstanceFinishedNow()
1847 #define xTraceTaskInstanceFinishedNext()
1848 #define vTraceStoreISRBegin(x) (void)(x)
1849 #define vTraceStoreISREnd(x) (void)(x)
1850 #define xTraceSetISRProperties(a, b) ((void)(a), (void)(b), (traceHandle)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
1851 #define xTraceRegisterChannelFormat(eventLabel, formatStr) ((void)(eventLabel), (void)(formatStr), 0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
1852 #define vTraceUBData(label, ...) (void)(label)
1853 #endif
1854 
1855 #define prvTraceStoreEvent_None(_eventID) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(_eventID), TRC_SUCCESS)
1856 
1857 #define prvTraceStoreEvent_Handle(_eventID, _handle) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_eventID), (void)(_handle), TRC_SUCCESS)
1858 
1859 #define prvTraceStoreEvent_Param(_eventID, _param1)  TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_eventID), (void)(_param1), TRC_SUCCESS)
1860 
1861 #define prvTraceStoreEvent_HandleParam(_eventID, _handle, _param1) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(_eventID), (void)(_handle), (void)(_param1), TRC_SUCCESS)
1862 
1863 #define prvTraceStoreEvent_ParamParam(_eventID, _param1, _param2) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(_eventID), (void)(_param1), (void)(_param2), TRC_SUCCESS)
1864 
1865 #define prvTraceStoreEvent_HandleParamParam(_eventID, _handle, _param1, _param2) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5((void)(_eventID), (void)(_handle), (void)(_param1), (void)(_param2), TRC_SUCCESS)
1866 
1867 #define prvTraceStoreEvent_ParamParamParam(_eventID, _param1, _param2, _param3) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5((void)(_eventID), (void)(_param1), (void)(_param2), (void)(_param3), TRC_SUCCESS)
1868 
1869 #define vTraceSetFilterGroup(x) (void)(x)
1870 #define vTraceSetFilterMask(x) (void)(x)
1871 
1872 #define prvTraceSetReadyEventsEnabled(status) (void)(status)
1873 
1874 #define vTraceExcludeTask(handle) (void)(handle)
1875 
1876 #define vTraceConsoleChannelPrintF(fmt, ...) (void)(fmt)
1877 
1878 #ifndef TRC_ALLOC_CUSTOM_BUFFER
1879 #define TRC_ALLOC_CUSTOM_BUFFER(bufname)
1880 #endif
1881 
1882 #define xTraceIsRecorderEnabled() (0)
1883 #define xTraceIsRecorderInitialized() (0)
1884 
1885 #define xTraceSetBuffer(p) (TRC_SUCCESS)
1886 #define xTraceGetEventBuffer(p) (TRC_FAIL)
1887 
1888 #define vTraceSetStopHook(x) (void)(x)
1889 
1890 #define TraceRecorderData_t uint32_t
1891 
1892 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
1893 
1894 /**
1895  * @deprecated Backwards compatibility. Use xTraceInitialize instead.
1896  */
1897 #define vTraceInitialize (void)xTraceInitialize
1898 
1899 /**
1900  * @deprecated Backwards compatibility. Use xTraceEnable instead.
1901  */
1902 #define vTraceEnable (void)xTraceEnable
1903 
1904 /**
1905  * @deprecated Backwards compatibility. Use xTraceDisable instead.
1906  */
1907 #define vTraceStop (void)xTraceDisable
1908 
1909 /**
1910  * @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNow instead.
1911  */
1912 #define vTraceInstanceFinishedNow (void)xTraceTaskInstanceFinishedNow
1913 
1914 /**
1915  * @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNext instead.
1916  */
1917 #define vTraceInstanceFinishedNext (void)xTraceTaskInstanceFinishedNext
1918 
1919 /**
1920  * @deprecated Backwards compatibility. Use xTracePrintF instead.
1921  */
1922 #define vTracePrintF (void)xTracePrintF
1923 
1924 /**
1925  * @deprecated Backwards compatibility. Use xTraceVPrintF instead.
1926  */
1927 #define vTraceVPrintF (void)xTraceVPrintF
1928 
1929 /**
1930  * @deprecated Backwards compatibility. Use xTracePrint instead.
1931  */
1932 #define vTracePrint (void)xTracePrint
1933 
1934 /**
1935  * @deprecated Backwards compatibility. Use xTraceSetBuffer instead.
1936  */
1937 #define vTraceSetRecorderDataBuffer(pxBuffer) xTraceSetBuffer((TraceRecorderData_t*)(pxBuffer))
1938 
1939 #ifdef __cplusplus
1940 }
1941 #endif
1942 
1943 #endif /* TRC_RECORDER_H */
1944