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