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