1 /* 2 * Trace Recorder for Tracealyzer v4.9.2 3 * Copyright 2023 Percepio AB 4 * www.percepio.com 5 * 6 * SPDX-License-Identifier: Apache-2.0 7 * 8 * The interface definitions for trace streaming ("stream ports"). 9 * This "stream port" sets up the recorder to use ARM ITM as streaming channel. 10 * 11 * To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus), 12 * see Percepio Application Note PA-021, available at 13 * https://percepio.com/2018/05/04/keil-itm-support/ 14 * 15 * To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet, 16 * see Percepio Application Note PA-023, https://percepio.com/iar 17 * 18 * NOTE: This stream port may block the application in case the ITM port 19 * is not ready for more data (the TPIU FIFO has become full). This is 20 * necessary to avoid data loss, as the TPIU FIFO is often quite small. 21 * 22 * --- Direct vs. Indirect ITM streaming --- 23 * Direct streaming: By default, this stream port writes directly to the ITM 24 * register mode without any RAM buffer. This assumes you have a fast debug 25 * probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking. 26 * In case the ITM blocking appears to disturb your application, make sure your 27 * debugger is configured for maximum performance, as described in the above 28 * Application Nodes. 29 * 30 * Indirect streaming: If direct streaming gives too much overhead, you may 31 * instead try indirect ITM streaming. This is done by enabling the internal 32 * RAM buffer, like below. This reconfigures the recorder to store the events 33 * in the internal RAM buffer instead of writing them directly to the ITM port. 34 * 35 * Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode. 36 * 37 * This increases RAM usage but eliminates peaks in the trace data rate. 38 * Moreover, the ITM writes are then performed in a separate task (TzCtrl). 39 * You find relevant settings (buffer size etc.) in trcStreamingConfig.h. 40 * 41 * See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming 42 * 43 * --- One-way vs. Two-way Communication --- 44 * The ITM port only provides one-way communication, from target to host. 45 * This is sufficient if you start the tracing from the target application, 46 * using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer 47 * recording before you start the target system. 48 * 49 * In case you prefer to interactively start and stop the tracing from the host 50 * computer, you need two-way communication to send commands to the recorder. 51 * This is possible by writing such "start" and "stop" commands to a special 52 * buffer, monitored by the recorder library, using the debugger IDE. 53 * See trcStreamingPort.c and also the example macro for Keil uVision 54 * (Keil-uVision-Tracealyzer-ITM-Exporter.ini). 55 */ 56 57 #ifndef TRC_STREAM_PORT_H 58 #define TRC_STREAM_PORT_H 59 60 #if (TRC_USE_TRACEALYZER_RECORDER == 1) 61 62 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) 63 64 #include <stdint.h> 65 #include <trcTypes.h> 66 #include <trcStreamPortConfig.h> 67 68 #ifdef __cplusplus 69 extern "C" { 70 #endif 71 72 #if (!defined(TRC_CFG_STREAM_PORT_ITM_PORT) || (TRC_CFG_STREAM_PORT_ITM_PORT) < 0) || ((TRC_CFG_STREAM_PORT_ITM_PORT) > 31) 73 #error "Invalid ITM port defined in trcStreamPortConfig.h." 74 #endif 75 76 /* Important for the ITM port - no RAM buffer, direct writes. In most other ports this can be skipped (default is 1) */ 77 #define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER) 78 79 #define TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_WRITE_MODE) 80 81 #define TRC_INTERNAL_EVENT_BUFFER_TRANSFER_MODE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_TRANSFER_MODE) 82 83 #define TRC_INTERNAL_BUFFER_CHUNK_SIZE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_SIZE) 84 85 #define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT) 86 87 #define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT) 88 89 /* Aligned */ 90 #define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) 91 92 typedef struct TraceStreamPortBuffer /* Aligned */ 93 { 94 #if (TRC_USE_INTERNAL_BUFFER == 1) 95 uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE]; 96 #endif 97 uint8_t buffer[sizeof(TraceUnsignedBaseType_t)]; 98 } TraceStreamPortBuffer_t; 99 100 /** 101 * 102 */ 103 traceResult prvTraceItmWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten); 104 105 /** 106 * 107 */ 108 traceResult prvTraceItmRead(void* ptrData, uint32_t uiSize, int32_t* piBytesRead); 109 110 /** 111 * 112 */ 113 traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); 114 115 /** 116 * @brief Allocates data from the stream port. 117 * 118 * @param[in] uiSize Allocation size 119 * @param[out] ppvData Allocation data pointer 120 * 121 * @retval TRC_FAIL Allocate failed 122 * @retval TRC_SUCCESS Success 123 */ 124 #if (TRC_USE_INTERNAL_BUFFER == 1) 125 #if (TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE == TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_COPY) 126 #define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData)) 127 #else 128 #define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceInternalEventBufferAlloc(uiSize, ppvData)) 129 #endif 130 #else 131 #define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData)) 132 #endif 133 134 /** 135 * @brief Commits data to the stream port, depending on the implementation/configuration of the 136 * stream port this data might be directly written to the stream port interface, buffered, or 137 * something else. 138 * 139 * @param[in] pvData Data to commit 140 * @param[in] uiSize Data to commit size 141 * @param[out] piBytesCommitted Bytes committed 142 * 143 * @retval TRC_FAIL Commit failed 144 * @retval TRC_SUCCESS Success 145 */ 146 #if (TRC_USE_INTERNAL_BUFFER == 1) 147 #if (TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE == TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_COPY) 148 #define xTraceStreamPortCommit xTraceInternalEventBufferPush 149 #else 150 #define xTraceStreamPortCommit xTraceInternalEventBufferAllocCommit 151 #endif 152 #else 153 #define xTraceStreamPortCommit xTraceStreamPortWriteData 154 #endif 155 156 /** 157 * @brief Writes data through the stream port interface. 158 * 159 * @param[in] pvData Data to write 160 * @param[in] uiSize Data to write size 161 * @param[out] piBytesWritten Bytes written 162 * 163 * @retval TRC_FAIL Write failed 164 * @retval TRC_SUCCESS Success 165 */ 166 #define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(prvTraceItmWrite(pvData, uiSize, piBytesWritten), TRC_SUCCESS) 167 168 #define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) prvTraceItmRead(pvData, uiSize, piBytesRead) 169 170 #define xTraceStreamPortOnEnable(uiStartOption) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(uiStartOption), TRC_SUCCESS) 171 172 #define xTraceStreamPortOnDisable() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) 173 174 #define xTraceStreamPortOnTraceBegin() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) 175 176 #define xTraceStreamPortOnTraceEnd() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) 177 178 #ifdef __cplusplus 179 } 180 #endif 181 182 #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ 183 184 #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ 185 186 #endif /* TRC_STREAM_PORT_H */ 187