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