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