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