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