1 /********************************************************************* 2 * SEGGER Microcontroller GmbH * 3 * The Embedded Experts * 4 ********************************************************************** 5 * * 6 * (c) 1995 - 2021 SEGGER Microcontroller GmbH * 7 * * 8 * www.segger.com Support: support@segger.com * 9 * * 10 ********************************************************************** 11 * * 12 * SEGGER RTT * Real Time Transfer for embedded targets * 13 * * 14 ********************************************************************** 15 * * 16 * All rights reserved. * 17 * * 18 * SEGGER strongly recommends to not make any changes * 19 * to or modify the source code of this software in order to stay * 20 * compatible with the RTT protocol and J-Link. * 21 * * 22 * Redistribution and use in source and binary forms, with or * 23 * without modification, are permitted provided that the following * 24 * condition is met: * 25 * * 26 * o Redistributions of source code must retain the above copyright * 27 * notice, this condition and the following disclaimer. * 28 * * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * 30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * 32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * 33 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * 34 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * 35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * 36 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * 37 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * 38 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * 40 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * 41 * DAMAGE. * 42 * * 43 ********************************************************************** 44 * * 45 * RTT version: 7.22 * 46 * * 47 ********************************************************************** 48 49 ---------------------------END-OF-HEADER------------------------------ 50 File : SEGGER_RTT.h 51 Purpose : Implementation of SEGGER real-time transfer which allows 52 real-time communication on targets which support debugger 53 memory accesses while the CPU is running. 54 Revision: $Rev: 20869 $ 55 ---------------------------------------------------------------------- 56 */ 57 58 #ifndef SEGGER_RTT_H 59 #define SEGGER_RTT_H 60 61 #include "SEGGER_RTT_Conf.h" 62 63 /********************************************************************* 64 * 65 * Defines, defaults 66 * 67 ********************************************************************** 68 */ 69 #ifndef RTT_USE_ASM 70 #if (defined __SES_ARM) // SEGGER Embedded Studio 71 #define _CC_HAS_RTT_ASM_SUPPORT 1 72 #elif (defined __CROSSWORKS_ARM) // Rowley Crossworks 73 #define _CC_HAS_RTT_ASM_SUPPORT 1 74 #elif (defined __ARMCC_VERSION) // ARM compiler 75 #if (__ARMCC_VERSION >= 6000000) // ARM compiler V6.0 and later is clang based 76 #define _CC_HAS_RTT_ASM_SUPPORT 1 77 #else 78 #define _CC_HAS_RTT_ASM_SUPPORT 0 79 #endif 80 #elif (defined __GNUC__) // GCC 81 #define _CC_HAS_RTT_ASM_SUPPORT 1 82 #elif (defined __clang__) // Clang compiler 83 #define _CC_HAS_RTT_ASM_SUPPORT 1 84 #elif ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler 85 #define _CC_HAS_RTT_ASM_SUPPORT 1 86 #else 87 #define _CC_HAS_RTT_ASM_SUPPORT 0 88 #endif 89 #if ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler 90 // 91 // IAR assembler / compiler 92 // 93 #if (__VER__ < 6300000) 94 #define VOLATILE 95 #else 96 #define VOLATILE volatile 97 #endif 98 #if (defined __ARM7M__) // Needed for old versions that do not know the define yet 99 #if (__CORE__ == __ARM7M__) // Cortex-M3 100 #define _CORE_HAS_RTT_ASM_SUPPORT 1 101 #endif 102 #endif 103 #if (defined __ARM7EM__) // Needed for old versions that do not know the define yet 104 #if (__CORE__ == __ARM7EM__) // Cortex-M4/M7 105 #define _CORE_HAS_RTT_ASM_SUPPORT 1 106 #define _CORE_NEEDS_DMB 1 107 #define RTT__DMB() asm VOLATILE("DMB"); 108 #endif 109 #endif 110 #if (defined __ARM8M_BASELINE__) // Needed for old versions that do not know the define yet 111 #if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23 112 #define _CORE_HAS_RTT_ASM_SUPPORT 0 113 #define _CORE_NEEDS_DMB 1 114 #define RTT__DMB() asm VOLATILE("DMB"); 115 #endif 116 #endif 117 #if (defined __ARM8M_MAINLINE__) // Needed for old versions that do not know the define yet 118 #if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33 119 #define _CORE_HAS_RTT_ASM_SUPPORT 1 120 #define _CORE_NEEDS_DMB 1 121 #define RTT__DMB() asm VOLATILE("DMB"); 122 #endif 123 #endif 124 #else 125 // 126 // GCC / Clang 127 // 128 #if (defined __ARM_ARCH_7M__) // Cortex-M3 129 #define _CORE_HAS_RTT_ASM_SUPPORT 1 130 #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 131 #define _CORE_HAS_RTT_ASM_SUPPORT 1 132 #define _CORE_NEEDS_DMB 1 133 #define RTT__DMB() __asm volatile("dmb\n" : : :); 134 #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 135 #define _CORE_HAS_RTT_ASM_SUPPORT 0 136 #define _CORE_NEEDS_DMB 1 137 #define RTT__DMB() __asm volatile("dmb\n" : : :); 138 #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 139 #define _CORE_HAS_RTT_ASM_SUPPORT 1 140 #define _CORE_NEEDS_DMB 1 141 #define RTT__DMB() __asm volatile("dmb\n" : : :); 142 #else 143 #define _CORE_HAS_RTT_ASM_SUPPORT 0 144 #endif 145 #endif 146 // 147 // If IDE and core support the ASM version, enable ASM version by default 148 // 149 #ifndef _CORE_HAS_RTT_ASM_SUPPORT 150 #define _CORE_HAS_RTT_ASM_SUPPORT 0 // Default for unknown cores 151 #endif 152 #if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT) 153 #define RTT_USE_ASM (1) 154 #else 155 #define RTT_USE_ASM (0) 156 #endif 157 #endif 158 159 // 160 // We need to know if a DMB is needed to make sure that on Cortex-M7 etc. 161 // the order of accesses to the ring buffers is guaranteed 162 // Needed for: Cortex-M7, Cortex-M23, Cortex-M33 163 // 164 #ifndef _CORE_NEEDS_DMB 165 #define _CORE_NEEDS_DMB 0 166 #endif 167 168 #ifndef RTT__DMB 169 #if _CORE_NEEDS_DMB 170 #error "Don't know how to place inline assembly for DMB" 171 #else 172 #define RTT__DMB() 173 #endif 174 #endif 175 176 #ifndef SEGGER_RTT_CPU_CACHE_LINE_SIZE 177 #define SEGGER_RTT_CPU_CACHE_LINE_SIZE \ 178 (0) // On most target systems where RTT is used, we do not have a CPU cache, therefore 0 is a good default here 179 #endif 180 181 #ifndef SEGGER_RTT_UNCACHED_OFF 182 #if SEGGER_RTT_CPU_CACHE_LINE_SIZE 183 #error "SEGGER_RTT_UNCACHED_OFF must be defined when setting SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" 184 #else 185 #define SEGGER_RTT_UNCACHED_OFF (0) 186 #endif 187 #endif 188 #if RTT_USE_ASM 189 #if SEGGER_RTT_CPU_CACHE_LINE_SIZE 190 #error "RTT_USE_ASM is not available if SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" 191 #endif 192 #endif 193 194 #ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file 195 #include <stdlib.h> 196 #include <stdarg.h> 197 198 /********************************************************************* 199 * 200 * Defines, fixed 201 * 202 ********************************************************************** 203 */ 204 205 // 206 // Determine how much we must pad the control block to make it a multiple of a cache line in size 207 // Assuming: U8 = 1B 208 // U16 = 2B 209 // U32 = 4B 210 // U8/U16/U32* = 4B 211 // 212 #if SEGGER_RTT_CPU_CACHE_LINE_SIZE // Avoid division by zero in case we do not have any cache 213 #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) \ 214 (((NumBytes + SEGGER_RTT_CPU_CACHE_LINE_SIZE - 1) / SEGGER_RTT_CPU_CACHE_LINE_SIZE) * \ 215 SEGGER_RTT_CPU_CACHE_LINE_SIZE) 216 #else 217 #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (NumBytes) 218 #endif 219 #define SEGGER_RTT__CB_SIZE (16 + 4 + 4 + (SEGGER_RTT_MAX_NUM_UP_BUFFERS * 24) + (SEGGER_RTT_MAX_NUM_DOWN_BUFFERS * 24)) 220 #define SEGGER_RTT__CB_PADDING (SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(SEGGER_RTT__CB_SIZE) - SEGGER_RTT__CB_SIZE) 221 222 /********************************************************************* 223 * 224 * Types 225 * 226 ********************************************************************** 227 */ 228 229 // 230 // Description for a circular buffer (also called "ring buffer") 231 // which is used as up-buffer (T->H) 232 // 233 typedef struct 234 { 235 const char *sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" 236 char *pBuffer; // Pointer to start of buffer 237 unsigned 238 SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the 239 // buffer in order to avoid the problem of being unable to distinguish between full and empty. 240 unsigned WrOff; // Position of next item to be written by either target. 241 volatile unsigned 242 RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. 243 unsigned Flags; // Contains configuration flags 244 } SEGGER_RTT_BUFFER_UP; 245 246 // 247 // Description for a circular buffer (also called "ring buffer") 248 // which is used as down-buffer (H->T) 249 // 250 typedef struct 251 { 252 const char *sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" 253 char *pBuffer; // Pointer to start of buffer 254 unsigned 255 SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the 256 // buffer in order to avoid the problem of being unable to distinguish between full and empty. 257 volatile unsigned 258 WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. 259 unsigned RdOff; // Position of next item to be read by target (down-buffer). 260 unsigned Flags; // Contains configuration flags 261 } SEGGER_RTT_BUFFER_DOWN; 262 263 // 264 // RTT control block which describes the number of buffers available 265 // as well as the configuration for each buffer 266 // 267 // 268 typedef struct 269 { 270 char acID[16]; // Initialized to "SEGGER RTT" 271 int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) 272 int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) 273 SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via 274 // debug probe to host 275 SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from 276 // host via debug probe to target 277 #if SEGGER_RTT__CB_PADDING 278 unsigned char aDummy[SEGGER_RTT__CB_PADDING]; 279 #endif 280 } SEGGER_RTT_CB; 281 282 /********************************************************************* 283 * 284 * Global data 285 * 286 ********************************************************************** 287 */ 288 extern SEGGER_RTT_CB _SEGGER_RTT; 289 290 /********************************************************************* 291 * 292 * RTT API functions 293 * 294 ********************************************************************** 295 */ 296 #ifdef __cplusplus 297 extern "C" { 298 #endif 299 int SEGGER_RTT_AllocDownBuffer(const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags); 300 int SEGGER_RTT_AllocUpBuffer(const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags); 301 int SEGGER_RTT_ConfigUpBuffer( 302 unsigned BufferIndex, const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags); 303 int SEGGER_RTT_ConfigDownBuffer( 304 unsigned BufferIndex, const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags); 305 int SEGGER_RTT_GetKey(void); 306 unsigned SEGGER_RTT_HasData(unsigned BufferIndex); 307 int SEGGER_RTT_HasKey(void); 308 unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex); 309 void SEGGER_RTT_Init(void); 310 unsigned SEGGER_RTT_Read(unsigned BufferIndex, void *pBuffer, unsigned BufferSize); 311 unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void *pData, unsigned BufferSize); 312 int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char *sName); 313 int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char *sName); 314 int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags); 315 int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags); 316 int SEGGER_RTT_WaitKey(void); 317 unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes); 318 unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes); 319 unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes); 320 unsigned SEGGER_RTT_ASM_WriteSkipNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes); 321 unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char *s); 322 void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes); 323 unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c); 324 unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c); 325 unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c); 326 unsigned SEGGER_RTT_GetAvailWriteSpace(unsigned BufferIndex); 327 unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex); 328 // 329 // Function macro for performance optimization 330 // 331 #define SEGGER_RTT_HASDATA(n) \ 332 (((SEGGER_RTT_BUFFER_DOWN *)((char *)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - \ 333 ((SEGGER_RTT_BUFFER_DOWN *)((char *)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) 334 335 #if RTT_USE_ASM 336 #define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock 337 #endif 338 339 /********************************************************************* 340 * 341 * RTT transfer functions to send RTT data via other channels. 342 * 343 ********************************************************************** 344 */ 345 unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void *pBuffer, unsigned BufferSize); 346 unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void *pData, unsigned BufferSize); 347 unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes); 348 unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes); 349 350 #define SEGGER_RTT_HASDATA_UP(n) \ 351 (((SEGGER_RTT_BUFFER_UP *)((char *)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - \ 352 ((SEGGER_RTT_BUFFER_UP *)((char *)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF)) \ 353 ->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into 354 // HW directly 355 356 /********************************************************************* 357 * 358 * RTT "Terminal" API functions 359 * 360 ********************************************************************** 361 */ 362 int SEGGER_RTT_SetTerminal(unsigned char TerminalId); 363 int SEGGER_RTT_TerminalOut(unsigned char TerminalId, const char *s); 364 365 /********************************************************************* 366 * 367 * RTT printf functions (require SEGGER_RTT_printf.c) 368 * 369 ********************************************************************** 370 */ 371 int SEGGER_RTT_printf(unsigned BufferIndex, const char *sFormat, ...); 372 int SEGGER_RTT_vprintf(unsigned BufferIndex, const char *sFormat, va_list *pParamList); 373 374 #ifdef __cplusplus 375 } 376 #endif 377 378 #endif // ifndef(SEGGER_RTT_ASM) 379 380 /********************************************************************* 381 * 382 * Defines 383 * 384 ********************************************************************** 385 */ 386 387 // 388 // Operating modes. Define behavior if buffer is full (not enough space for entire message) 389 // 390 #define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0) // Skip. Do not block, output nothing. (Default) 391 #define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1) // Trim: Do not block, output as much as fits. 392 #define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2) // Block: Wait until there is space in the buffer. 393 #define SEGGER_RTT_MODE_MASK (3) 394 395 // 396 // Control sequences, based on ANSI. 397 // Can be used to control color, and clear the screen 398 // 399 #define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors 400 #define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left 401 402 #define RTT_CTRL_TEXT_BLACK "\x1B[2;30m" 403 #define RTT_CTRL_TEXT_RED "\x1B[2;31m" 404 #define RTT_CTRL_TEXT_GREEN "\x1B[2;32m" 405 #define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m" 406 #define RTT_CTRL_TEXT_BLUE "\x1B[2;34m" 407 #define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m" 408 #define RTT_CTRL_TEXT_CYAN "\x1B[2;36m" 409 #define RTT_CTRL_TEXT_WHITE "\x1B[2;37m" 410 411 #define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m" 412 #define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m" 413 #define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m" 414 #define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m" 415 #define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m" 416 #define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m" 417 #define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m" 418 #define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m" 419 420 #define RTT_CTRL_BG_BLACK "\x1B[24;40m" 421 #define RTT_CTRL_BG_RED "\x1B[24;41m" 422 #define RTT_CTRL_BG_GREEN "\x1B[24;42m" 423 #define RTT_CTRL_BG_YELLOW "\x1B[24;43m" 424 #define RTT_CTRL_BG_BLUE "\x1B[24;44m" 425 #define RTT_CTRL_BG_MAGENTA "\x1B[24;45m" 426 #define RTT_CTRL_BG_CYAN "\x1B[24;46m" 427 #define RTT_CTRL_BG_WHITE "\x1B[24;47m" 428 429 #define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m" 430 #define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m" 431 #define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m" 432 #define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m" 433 #define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m" 434 #define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m" 435 #define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m" 436 #define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m" 437 438 #endif 439 440 /*************************** End of file ****************************/ 441