1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.9.2
3 * Copyright 2023 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 
9 /**
10  * @file
11  *
12  * @brief Public trace print APIs.
13  */
14 
15 #ifndef TRC_PRINT_H
16 #define TRC_PRINT_H
17 
18 #if (TRC_USE_TRACEALYZER_RECORDER == 1) && (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
19 
20 #include <stdarg.h>
21 #include <trcTypes.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /**
28  * @defgroup trace_print_apis Trace Print APIs
29  * @ingroup trace_recorder_apis
30  * @{
31  */
32 
33 typedef struct TracePrintData	/* Aligned */
34 {
35 	TraceStringHandle_t defaultChannel;
36 	TraceStringHandle_t consoleChannel;
37 } TracePrintData_t;
38 
39 /**
40  * @internal Initialize print trace system.
41  *
42  * @param[in] pxBuffer Pointer to memory that will be used by the print
43  * trace system.
44  *
45  * @retval TRC_FAIL Failure
46  * @retval TRC_SUCCESS Success
47  */
48 traceResult xTracePrintInitialize(TracePrintData_t* pxBuffer);
49 
50 /**
51  * @brief Generate a "User Event". Channel and format string are only stored in ELF.
52  *
53  * This is a compact version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
54  * NOTE! All parameters must be cast to TraceUnsignedBaseType_t/TraceBaseType_t!
55  *
56  * Example:
57  *	xTracePrintCompact("MyChannel", "MyFormat %d", 1);
58  *
59  * @param[in] szChannel Channel string.
60  * @param[in] szFormat Format string.
61  *
62  * @retval TRC_FAIL Failure
63  * @retval TRC_SUCCESS Success
64  */
65 traceResult xTracePrintCompactF(const char* szChannel, const char* szFormat, ...);
66 
67 /**
68  * @brief Generate a "User Event" with 0 parameters. Channel and format string are only stored in ELF.
69  *
70  * This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
71  *
72  * Example:
73  *	xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
74  *	...
75  *	xTracePrintCompactF0("MyChannel", "MyText");
76  *
77  * @param[in] szChannel Channel string.
78  * @param[in] szFormat Format string.
79  *
80  * @retval TRC_FAIL Failure
81  * @retval TRC_SUCCESS Success
82  */
83 #define xTracePrintCompactF0(szChannel, szFormat) xTraceEventCreate2(PSF_EVENT_USER_EVENT_FIXED, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat))
84 
85 /**
86  * @brief Generate a "User Event" with 1 parameter. Channel and format string are only stored in ELF.
87  *
88  * This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
89  *
90  * Example:
91  *	xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
92  *	...
93  *	xTracePrintCompactF1("MyChannel", "MyFormat %u", 1);
94  *
95  * @param[in] szChannel Channel string.
96  * @param[in] szFormat Format string.
97  * @param[in] uxParam1 First parameter.
98  *
99  * @retval TRC_FAIL Failure
100  * @retval TRC_SUCCESS Success
101  */
102 #define xTracePrintCompactF1(szChannel, szFormat, uxParam1) xTraceEventCreate3(PSF_EVENT_USER_EVENT_FIXED + 1, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1)
103 
104 /**
105  * @brief Generate a "User Event" with 2 parameters. Channel and format string are only stored in ELF.
106  *
107  * This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
108  *
109  * Example
110  *	xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
111  *	...
112  *	xTracePrintCompactF2("MyChannel", "MyFormat %u %u", 1, 2);
113  *
114  * @param[in] szChannel Channel string.
115  * @param[in] szFormat Format string.
116  * @param[in] uxParam1 First parameter.
117  * @param[in] uxParam2 Second parameter.
118  *
119  * @retval TRC_FAIL Failure
120  * @retval TRC_SUCCESS Success
121  */
122 #define xTracePrintCompactF2(szChannel, szFormat, uxParam1, uxParam2) xTraceEventCreate4(PSF_EVENT_USER_EVENT_FIXED + 2, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1, uxParam2)
123 
124 /**
125  * @brief Generate a "User Event" with 3 parameters. Channel and format string are only stored in ELF.
126  *
127  * This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
128  *
129  * Example:
130  *	xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
131  *	...
132  *	xTracePrintCompactF3("MyChannel", "MyFormat %u %u %u", 1, 2, 3);
133  *
134  * @param[in] szChannel Channel string.
135  * @param[in] szFormat Format string.
136  * @param[in] uxParam1 First parameter.
137  * @param[in] uxParam2 Second parameter.
138  * @param[in] uxParam3 Third parameter.
139  *
140  * @retval TRC_FAIL Failure
141  * @retval TRC_SUCCESS Success
142  */
143 #define xTracePrintCompactF3(szChannel, szFormat, uxParam1, uxParam2, uxParam3) xTraceEventCreate5(PSF_EVENT_USER_EVENT_FIXED + 3, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1, uxParam2, uxParam3)
144 
145 /**
146  * @brief Generate a "User Event" with 4 parameters. Channel and format string are only stored in ELF.
147  *
148  * This is a compact and fixed version of xTracePrintF(). Only addresses to channel and format strings are stored and an ELF file must be provided to interpret the trace.
149  *
150  * Example:
151  *	xTraceDependencyRegister("my_project.elf", TRC_DEPENDENCY_TYPE_ELF);
152  *	...
153  *	xTracePrintCompactF4("MyChannel", "MyFormat %u %u %u %u", 1, 2, 3, 4);
154  *
155  * @param[in] szChannel Channel string.
156  * @param[in] szFormat Format string.
157  * @param[in] uxParam1 First parameter.
158  * @param[in] uxParam2 Second parameter.
159  * @param[in] uxParam3 Third parameter.
160  * @param[in] uxParam4 Fourth parameter.
161  *
162  * @retval TRC_FAIL Failure
163  * @retval TRC_SUCCESS Success
164  */
165 #define xTracePrintCompactF4(szChannel, szFormat, uxParam1, uxParam2, uxParam3, uxParam4) xTraceEventCreate6(PSF_EVENT_USER_EVENT_FIXED + 4, (TraceUnsignedBaseType_t)(szChannel), (TraceUnsignedBaseType_t)(szFormat), uxParam1, uxParam2, uxParam3, uxParam4)
166 
167 /**
168  * @brief Generate a "User Event" with 0 parameters.
169  *
170  * This is a highly optimized version of xTracePrintF().
171  * The channel and format string must be registered using xTraceStringRegister().
172  *
173  * Example:
174  * 	TraceStringHandle_t xChannel;
175  * 	TraceStringHandle_t xHelloWorld;
176  *
177  *	xTraceStringRegister("MyChannel", &xChannel);
178  *	xTraceStringRegister("Hello world!", &xHelloWorld);
179  *	...
180  *	xTracePrintFormat0(xChannel, xHelloWorld);
181  *
182  * @param[in] xChannel Channel handle.
183  * @param[in] xFormatStringHandle Format string handle.
184  *
185  * @retval TRC_FAIL Failure
186  * @retval TRC_SUCCESS Success
187  */
188 #define xTracePrintF0(xChannelStringHandle, xFormatStringHandle) xTraceEventCreate2(PSF_EVENT_USER_EVENT_FIXED, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle))
189 
190 /**
191  * @brief Generate a "User Event" with 1 parameter.
192  *
193  * This is a highly optimized version of xTracePrintF().
194  * The channel and format string must be registered using xTraceStringRegister().
195  *
196  * Example:
197  * 	TraceStringHandle_t xChannel;
198  * 	TraceStringHandle_t xHelloWorld;
199  *
200  *	xTraceStringRegister("MyChannel", &xChannel);
201  *	xTraceStringRegister("Hello world! %d", &xHelloWorld);
202  *	...
203  *	xTracePrintFormat1(xChannel, xHelloWorld, 1);
204  *
205  * @param[in] xChannel Channel handle.
206  * @param[in] xFormatStringHandle Format string handle.
207  * @param[in] uxParam1 First parameter.
208  *
209  * @retval TRC_FAIL Failure
210  * @retval TRC_SUCCESS Success
211  */
212 #define xTracePrintF1(xChannelStringHandle, xFormatStringHandle, uxParam1) xTraceEventCreate3(PSF_EVENT_USER_EVENT_FIXED + 1, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1)
213 
214 /**
215  * @brief Generate a "User Event" with 2 parameters.
216  *
217  * This is a highly optimized version of xTracePrintF().
218  * The channel and format string must be registered using xTraceStringRegister().
219  *
220  * Example:
221  * 	TraceStringHandle_t xChannel;
222  * 	TraceStringHandle_t xHelloWorld;
223  *
224  *	xTraceStringRegister("MyChannel", &xChannel);
225  *	xTraceStringRegister("Hello world! %d %d", &xHelloWorld);
226  *	...
227  *	xTracePrintFormat2(xChannel, xHelloWorld, 1, 2);
228  *
229  * @param[in] xChannel Channel handle.
230  * @param[in] xFormatStringHandle Format string handle.
231  * @param[in] uxParam1 First parameter.
232  * @param[in] uxParam2 Second parameter.
233  *
234  * @retval TRC_FAIL Failure
235  * @retval TRC_SUCCESS Success
236  */
237 #define xTracePrintF2(xChannelStringHandle, xFormatStringHandle, uxParam1, uxParam2) xTraceEventCreate4(PSF_EVENT_USER_EVENT_FIXED + 2, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1, uxParam2)
238 
239 /**
240  * @brief Generate a "User Event" with 3 parameters.
241  *
242  * This is a highly optimized version of xTracePrintF().
243  * The channel and format string must be registered using xTraceStringRegister().
244  *
245  * Example:
246  * 	TraceStringHandle_t xChannel;
247  * 	TraceStringHandle_t xHelloWorld;
248  *
249  *	xTraceStringRegister("MyChannel", &xChannel);
250  *	xTraceStringRegister("Hello world! %d %d %d", &xHelloWorld);
251  *	...
252  *	xTracePrintFormat3(xChannel, xHelloWorld, 1, 2, 3);
253  *
254  * @param[in] xChannel Channel handle.
255  * @param[in] xFormatStringHandle Format string handle.
256  * @param[in] uxParam1 First parameter.
257  * @param[in] uxParam2 Second parameter.
258  * @param[in] uxParam3 Third parameter.
259  *
260  * @retval TRC_FAIL Failure
261  * @retval TRC_SUCCESS Success
262  */
263 #define xTracePrintF3(xChannelStringHandle, xFormatStringHandle, uxParam1, uxParam2, uxParam3) xTraceEventCreate5(PSF_EVENT_USER_EVENT_FIXED + 3, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1, uxParam2, uxParam3)
264 
265 /**
266  * @brief Generate a "User Event" with 4 parameters.
267  *
268  * This is a highly optimized version of xTracePrintF().
269  * The channel and format string must be registered using xTraceStringRegister().
270  *
271  * Example:
272  * 	TraceStringHandle_t xChannel;
273  * 	TraceStringHandle_t xHelloWorld;
274  *
275  *	xTraceStringRegister("MyChannel", &xChannel);
276  *	xTraceStringRegister("Hello world! %d %d %d %d", &xHelloWorld);
277  *	...
278  *	xTracePrintFormat4(xChannel, xHelloWorld, 1, 2, 3, 4);
279  *
280  * @param[in] xChannel Channel handle.
281  * @param[in] xFormatStringHandle Format string handle.
282  * @param[in] uxParam1 First parameter.
283  * @param[in] uxParam2 Second parameter.
284  * @param[in] uxParam3 Third parameter.
285  * @param[in] uxParam4 Fourth parameter.
286  *
287  * @retval TRC_FAIL Failure
288  * @retval TRC_SUCCESS Success
289  */
290 #define xTracePrintF4(xChannelStringHandle, xFormatStringHandle, uxParam1, uxParam2, uxParam3, uxParam4) xTraceEventCreate6(PSF_EVENT_USER_EVENT_FIXED + 4, (TraceUnsignedBaseType_t)(xChannelStringHandle), (TraceUnsignedBaseType_t)(xFormatStringHandle), uxParam1, uxParam2, uxParam3, uxParam4)
291 
292 /**
293  * @brief Generate "User Events" with unformatted text.
294  *
295  * User Events can be used for very efficient application logging, and are shown
296  * as yellow labels in the main trace view.
297  *
298  * You may group User Events into User Event Channels. The yellow User Event
299  * labels shows the logged string, preceded by the channel  name within
300  * brackets. For example:
301  *
302  *  "[MyChannel] Hello World!"
303  *
304  * The User Event Channels are shown in the View Filter, which makes it easy to
305  * select what User Events you wish to display. User Event Channels are created
306  * using xTraceStringRegister().
307  *
308  * Example:
309  *
310  *	 TraceStringHandle_t xChannel;
311  *	 xTraceStringRegister("MyChannel", &xChannel);
312  *	 ...
313  *	 xTracePrint(xChannel, "Hello World!");
314  *
315  * @param[in] xChannel Channel.
316  * @param[in] szString String.
317  *
318  * @retval TRC_FAIL Failure
319  * @retval TRC_SUCCESS Success
320  */
321 traceResult xTracePrint(TraceStringHandle_t xChannel, const char* szString);
322 
323 /**
324  * @brief Wrapper for xTracePrintF for printing to default channel.
325  *
326  * Wrapper for vTracePrintF, using the default channel. Can be used as a drop-in
327  * replacement for printf and similar functions, e.g. in a debug logging macro.
328  * NOTE! All parameters must be cast to TraceUnsignedBaseType_t/TraceBaseType_t!
329  *
330  * Example:
331  * 	// Old: #define LogString debug_console_printf
332  *
333  *  // New, log to Tracealyzer instead:
334  *  #define LogString xTraceConsoleChannelPrintF
335  *  ...
336  *  LogString("My value is: %d", myValue);
337  *
338  * @param[in] szFormat Format.
339  * @param[in] ... Parameters.
340  *
341  * @retval TRC_FAIL Failure
342  * @retval TRC_SUCCESS Success
343  */
344 traceResult xTraceConsoleChannelPrintF(const char* szFormat, ...);
345 
346 /**
347  * @brief Generates "User Events" with formatted text and data.
348  *
349  * Generates "User Events", with formatted text and data, similar to a "printf".
350  * It is very fast since the actual formatting is done on the host side when the
351  * trace is displayed.
352  *
353  * User Events can be used for very efficient application logging, and are shown
354  * as yellow labels in the main trace view.
355  * An advantage of User Events is that data can be plotted in the "User Event
356  * Signal Plot" view, visualizing any data you log as User Events, discrete
357  * states or control system signals (e.g. system inputs or outputs).
358  *
359  * You may group User Events into User Event Channels. The yellow User Event
360  * labels show the logged string, preceded by the channel name within brackets.
361  *
362  * Example:
363  *
364  *  "[MyChannel] Hello World!"
365  *
366  * The User Event Channels are shown in the View Filter, which makes it easy to
367  * select what User Events you wish to display. User Event Channels are created
368  * using xTraceStringRegister().
369  *
370  * Example:
371  *
372  *	 TraceStringHandle_t adc_uechannel;
373  *	 xTraceStringRegister("ADC User Events", &adc_uechannel);
374  *	 ...
375  *	 xTracePrintF(adc_uechannel,
376  *				 "ADC channel %d: %d volts",
377  *				 ch, adc_reading);
378  *
379  * NOTE! All data arguments are assumed to be TraceUnsignedBaseType_t/TraceBaseType_t. The following formats are
380  * supported:
381  * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> "  -42"
382  * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> "   42"
383  * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> "  2A"
384  * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> "  2a"
385  * %s - string (currently, this must be an earlier stored symbol name)
386  *
387  * Up to 15 data arguments are allowed, with a total size of maximum 60 byte
388  * including 8 byte for the base event fields and the format string. So with
389  * one data argument, the maximum string length is 48 chars. If this is exceeded
390  * the string is truncated (4 bytes at a time).
391  *
392  * @param[in] xChannel Channel.
393  * @param[in] szFormat Format.
394  * @param[in] ... Parameters.
395  *
396  * @retval TRC_FAIL Failure
397  * @retval TRC_SUCCESS Success
398  */
399 traceResult xTracePrintF(TraceStringHandle_t xChannel, const char* szFormat, ...);
400 
401 /**
402  * @brief Generates "User Events" with formatted text and data.
403  *
404  * @param[in] xChannel Channel.
405  * @param[in] szFormat Format.
406  * @param[in] pxVariableList Pointer to variable list arguments.
407  *
408  * @retval TRC_FAIL Failure
409  * @retval TRC_SUCCESS Success
410  */
411 traceResult xTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, va_list* pxVariableList);
412 
413 /** @} */
414 
415 #ifdef __cplusplus
416 }
417 #endif
418 
419 #else
420 
421 typedef struct TracePrintData
422 {
423 	TraceUnsignedBaseType_t buffer[1];
424 } TracePrintData_t;
425 
426 #define xTracePrintInitialize(__pvBuffer) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(__pvBuffer), TRC_SUCCESS)
427 
428 #define xTracePrint(_c, _s) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_c), (void)(_s), TRC_SUCCESS)
429 
430 #define xTracePrintF(_c, _s, ...) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_c), (void)(_s), TRC_SUCCESS)
431 
432 #define xTraceConsoleChannelPrintF(_s, ...) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(_s), TRC_SUCCESS)
433 
434 #define xTraceVPrintF(_c, _s, _v) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(_c), (void)(_s), (void)(_v), TRC_SUCCESS)
435 
436 #define xTracePrintF0(_c, _f) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)(_c), (void)(_f), TRC_SUCCESS)
437 #define xTracePrintF1(_c, _f, _p1) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)(_c), (void)(_f), (void)(_p1), TRC_SUCCESS)
438 #define xTracePrintF2(_c, _f, _p1, _p2) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5((void)(_c), (void)(_f), (void)(_p1), (void)(_p2), TRC_SUCCESS)
439 #define xTracePrintF3(_c, _f, _p1, _p2, _p3) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_6((void)(_c), (void)(_f), (void)(_p1), (void)(_p2), (void)(_p3), TRC_SUCCESS)
440 #define xTracePrintF4(_c, _f, _p1, _p2, _p3, _p4) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_7((void)(_c), (void)(_f), (void)(_p1), (void)(_p2), (void)(_p3), (void)(_p4), TRC_SUCCESS)
441 
442 #define xTracePrintCompactF xTracePrintF
443 #define xTracePrintCompactF0 xTracePrintF0
444 #define xTracePrintCompactF1 xTracePrintF1
445 #define xTracePrintCompactF2 xTracePrintF2
446 #define xTracePrintCompactF3 xTracePrintF3
447 #define xTracePrintCompactF4 xTracePrintF4
448 
449 #endif
450 
451 #endif
452