DIY Logging Volt/Ampmeter
SEGGER_RTT.c
Go to the documentation of this file.
1 /*********************************************************************
2 * SEGGER Microcontroller GmbH *
3 * The Embedded Experts *
4 **********************************************************************
5 * *
6 * (c) 1995 - 2019 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 ---------------------------END-OF-HEADER------------------------------
45 File : SEGGER_RTT.c
46 Purpose : Implementation of SEGGER real-time transfer (RTT) which
47  allows real-time communication on targets which support
48  debugger memory accesses while the CPU is running.
49 Revision: $Rev: 20869 $
50 
51 Additional information:
52  Type "int" is assumed to be 32-bits in size
53  H->T Host to target communication
54  T->H Target to host communication
55 
56  RTT channel 0 is always present and reserved for Terminal usage.
57  Name is fixed to "Terminal"
58 
59  Effective buffer size: SizeOfBuffer - 1
60 
61  WrOff == RdOff: Buffer is empty
62  WrOff == (RdOff - 1): Buffer is full
63  WrOff > RdOff: Free space includes wrap-around
64  WrOff < RdOff: Used space includes wrap-around
65  (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0):
66  Buffer full and wrap-around after next byte
67 
68 
69 ----------------------------------------------------------------------
70 */
71 
72 #include "SEGGER_RTT.h"
73 
74 #include <string.h> // for memcpy
75 
76 /*********************************************************************
77 *
78 * Configuration, default values
79 *
80 **********************************************************************
81 */
82 
83 #if SEGGER_RTT_CPU_CACHE_LINE_SIZE
84  #ifdef SEGGER_RTT_CB_ALIGN
85  #error "Custom SEGGER_RTT_CB_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
86  #endif
87  #ifdef SEGGER_RTT_BUFFER_ALIGN
88  #error "Custom SEGGER_RTT_BUFFER_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
89  #endif
90  #ifdef SEGGER_RTT_PUT_CB_SECTION
91  #error "Custom SEGGER_RTT_PUT_CB_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
92  #endif
93  #ifdef SEGGER_RTT_PUT_BUFFER_SECTION
94  #error "Custom SEGGER_RTT_PUT_BUFFER_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
95  #endif
96  #ifdef SEGGER_RTT_BUFFER_ALIGNMENT
97  #error "Custom SEGGER_RTT_BUFFER_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
98  #endif
99  #ifdef SEGGER_RTT_ALIGNMENT
100  #error "Custom SEGGER_RTT_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
101  #endif
102 #endif
103 
104 #ifndef BUFFER_SIZE_UP
105  #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host
106 #endif
107 
108 #ifndef BUFFER_SIZE_DOWN
109  #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input)
110 #endif
111 
112 #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
113  #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target
114 #endif
115 
116 #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
117  #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target
118 #endif
119 
120 #ifndef SEGGER_RTT_BUFFER_SECTION
121  #if defined(SEGGER_RTT_SECTION)
122  #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
123  #endif
124 #endif
125 
126 #ifndef SEGGER_RTT_ALIGNMENT
127  #define SEGGER_RTT_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE
128 #endif
129 
130 #ifndef SEGGER_RTT_BUFFER_ALIGNMENT
131  #define SEGGER_RTT_BUFFER_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE
132 #endif
133 
134 #ifndef SEGGER_RTT_MODE_DEFAULT
135  #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP
136 #endif
137 
138 #ifndef SEGGER_RTT_LOCK
139  #define SEGGER_RTT_LOCK()
140 #endif
141 
142 #ifndef SEGGER_RTT_UNLOCK
143  #define SEGGER_RTT_UNLOCK()
144 #endif
145 
146 #ifndef STRLEN
147  #define STRLEN(a) strlen((a))
148 #endif
149 
150 #ifndef STRCPY
151  #define STRCPY(pDest, pSrc) strcpy((pDest), (pSrc))
152 #endif
153 
154 #ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP
155  #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0
156 #endif
157 
158 #ifndef SEGGER_RTT_MEMCPY
159  #ifdef MEMCPY
160  #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes))
161  #else
162  #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
163  #endif
164 #endif
165 
166 #ifndef MIN
167  #define MIN(a, b) (((a) < (b)) ? (a) : (b))
168 #endif
169 
170 #ifndef MAX
171  #define MAX(a, b) (((a) > (b)) ? (a) : (b))
172 #endif
173 //
174 // For some environments, NULL may not be defined until certain headers are included
175 //
176 #ifndef NULL
177  #define NULL 0
178 #endif
179 
180 /*********************************************************************
181 *
182 * Defines, fixed
183 *
184 **********************************************************************
185 */
186 #if (defined __ICCARM__) || (defined __ICCRX__)
187  #define RTT_PRAGMA(P) _Pragma(#P)
188 #endif
189 
190 #if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT
191  #if (defined __GNUC__)
192  #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
193  #elif (defined __ICCARM__) || (defined __ICCRX__)
194  #define PRAGMA(A) _Pragma(#A)
195 #define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \
196  Var
197  #elif (defined __CC_ARM)
198  #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
199  #else
200  #error "Alignment not supported for this compiler."
201  #endif
202 #else
203  #define SEGGER_RTT_ALIGN(Var, Alignment) Var
204 #endif
205 
206 #if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION)
207  #if (defined __GNUC__)
208  #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var
209  #elif (defined __ICCARM__) || (defined __ICCRX__)
210 #define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \
211  Var
212  #elif (defined __CC_ARM)
213  #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var
214  #else
215  #error "Section placement not supported for this compiler."
216  #endif
217 #else
218  #define SEGGER_RTT_PUT_SECTION(Var, Section) Var
219 #endif
220 
221 #if SEGGER_RTT_ALIGNMENT
222  #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT)
223 #else
224  #define SEGGER_RTT_CB_ALIGN(Var) Var
225 #endif
226 
227 #if SEGGER_RTT_BUFFER_ALIGNMENT
228  #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT)
229 #else
230  #define SEGGER_RTT_BUFFER_ALIGN(Var) Var
231 #endif
232 
233 
234 #if defined(SEGGER_RTT_SECTION)
235  #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION)
236 #else
237  #define SEGGER_RTT_PUT_CB_SECTION(Var) Var
238 #endif
239 
240 #if defined(SEGGER_RTT_BUFFER_SECTION)
241  #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION)
242 #else
243  #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var
244 #endif
245 
246 /*********************************************************************
247 *
248 * Static const data
249 *
250 **********************************************************************
251 */
252 
253 static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
254 
255 /*********************************************************************
256 *
257 * Static data
258 *
259 **********************************************************************
260 */
261 
262 //
263 // RTT Control Block and allocate buffers for channel 0
264 //
268 
269 static unsigned char _ActiveTerminal;
270 
271 /*********************************************************************
272 *
273 * Static functions
274 *
275 **********************************************************************
276 */
277 
278 /*********************************************************************
279 *
280 * _DoInit()
281 *
282 * Function description
283 * Initializes the control block an buffers.
284 * May only be called via INIT() to avoid overriding settings.
285 *
286 */
287 #define INIT() { \
288  volatile SEGGER_RTT_CB* pRTTCBInit; \
289  pRTTCBInit = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \
290  do { \
291  if (pRTTCBInit->acID[0] == '\0') { \
292  _DoInit(); \
293  } \
294  } while (0); \
295  }
296 
297 static void _DoInit(void) {
298  volatile SEGGER_RTT_CB* p; // Volatile to make sure that compiler cannot change the order of accesses to the control block
299  //
300  // Initialize control block
301  //
302  p = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access control block uncached so that nothing in the cache ever becomes dirty and all changes are visible in HW directly
305  //
306  // Initialize up buffer 0
307  //
308  p->aUp[0].sName = "Terminal";
309  p->aUp[0].pBuffer = _acUpBuffer;
311  p->aUp[0].RdOff = 0u;
312  p->aUp[0].WrOff = 0u;
314  //
315  // Initialize down buffer 0
316  //
317  p->aDown[0].sName = "Terminal";
318  p->aDown[0].pBuffer = _acDownBuffer;
320  p->aDown[0].RdOff = 0u;
321  p->aDown[0].WrOff = 0u;
323  //
324  // Finish initialization of the control block.
325  // Copy Id string in three steps to make sure "SEGGER RTT" is not found
326  // in initializer memory (usually flash) by J-Link
327  //
328  STRCPY((char*)&p->acID[7], "RTT");
329  RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
330  STRCPY((char*)&p->acID[0], "SEGGER");
331  RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
332  p->acID[6] = ' ';
333  RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
334 }
335 
336 /*********************************************************************
337 *
338 * _WriteBlocking()
339 *
340 * Function description
341 * Stores a specified number of characters in SEGGER RTT ring buffer
342 * and updates the associated write pointer which is periodically
343 * read by the host.
344 * The caller is responsible for managing the write chunk sizes as
345 * _WriteBlocking() will block until all data has been posted successfully.
346 *
347 * Parameters
348 * pRing Ring buffer to post to.
349 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
350 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
351 *
352 * Return value
353 * >= 0 - Number of bytes written into buffer.
354 */
355 static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) {
356  unsigned NumBytesToWrite;
357  unsigned NumBytesWritten;
358  unsigned RdOff;
359  unsigned WrOff;
360  volatile char* pDst;
361  //
362  // Write data to buffer and handle wrap-around if necessary
363  //
364  NumBytesWritten = 0u;
365  WrOff = pRing->WrOff;
366  do {
367  RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime
368  if (RdOff > WrOff) {
369  NumBytesToWrite = RdOff - WrOff - 1u;
370  } else {
371  NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u);
372  }
373  NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around
374  NumBytesToWrite = MIN(NumBytesToWrite, NumBytes);
375  pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
376 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
377  NumBytesWritten += NumBytesToWrite;
378  NumBytes -= NumBytesToWrite;
379  WrOff += NumBytesToWrite;
380  while (NumBytesToWrite--) {
381  *pDst++ = *pBuffer++;
382  };
383 #else
384  SEGGER_RTT_MEMCPY((void*)pDst, pBuffer, NumBytesToWrite);
385  NumBytesWritten += NumBytesToWrite;
386  pBuffer += NumBytesToWrite;
387  NumBytes -= NumBytesToWrite;
388  WrOff += NumBytesToWrite;
389 #endif
390  if (WrOff == pRing->SizeOfBuffer) {
391  WrOff = 0u;
392  }
393  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
394  pRing->WrOff = WrOff;
395  } while (NumBytes);
396  return NumBytesWritten;
397 }
398 
399 /*********************************************************************
400 *
401 * _WriteNoCheck()
402 *
403 * Function description
404 * Stores a specified number of characters in SEGGER RTT ring buffer
405 * and updates the associated write pointer which is periodically
406 * read by the host.
407 * It is callers responsibility to make sure data actually fits in buffer.
408 *
409 * Parameters
410 * pRing Ring buffer to post to.
411 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
412 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
413 *
414 * Notes
415 * (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking
416 */
417 static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) {
418  unsigned NumBytesAtOnce;
419  unsigned WrOff;
420  unsigned Rem;
421  volatile char* pDst;
422 
423  WrOff = pRing->WrOff;
424  Rem = pRing->SizeOfBuffer - WrOff;
425  if (Rem > NumBytes) {
426  //
427  // All data fits before wrap around
428  //
429  pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
430 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
431  WrOff += NumBytes;
432  while (NumBytes--) {
433  *pDst++ = *pData++;
434  };
435  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
436  pRing->WrOff = WrOff;
437 #else
438  SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes);
439  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
440  pRing->WrOff = WrOff + NumBytes;
441 #endif
442  } else {
443  //
444  // We reach the end of the buffer, so need to wrap around
445  //
446 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
447  pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
448  NumBytesAtOnce = Rem;
449  while (NumBytesAtOnce--) {
450  *pDst++ = *pData++;
451  };
452  pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF;
453  NumBytesAtOnce = NumBytes - Rem;
454  while (NumBytesAtOnce--) {
455  *pDst++ = *pData++;
456  };
457  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
458  pRing->WrOff = NumBytes - Rem;
459 #else
460  NumBytesAtOnce = Rem;
461  pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
462  SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytesAtOnce);
463  NumBytesAtOnce = NumBytes - Rem;
464  pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF;
465  SEGGER_RTT_MEMCPY((void*)pDst, pData + Rem, NumBytesAtOnce);
466  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
467  pRing->WrOff = NumBytesAtOnce;
468 #endif
469  }
470 }
471 
472 /*********************************************************************
473 *
474 * _PostTerminalSwitch()
475 *
476 * Function description
477 * Switch terminal to the given terminal ID. It is the caller's
478 * responsibility to ensure the terminal ID is correct and there is
479 * enough space in the buffer for this to complete successfully.
480 *
481 * Parameters
482 * pRing Ring buffer to post to.
483 * TerminalId Terminal ID to switch to.
484 */
485 static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) {
486  unsigned char ac[2];
487 
488  ac[0] = 0xFFu;
489  ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit
490  _WriteBlocking(pRing, (const char*)ac, 2u);
491 }
492 
493 /*********************************************************************
494 *
495 * _GetAvailWriteSpace()
496 *
497 * Function description
498 * Returns the number of bytes that can be written to the ring
499 * buffer without blocking.
500 *
501 * Parameters
502 * pRing Ring buffer to check.
503 *
504 * Return value
505 * Number of bytes that are free in the buffer.
506 */
507 static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) {
508  unsigned RdOff;
509  unsigned WrOff;
510  unsigned r;
511  //
512  // Avoid warnings regarding volatile access order. It's not a problem
513  // in this case, but dampen compiler enthusiasm.
514  //
515  RdOff = pRing->RdOff;
516  WrOff = pRing->WrOff;
517  if (RdOff <= WrOff) {
518  r = pRing->SizeOfBuffer - 1u - WrOff + RdOff;
519  } else {
520  r = RdOff - WrOff - 1u;
521  }
522  return r;
523 }
524 
525 /*********************************************************************
526 *
527 * Public code
528 *
529 **********************************************************************
530 */
531 
532 /*********************************************************************
533 *
534 * SEGGER_RTT_ReadUpBufferNoLock()
535 *
536 * Function description
537 * Reads characters from SEGGER real-time-terminal control block
538 * which have been previously stored by the application.
539 * Do not lock against interrupts and multiple access.
540 * Used to do the same operation that J-Link does, to transfer
541 * RTT data via other channels, such as TCP/IP or UART.
542 *
543 * Parameters
544 * BufferIndex Index of Up-buffer to be used.
545 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to.
546 * BufferSize Size of the target application buffer.
547 *
548 * Return value
549 * Number of bytes that have been read.
550 *
551 * Additional information
552 * This function must not be called when J-Link might also do RTT.
553 */
554 unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
555  unsigned NumBytesRem;
556  unsigned NumBytesRead;
557  unsigned RdOff;
558  unsigned WrOff;
559  unsigned char* pBuffer;
560  SEGGER_RTT_BUFFER_UP* pRing;
561  volatile char* pSrc;
562 
563  INIT();
564  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
565  pBuffer = (unsigned char*)pData;
566  RdOff = pRing->RdOff;
567  WrOff = pRing->WrOff;
568  NumBytesRead = 0u;
569  //
570  // Read from current read position to wrap-around of buffer, first
571  //
572  if (RdOff > WrOff) {
573  NumBytesRem = pRing->SizeOfBuffer - RdOff;
574  NumBytesRem = MIN(NumBytesRem, BufferSize);
575  pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
576 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
577  NumBytesRead += NumBytesRem;
578  BufferSize -= NumBytesRem;
579  RdOff += NumBytesRem;
580  while (NumBytesRem--) {
581  *pBuffer++ = *pSrc++;
582  };
583 #else
584  SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
585  NumBytesRead += NumBytesRem;
586  pBuffer += NumBytesRem;
587  BufferSize -= NumBytesRem;
588  RdOff += NumBytesRem;
589 #endif
590  //
591  // Handle wrap-around of buffer
592  //
593  if (RdOff == pRing->SizeOfBuffer) {
594  RdOff = 0u;
595  }
596  }
597  //
598  // Read remaining items of buffer
599  //
600  NumBytesRem = WrOff - RdOff;
601  NumBytesRem = MIN(NumBytesRem, BufferSize);
602  if (NumBytesRem > 0u) {
603  pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
604 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
605  NumBytesRead += NumBytesRem;
606  BufferSize -= NumBytesRem;
607  RdOff += NumBytesRem;
608  while (NumBytesRem--) {
609  *pBuffer++ = *pSrc++;
610  };
611 #else
612  SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
613  NumBytesRead += NumBytesRem;
614  pBuffer += NumBytesRem;
615  BufferSize -= NumBytesRem;
616  RdOff += NumBytesRem;
617 #endif
618  }
619  //
620  // Update read offset of buffer
621  //
622  if (NumBytesRead) {
623  pRing->RdOff = RdOff;
624  }
625  //
626  return NumBytesRead;
627 }
628 
629 /*********************************************************************
630 *
631 * SEGGER_RTT_ReadNoLock()
632 *
633 * Function description
634 * Reads characters from SEGGER real-time-terminal control block
635 * which have been previously stored by the host.
636 * Do not lock against interrupts and multiple access.
637 *
638 * Parameters
639 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
640 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
641 * BufferSize Size of the target application buffer.
642 *
643 * Return value
644 * Number of bytes that have been read.
645 */
646 unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
647  unsigned NumBytesRem;
648  unsigned NumBytesRead;
649  unsigned RdOff;
650  unsigned WrOff;
651  unsigned char* pBuffer;
652  SEGGER_RTT_BUFFER_DOWN* pRing;
653  volatile char* pSrc;
654  //
655  INIT();
656  pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
657  pBuffer = (unsigned char*)pData;
658  RdOff = pRing->RdOff;
659  WrOff = pRing->WrOff;
660  NumBytesRead = 0u;
661  //
662  // Read from current read position to wrap-around of buffer, first
663  //
664  if (RdOff > WrOff) {
665  NumBytesRem = pRing->SizeOfBuffer - RdOff;
666  NumBytesRem = MIN(NumBytesRem, BufferSize);
667  pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
668 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
669  NumBytesRead += NumBytesRem;
670  BufferSize -= NumBytesRem;
671  RdOff += NumBytesRem;
672  while (NumBytesRem--) {
673  *pBuffer++ = *pSrc++;
674  };
675 #else
676  SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
677  NumBytesRead += NumBytesRem;
678  pBuffer += NumBytesRem;
679  BufferSize -= NumBytesRem;
680  RdOff += NumBytesRem;
681 #endif
682  //
683  // Handle wrap-around of buffer
684  //
685  if (RdOff == pRing->SizeOfBuffer) {
686  RdOff = 0u;
687  }
688  }
689  //
690  // Read remaining items of buffer
691  //
692  NumBytesRem = WrOff - RdOff;
693  NumBytesRem = MIN(NumBytesRem, BufferSize);
694  if (NumBytesRem > 0u) {
695  pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
696 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
697  NumBytesRead += NumBytesRem;
698  BufferSize -= NumBytesRem;
699  RdOff += NumBytesRem;
700  while (NumBytesRem--) {
701  *pBuffer++ = *pSrc++;
702  };
703 #else
704  SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
705  NumBytesRead += NumBytesRem;
706  pBuffer += NumBytesRem;
707  BufferSize -= NumBytesRem;
708  RdOff += NumBytesRem;
709 #endif
710  }
711  if (NumBytesRead) {
712  pRing->RdOff = RdOff;
713  }
714  //
715  return NumBytesRead;
716 }
717 
718 /*********************************************************************
719 *
720 * SEGGER_RTT_ReadUpBuffer
721 *
722 * Function description
723 * Reads characters from SEGGER real-time-terminal control block
724 * which have been previously stored by the application.
725 * Used to do the same operation that J-Link does, to transfer
726 * RTT data via other channels, such as TCP/IP or UART.
727 *
728 * Parameters
729 * BufferIndex Index of Up-buffer to be used.
730 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to.
731 * BufferSize Size of the target application buffer.
732 *
733 * Return value
734 * Number of bytes that have been read.
735 *
736 * Additional information
737 * This function must not be called when J-Link might also do RTT.
738 * This function locks against all other RTT operations. I.e. during
739 * the read operation, writing is also locked.
740 * If only one consumer reads from the up buffer,
741 * call sEGGER_RTT_ReadUpBufferNoLock() instead.
742 */
743 unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) {
744  unsigned NumBytesRead;
745 
746  SEGGER_RTT_LOCK();
747  //
748  // Call the non-locking read function
749  //
750  NumBytesRead = SEGGER_RTT_ReadUpBufferNoLock(BufferIndex, pBuffer, BufferSize);
751  //
752  // Finish up.
753  //
755  //
756  return NumBytesRead;
757 }
758 
759 /*********************************************************************
760 *
761 * SEGGER_RTT_Read
762 *
763 * Function description
764 * Reads characters from SEGGER real-time-terminal control block
765 * which have been previously stored by the host.
766 *
767 * Parameters
768 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
769 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
770 * BufferSize Size of the target application buffer.
771 *
772 * Return value
773 * Number of bytes that have been read.
774 */
775 unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) {
776  unsigned NumBytesRead;
777 
778  SEGGER_RTT_LOCK();
779  //
780  // Call the non-locking read function
781  //
782  NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize);
783  //
784  // Finish up.
785  //
787  //
788  return NumBytesRead;
789 }
790 
791 /*********************************************************************
792 *
793 * SEGGER_RTT_WriteWithOverwriteNoLock
794 *
795 * Function description
796 * Stores a specified number of characters in SEGGER RTT
797 * control block.
798 * SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application
799 * and overwrites data if the data does not fit into the buffer.
800 *
801 * Parameters
802 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
803 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
804 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
805 *
806 * Notes
807 * (1) If there is not enough space in the "Up"-buffer, data is overwritten.
808 * (2) For performance reasons this function does not call Init()
809 * and may only be called after RTT has been initialized.
810 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
811 * (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link
812 * connection reads RTT data.
813 */
814 void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
815  const char* pData;
816  SEGGER_RTT_BUFFER_UP* pRing;
817  unsigned Avail;
818  volatile char* pDst;
819  //
820  // Get "to-host" ring buffer and copy some elements into local variables.
821  //
822  pData = (const char *)pBuffer;
823  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
824  //
825  // Check if we will overwrite data and need to adjust the RdOff.
826  //
827  if (pRing->WrOff == pRing->RdOff) {
828  Avail = pRing->SizeOfBuffer - 1u;
829  } else if ( pRing->WrOff < pRing->RdOff) {
830  Avail = pRing->RdOff - pRing->WrOff - 1u;
831  } else {
832  Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer;
833  }
834  if (NumBytes > Avail) {
835  pRing->RdOff += (NumBytes - Avail);
836  while (pRing->RdOff >= pRing->SizeOfBuffer) {
837  pRing->RdOff -= pRing->SizeOfBuffer;
838  }
839  }
840  //
841  // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds
842  //
843  Avail = pRing->SizeOfBuffer - pRing->WrOff;
844  do {
845  if (Avail > NumBytes) {
846  //
847  // Last round
848  //
849  pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
850 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
851  Avail = NumBytes;
852  while (NumBytes--) {
853  *pDst++ = *pData++;
854  };
855  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
856  pRing->WrOff += Avail;
857 #else
858  SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes);
859  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
860  pRing->WrOff += NumBytes;
861 #endif
862  break;
863  } else {
864  //
865  // Wrap-around necessary, write until wrap-around and reset WrOff
866  //
867  pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
868 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
869  NumBytes -= Avail;
870  while (Avail--) {
871  *pDst++ = *pData++;
872  };
873  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
874  pRing->WrOff = 0;
875 #else
876  SEGGER_RTT_MEMCPY((void*)pDst, pData, Avail);
877  pData += Avail;
878  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
879  pRing->WrOff = 0;
880  NumBytes -= Avail;
881 #endif
882  Avail = (pRing->SizeOfBuffer - 1);
883  }
884  } while (NumBytes);
885 }
886 
887 /*********************************************************************
888 *
889 * SEGGER_RTT_WriteSkipNoLock
890 *
891 * Function description
892 * Stores a specified number of characters in SEGGER RTT
893 * control block which is then read by the host.
894 * SEGGER_RTT_WriteSkipNoLock does not lock the application and
895 * skips all data, if the data does not fit into the buffer.
896 *
897 * Parameters
898 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
899 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
900 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
901 * MUST be > 0!!!
902 * This is done for performance reasons, so no initial check has do be done.
903 *
904 * Return value
905 * 1: Data has been copied
906 * 0: No space, data has not been copied
907 *
908 * Notes
909 * (1) If there is not enough space in the "Up"-buffer, all data is dropped.
910 * (2) For performance reasons this function does not call Init()
911 * and may only be called after RTT has been initialized.
912 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
913 */
914 #if (RTT_USE_ASM == 0)
915 unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
916  const char* pData;
917  SEGGER_RTT_BUFFER_UP* pRing;
918  unsigned Avail;
919  unsigned RdOff;
920  unsigned WrOff;
921  unsigned Rem;
922  volatile char* pDst;
923  //
924  // Cases:
925  // 1) RdOff <= WrOff => Space until wrap-around is sufficient
926  // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks)
927  // 3) RdOff < WrOff => No space in buf
928  // 4) RdOff > WrOff => Space is sufficient
929  // 5) RdOff > WrOff => No space in buf
930  //
931  // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough
932  //
933  pData = (const char *)pBuffer;
934  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
935  RdOff = pRing->RdOff;
936  WrOff = pRing->WrOff;
937  if (RdOff <= WrOff) { // Case 1), 2) or 3)
938  Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0)
939  if (Avail >= NumBytes) { // Case 1)?
940 CopyStraight:
941  pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
942  memcpy((void*)pDst, pData, NumBytes);
943  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
944  pRing->WrOff = WrOff + NumBytes;
945  return 1;
946  }
947  Avail += RdOff; // Space incl. wrap-around
948  if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit)
949  Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer
950  pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
951  memcpy((void*)pDst, pData, Rem); // Copy 1st chunk
952  NumBytes -= Rem;
953  //
954  // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used
955  // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element
956  // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks
957  // Therefore, check if 2nd memcpy is necessary at all
958  //
959  if (NumBytes) {
960  pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF;
961  memcpy((void*)pDst, pData + Rem, NumBytes);
962  }
963  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
964  pRing->WrOff = NumBytes;
965  return 1;
966  }
967  } else { // Potential case 4)
968  Avail = RdOff - WrOff - 1u;
969  if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit)
970  goto CopyStraight;
971  }
972  }
973  return 0; // No space in buffer
974 }
975 #endif
976 
977 /*********************************************************************
978 *
979 * SEGGER_RTT_WriteDownBufferNoLock
980 *
981 * Function description
982 * Stores a specified number of characters in SEGGER RTT
983 * control block inside a <Down> buffer.
984 * SEGGER_RTT_WriteDownBufferNoLock does not lock the application.
985 * Used to do the same operation that J-Link does, to transfer
986 * RTT data from other channels, such as TCP/IP or UART.
987 *
988 * Parameters
989 * BufferIndex Index of "Down"-buffer to be used.
990 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
991 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
992 *
993 * Return value
994 * Number of bytes which have been stored in the "Down"-buffer.
995 *
996 * Notes
997 * (1) Data is stored according to buffer flags.
998 * (2) For performance reasons this function does not call Init()
999 * and may only be called after RTT has been initialized.
1000 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
1001 *
1002 * Additional information
1003 * This function must not be called when J-Link might also do RTT.
1004 */
1005 unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
1006  unsigned Status;
1007  unsigned Avail;
1008  const char* pData;
1009  SEGGER_RTT_BUFFER_UP* pRing;
1010  //
1011  // Get "to-target" ring buffer.
1012  // It is save to cast that to a "to-host" buffer. Up and Down buffer differ in volatility of offsets that might be modified by J-Link.
1013  //
1014  pData = (const char *)pBuffer;
1015  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1016  //
1017  // How we output depends upon the mode...
1018  //
1019  switch (pRing->Flags) {
1021  //
1022  // If we are in skip mode and there is no space for the whole
1023  // of this output, don't bother.
1024  //
1025  Avail = _GetAvailWriteSpace(pRing);
1026  if (Avail < NumBytes) {
1027  Status = 0u;
1028  } else {
1029  Status = NumBytes;
1030  _WriteNoCheck(pRing, pData, NumBytes);
1031  }
1032  break;
1034  //
1035  // If we are in trim mode, trim to what we can output without blocking.
1036  //
1037  Avail = _GetAvailWriteSpace(pRing);
1038  Status = Avail < NumBytes ? Avail : NumBytes;
1039  _WriteNoCheck(pRing, pData, Status);
1040  break;
1042  //
1043  // If we are in blocking mode, output everything.
1044  //
1045  Status = _WriteBlocking(pRing, pData, NumBytes);
1046  break;
1047  default:
1048  Status = 0u;
1049  break;
1050  }
1051  //
1052  // Finish up.
1053  //
1054  return Status;
1055 }
1056 
1057 /*********************************************************************
1058 *
1059 * SEGGER_RTT_WriteNoLock
1060 *
1061 * Function description
1062 * Stores a specified number of characters in SEGGER RTT
1063 * control block which is then read by the host.
1064 * SEGGER_RTT_WriteNoLock does not lock the application.
1065 *
1066 * Parameters
1067 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1068 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
1069 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
1070 *
1071 * Return value
1072 * Number of bytes which have been stored in the "Up"-buffer.
1073 *
1074 * Notes
1075 * (1) Data is stored according to buffer flags.
1076 * (2) For performance reasons this function does not call Init()
1077 * and may only be called after RTT has been initialized.
1078 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
1079 */
1080 unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
1081  unsigned Status;
1082  unsigned Avail;
1083  const char* pData;
1084  SEGGER_RTT_BUFFER_UP* pRing;
1085  //
1086  // Get "to-host" ring buffer.
1087  //
1088  pData = (const char *)pBuffer;
1089  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1090  //
1091  // How we output depends upon the mode...
1092  //
1093  switch (pRing->Flags) {
1095  //
1096  // If we are in skip mode and there is no space for the whole
1097  // of this output, don't bother.
1098  //
1099  Avail = _GetAvailWriteSpace(pRing);
1100  if (Avail < NumBytes) {
1101  Status = 0u;
1102  } else {
1103  Status = NumBytes;
1104  _WriteNoCheck(pRing, pData, NumBytes);
1105  }
1106  break;
1108  //
1109  // If we are in trim mode, trim to what we can output without blocking.
1110  //
1111  Avail = _GetAvailWriteSpace(pRing);
1112  Status = Avail < NumBytes ? Avail : NumBytes;
1113  _WriteNoCheck(pRing, pData, Status);
1114  break;
1116  //
1117  // If we are in blocking mode, output everything.
1118  //
1119  Status = _WriteBlocking(pRing, pData, NumBytes);
1120  break;
1121  default:
1122  Status = 0u;
1123  break;
1124  }
1125  //
1126  // Finish up.
1127  //
1128  return Status;
1129 }
1130 
1131 /*********************************************************************
1132 *
1133 * SEGGER_RTT_WriteDownBuffer
1134 *
1135 * Function description
1136 * Stores a specified number of characters in SEGGER RTT control block in a <Down> buffer.
1137 *
1138 * Parameters
1139 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1140 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
1141 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
1142 *
1143 * Return value
1144 * Number of bytes which have been stored in the "Down"-buffer.
1145 *
1146 * Notes
1147 * (1) Data is stored according to buffer flags.
1148 *
1149 * Additional information
1150 * This function must not be called when J-Link might also do RTT.
1151 * This function locks against all other RTT operations. I.e. during
1152 * the write operation, writing from the application is also locked.
1153 * If only one consumer writes to the down buffer,
1154 * call SEGGER_RTT_WriteDownBufferNoLock() instead.
1155 */
1156 unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
1157  unsigned Status;
1158 
1159  INIT();
1160  SEGGER_RTT_LOCK();
1161  Status = SEGGER_RTT_WriteDownBufferNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function
1163  return Status;
1164 }
1165 
1166 /*********************************************************************
1167 *
1168 * SEGGER_RTT_Write
1169 *
1170 * Function description
1171 * Stores a specified number of characters in SEGGER RTT
1172 * control block which is then read by the host.
1173 *
1174 * Parameters
1175 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1176 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
1177 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
1178 *
1179 * Return value
1180 * Number of bytes which have been stored in the "Up"-buffer.
1181 *
1182 * Notes
1183 * (1) Data is stored according to buffer flags.
1184 */
1185 unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
1186  unsigned Status;
1187 
1188  INIT();
1189  SEGGER_RTT_LOCK();
1190  Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function
1192  return Status;
1193 }
1194 
1195 /*********************************************************************
1196 *
1197 * SEGGER_RTT_WriteString
1198 *
1199 * Function description
1200 * Stores string in SEGGER RTT control block.
1201 * This data is read by the host.
1202 *
1203 * Parameters
1204 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1205 * s Pointer to string.
1206 *
1207 * Return value
1208 * Number of bytes which have been stored in the "Up"-buffer.
1209 *
1210 * Notes
1211 * (1) Data is stored according to buffer flags.
1212 * (2) String passed to this function has to be \0 terminated
1213 * (3) \0 termination character is *not* stored in RTT buffer
1214 */
1215 unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
1216  unsigned Len;
1217 
1218  Len = STRLEN(s);
1219  return SEGGER_RTT_Write(BufferIndex, s, Len);
1220 }
1221 
1222 /*********************************************************************
1223 *
1224 * SEGGER_RTT_PutCharSkipNoLock
1225 *
1226 * Function description
1227 * Stores a single character/byte in SEGGER RTT buffer.
1228 * SEGGER_RTT_PutCharSkipNoLock does not lock the application and
1229 * skips the byte, if it does not fit into the buffer.
1230 *
1231 * Parameters
1232 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1233 * c Byte to be stored.
1234 *
1235 * Return value
1236 * Number of bytes which have been stored in the "Up"-buffer.
1237 *
1238 * Notes
1239 * (1) If there is not enough space in the "Up"-buffer, the character is dropped.
1240 * (2) For performance reasons this function does not call Init()
1241 * and may only be called after RTT has been initialized.
1242 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
1243 */
1244 
1245 unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) {
1246  SEGGER_RTT_BUFFER_UP* pRing;
1247  unsigned WrOff;
1248  unsigned Status;
1249  volatile char* pDst;
1250  //
1251  // Get "to-host" ring buffer.
1252  //
1253  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1254  //
1255  // Get write position and handle wrap-around if necessary
1256  //
1257  WrOff = pRing->WrOff + 1;
1258  if (WrOff == pRing->SizeOfBuffer) {
1259  WrOff = 0;
1260  }
1261  //
1262  // Output byte if free space is available
1263  //
1264  if (WrOff != pRing->RdOff) {
1265  pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
1266  *pDst = c;
1267  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
1268  pRing->WrOff = WrOff;
1269  Status = 1;
1270  } else {
1271  Status = 0;
1272  }
1273  //
1274  return Status;
1275 }
1276 
1277 /*********************************************************************
1278 *
1279 * SEGGER_RTT_PutCharSkip
1280 *
1281 * Function description
1282 * Stores a single character/byte in SEGGER RTT buffer.
1283 *
1284 * Parameters
1285 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1286 * c Byte to be stored.
1287 *
1288 * Return value
1289 * Number of bytes which have been stored in the "Up"-buffer.
1290 *
1291 * Notes
1292 * (1) If there is not enough space in the "Up"-buffer, the character is dropped.
1293 */
1294 
1295 unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) {
1296  SEGGER_RTT_BUFFER_UP* pRing;
1297  unsigned WrOff;
1298  unsigned Status;
1299  volatile char* pDst;
1300  //
1301  // Prepare
1302  //
1303  INIT();
1304  SEGGER_RTT_LOCK();
1305  //
1306  // Get "to-host" ring buffer.
1307  //
1308  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1309  //
1310  // Get write position and handle wrap-around if necessary
1311  //
1312  WrOff = pRing->WrOff + 1;
1313  if (WrOff == pRing->SizeOfBuffer) {
1314  WrOff = 0;
1315  }
1316  //
1317  // Output byte if free space is available
1318  //
1319  if (WrOff != pRing->RdOff) {
1320  pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
1321  *pDst = c;
1322  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
1323  pRing->WrOff = WrOff;
1324  Status = 1;
1325  } else {
1326  Status = 0;
1327  }
1328  //
1329  // Finish up.
1330  //
1332  //
1333  return Status;
1334 }
1335 
1336  /*********************************************************************
1337 *
1338 * SEGGER_RTT_PutChar
1339 *
1340 * Function description
1341 * Stores a single character/byte in SEGGER RTT buffer.
1342 *
1343 * Parameters
1344 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1345 * c Byte to be stored.
1346 *
1347 * Return value
1348 * Number of bytes which have been stored in the "Up"-buffer.
1349 *
1350 * Notes
1351 * (1) Data is stored according to buffer flags.
1352 */
1353 
1354 unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) {
1355  SEGGER_RTT_BUFFER_UP* pRing;
1356  unsigned WrOff;
1357  unsigned Status;
1358  volatile char* pDst;
1359  //
1360  // Prepare
1361  //
1362  INIT();
1363  SEGGER_RTT_LOCK();
1364  //
1365  // Get "to-host" ring buffer.
1366  //
1367  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1368  //
1369  // Get write position and handle wrap-around if necessary
1370  //
1371  WrOff = pRing->WrOff + 1;
1372  if (WrOff == pRing->SizeOfBuffer) {
1373  WrOff = 0;
1374  }
1375  //
1376  // Wait for free space if mode is set to blocking
1377  //
1378  if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
1379  while (WrOff == pRing->RdOff) {
1380  ;
1381  }
1382  }
1383  //
1384  // Output byte if free space is available
1385  //
1386  if (WrOff != pRing->RdOff) {
1387  pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
1388  *pDst = c;
1389  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
1390  pRing->WrOff = WrOff;
1391  Status = 1;
1392  } else {
1393  Status = 0;
1394  }
1395  //
1396  // Finish up.
1397  //
1399  return Status;
1400 }
1401 
1402 /*********************************************************************
1403 *
1404 * SEGGER_RTT_GetKey
1405 *
1406 * Function description
1407 * Reads one character from the SEGGER RTT buffer.
1408 * Host has previously stored data there.
1409 *
1410 * Return value
1411 * < 0 - No character available (buffer empty).
1412 * >= 0 - Character which has been read. (Possible values: 0 - 255)
1413 *
1414 * Notes
1415 * (1) This function is only specified for accesses to RTT buffer 0.
1416 */
1418  char c;
1419  int r;
1420 
1421  r = (int)SEGGER_RTT_Read(0u, &c, 1u);
1422  if (r == 1) {
1423  r = (int)(unsigned char)c;
1424  } else {
1425  r = -1;
1426  }
1427  return r;
1428 }
1429 
1430 /*********************************************************************
1431 *
1432 * SEGGER_RTT_WaitKey
1433 *
1434 * Function description
1435 * Waits until at least one character is avaible in the SEGGER RTT buffer.
1436 * Once a character is available, it is read and this function returns.
1437 *
1438 * Return value
1439 * >=0 - Character which has been read.
1440 *
1441 * Notes
1442 * (1) This function is only specified for accesses to RTT buffer 0
1443 * (2) This function is blocking if no character is present in RTT buffer
1444 */
1446  int r;
1447 
1448  do {
1449  r = SEGGER_RTT_GetKey();
1450  } while (r < 0);
1451  return r;
1452 }
1453 
1454 /*********************************************************************
1455 *
1456 * SEGGER_RTT_HasKey
1457 *
1458 * Function description
1459 * Checks if at least one character for reading is available in the SEGGER RTT buffer.
1460 *
1461 * Return value
1462 * == 0 - No characters are available to read.
1463 * == 1 - At least one character is available.
1464 *
1465 * Notes
1466 * (1) This function is only specified for accesses to RTT buffer 0
1467 */
1469  SEGGER_RTT_BUFFER_DOWN* pRing;
1470  unsigned RdOff;
1471  int r;
1472 
1473  INIT();
1474  pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1475  RdOff = pRing->RdOff;
1476  if (RdOff != pRing->WrOff) {
1477  r = 1;
1478  } else {
1479  r = 0;
1480  }
1481  return r;
1482 }
1483 
1484 /*********************************************************************
1485 *
1486 * SEGGER_RTT_HasData
1487 *
1488 * Function description
1489 * Check if there is data from the host in the given buffer.
1490 *
1491 * Return value:
1492 * ==0: No data
1493 * !=0: Data in buffer
1494 *
1495 */
1496 unsigned SEGGER_RTT_HasData(unsigned BufferIndex) {
1497  SEGGER_RTT_BUFFER_DOWN* pRing;
1498  unsigned v;
1499 
1500  pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1501  v = pRing->WrOff;
1502  return v - pRing->RdOff;
1503 }
1504 
1505 /*********************************************************************
1506 *
1507 * SEGGER_RTT_HasDataUp
1508 *
1509 * Function description
1510 * Check if there is data remaining to be sent in the given buffer.
1511 *
1512 * Return value:
1513 * ==0: No data
1514 * !=0: Data in buffer
1515 *
1516 */
1517 unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) {
1518  SEGGER_RTT_BUFFER_UP* pRing;
1519  unsigned v;
1520 
1521  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1522  v = pRing->RdOff;
1523  return pRing->WrOff - v;
1524 }
1525 
1526 /*********************************************************************
1527 *
1528 * SEGGER_RTT_AllocDownBuffer
1529 *
1530 * Function description
1531 * Run-time configuration of the next down-buffer (H->T).
1532 * The next buffer, which is not used yet is configured.
1533 * This includes: Buffer address, size, name, flags, ...
1534 *
1535 * Parameters
1536 * sName Pointer to a constant name string.
1537 * pBuffer Pointer to a buffer to be used.
1538 * BufferSize Size of the buffer.
1539 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
1540 *
1541 * Return value
1542 * >= 0 - O.K. Buffer Index
1543 * < 0 - Error
1544 */
1545 int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
1546  int BufferIndex;
1547  volatile SEGGER_RTT_CB* pRTTCB;
1548 
1549  INIT();
1550  SEGGER_RTT_LOCK();
1551  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1552  BufferIndex = 0;
1553  do {
1554  if (pRTTCB->aDown[BufferIndex].pBuffer == NULL) {
1555  break;
1556  }
1557  BufferIndex++;
1558  } while (BufferIndex < pRTTCB->MaxNumDownBuffers);
1559  if (BufferIndex < pRTTCB->MaxNumDownBuffers) {
1560  pRTTCB->aDown[BufferIndex].sName = sName;
1561  pRTTCB->aDown[BufferIndex].pBuffer = (char*)pBuffer;
1562  pRTTCB->aDown[BufferIndex].SizeOfBuffer = BufferSize;
1563  pRTTCB->aDown[BufferIndex].RdOff = 0u;
1564  pRTTCB->aDown[BufferIndex].WrOff = 0u;
1565  pRTTCB->aDown[BufferIndex].Flags = Flags;
1566  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
1567  } else {
1568  BufferIndex = -1;
1569  }
1571  return BufferIndex;
1572 }
1573 
1574 /*********************************************************************
1575 *
1576 * SEGGER_RTT_AllocUpBuffer
1577 *
1578 * Function description
1579 * Run-time configuration of the next up-buffer (T->H).
1580 * The next buffer, which is not used yet is configured.
1581 * This includes: Buffer address, size, name, flags, ...
1582 *
1583 * Parameters
1584 * sName Pointer to a constant name string.
1585 * pBuffer Pointer to a buffer to be used.
1586 * BufferSize Size of the buffer.
1587 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
1588 *
1589 * Return value
1590 * >= 0 - O.K. Buffer Index
1591 * < 0 - Error
1592 */
1593 int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
1594  int BufferIndex;
1595  volatile SEGGER_RTT_CB* pRTTCB;
1596 
1597  INIT();
1598  SEGGER_RTT_LOCK();
1599  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1600  BufferIndex = 0;
1601  do {
1602  if (pRTTCB->aUp[BufferIndex].pBuffer == NULL) {
1603  break;
1604  }
1605  BufferIndex++;
1606  } while (BufferIndex < pRTTCB->MaxNumUpBuffers);
1607  if (BufferIndex < pRTTCB->MaxNumUpBuffers) {
1608  pRTTCB->aUp[BufferIndex].sName = sName;
1609  pRTTCB->aUp[BufferIndex].pBuffer = (char*)pBuffer;
1610  pRTTCB->aUp[BufferIndex].SizeOfBuffer = BufferSize;
1611  pRTTCB->aUp[BufferIndex].RdOff = 0u;
1612  pRTTCB->aUp[BufferIndex].WrOff = 0u;
1613  pRTTCB->aUp[BufferIndex].Flags = Flags;
1614  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
1615  } else {
1616  BufferIndex = -1;
1617  }
1619  return BufferIndex;
1620 }
1621 
1622 /*********************************************************************
1623 *
1624 * SEGGER_RTT_ConfigUpBuffer
1625 *
1626 * Function description
1627 * Run-time configuration of a specific up-buffer (T->H).
1628 * Buffer to be configured is specified by index.
1629 * This includes: Buffer address, size, name, flags, ...
1630 *
1631 * Parameters
1632 * BufferIndex Index of the buffer to configure.
1633 * sName Pointer to a constant name string.
1634 * pBuffer Pointer to a buffer to be used.
1635 * BufferSize Size of the buffer.
1636 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
1637 *
1638 * Return value
1639 * >= 0 - O.K.
1640 * < 0 - Error
1641 *
1642 * Additional information
1643 * Buffer 0 is configured on compile-time.
1644 * May only be called once per buffer.
1645 * Buffer name and flags can be reconfigured using the appropriate functions.
1646 */
1647 int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
1648  int r;
1649  volatile SEGGER_RTT_CB* pRTTCB;
1650 
1651  INIT();
1652  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1653  if (BufferIndex < (unsigned)pRTTCB->MaxNumUpBuffers) {
1654  SEGGER_RTT_LOCK();
1655  if (BufferIndex > 0u) {
1656  pRTTCB->aUp[BufferIndex].sName = sName;
1657  pRTTCB->aUp[BufferIndex].pBuffer = (char*)pBuffer;
1658  pRTTCB->aUp[BufferIndex].SizeOfBuffer = BufferSize;
1659  pRTTCB->aUp[BufferIndex].RdOff = 0u;
1660  pRTTCB->aUp[BufferIndex].WrOff = 0u;
1661  }
1662  pRTTCB->aUp[BufferIndex].Flags = Flags;
1664  r = 0;
1665  } else {
1666  r = -1;
1667  }
1668  return r;
1669 }
1670 
1671 /*********************************************************************
1672 *
1673 * SEGGER_RTT_ConfigDownBuffer
1674 *
1675 * Function description
1676 * Run-time configuration of a specific down-buffer (H->T).
1677 * Buffer to be configured is specified by index.
1678 * This includes: Buffer address, size, name, flags, ...
1679 *
1680 * Parameters
1681 * BufferIndex Index of the buffer to configure.
1682 * sName Pointer to a constant name string.
1683 * pBuffer Pointer to a buffer to be used.
1684 * BufferSize Size of the buffer.
1685 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
1686 *
1687 * Return value
1688 * >= 0 O.K.
1689 * < 0 Error
1690 *
1691 * Additional information
1692 * Buffer 0 is configured on compile-time.
1693 * May only be called once per buffer.
1694 * Buffer name and flags can be reconfigured using the appropriate functions.
1695 */
1696 int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
1697  int r;
1698  volatile SEGGER_RTT_CB* pRTTCB;
1699 
1700  INIT();
1701  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1702  if (BufferIndex < (unsigned)pRTTCB->MaxNumDownBuffers) {
1703  SEGGER_RTT_LOCK();
1704  if (BufferIndex > 0u) {
1705  pRTTCB->aDown[BufferIndex].sName = sName;
1706  pRTTCB->aDown[BufferIndex].pBuffer = (char*)pBuffer;
1707  pRTTCB->aDown[BufferIndex].SizeOfBuffer = BufferSize;
1708  pRTTCB->aDown[BufferIndex].RdOff = 0u;
1709  pRTTCB->aDown[BufferIndex].WrOff = 0u;
1710  }
1711  pRTTCB->aDown[BufferIndex].Flags = Flags;
1712  RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
1714  r = 0;
1715  } else {
1716  r = -1;
1717  }
1718  return r;
1719 }
1720 
1721 /*********************************************************************
1722 *
1723 * SEGGER_RTT_SetNameUpBuffer
1724 *
1725 * Function description
1726 * Run-time configuration of a specific up-buffer name (T->H).
1727 * Buffer to be configured is specified by index.
1728 *
1729 * Parameters
1730 * BufferIndex Index of the buffer to renamed.
1731 * sName Pointer to a constant name string.
1732 *
1733 * Return value
1734 * >= 0 O.K.
1735 * < 0 Error
1736 */
1737 int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) {
1738  int r;
1739  volatile SEGGER_RTT_CB* pRTTCB;
1740 
1741  INIT();
1742  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1743  if (BufferIndex < (unsigned)pRTTCB->MaxNumUpBuffers) {
1744  SEGGER_RTT_LOCK();
1745  pRTTCB->aUp[BufferIndex].sName = sName;
1747  r = 0;
1748  } else {
1749  r = -1;
1750  }
1751  return r;
1752 }
1753 
1754 /*********************************************************************
1755 *
1756 * SEGGER_RTT_SetNameDownBuffer
1757 *
1758 * Function description
1759 * Run-time configuration of a specific Down-buffer name (T->H).
1760 * Buffer to be configured is specified by index.
1761 *
1762 * Parameters
1763 * BufferIndex Index of the buffer to renamed.
1764 * sName Pointer to a constant name string.
1765 *
1766 * Return value
1767 * >= 0 O.K.
1768 * < 0 Error
1769 */
1770 int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
1771  int r;
1772  volatile SEGGER_RTT_CB* pRTTCB;
1773 
1774  INIT();
1775  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1776  if (BufferIndex < (unsigned)pRTTCB->MaxNumDownBuffers) {
1777  SEGGER_RTT_LOCK();
1778  pRTTCB->aDown[BufferIndex].sName = sName;
1780  r = 0;
1781  } else {
1782  r = -1;
1783  }
1784  return r;
1785 }
1786 
1787 /*********************************************************************
1788 *
1789 * SEGGER_RTT_SetFlagsUpBuffer
1790 *
1791 * Function description
1792 * Run-time configuration of specific up-buffer flags (T->H).
1793 * Buffer to be configured is specified by index.
1794 *
1795 * Parameters
1796 * BufferIndex Index of the buffer.
1797 * Flags Flags to set for the buffer.
1798 *
1799 * Return value
1800 * >= 0 O.K.
1801 * < 0 Error
1802 */
1803 int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) {
1804  int r;
1805  volatile SEGGER_RTT_CB* pRTTCB;
1806 
1807  INIT();
1808  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1809  if (BufferIndex < (unsigned)pRTTCB->MaxNumUpBuffers) {
1810  SEGGER_RTT_LOCK();
1811  pRTTCB->aUp[BufferIndex].Flags = Flags;
1813  r = 0;
1814  } else {
1815  r = -1;
1816  }
1817  return r;
1818 }
1819 
1820 /*********************************************************************
1821 *
1822 * SEGGER_RTT_SetFlagsDownBuffer
1823 *
1824 * Function description
1825 * Run-time configuration of specific Down-buffer flags (T->H).
1826 * Buffer to be configured is specified by index.
1827 *
1828 * Parameters
1829 * BufferIndex Index of the buffer to renamed.
1830 * Flags Flags to set for the buffer.
1831 *
1832 * Return value
1833 * >= 0 O.K.
1834 * < 0 Error
1835 */
1836 int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
1837  int r;
1838  volatile SEGGER_RTT_CB* pRTTCB;
1839 
1840  INIT();
1841  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1842  if (BufferIndex < (unsigned)pRTTCB->MaxNumDownBuffers) {
1843  SEGGER_RTT_LOCK();
1844  pRTTCB->aDown[BufferIndex].Flags = Flags;
1846  r = 0;
1847  } else {
1848  r = -1;
1849  }
1850  return r;
1851 }
1852 
1853 /*********************************************************************
1854 *
1855 * SEGGER_RTT_Init
1856 *
1857 * Function description
1858 * Initializes the RTT Control Block.
1859 * Should be used in RAM targets, at start of the application.
1860 *
1861 */
1862 void SEGGER_RTT_Init (void) {
1863  _DoInit();
1864 }
1865 
1866 /*********************************************************************
1867 *
1868 * SEGGER_RTT_SetTerminal
1869 *
1870 * Function description
1871 * Sets the terminal to be used for output on channel 0.
1872 *
1873 * Parameters
1874 * TerminalId Index of the terminal.
1875 *
1876 * Return value
1877 * >= 0 O.K.
1878 * < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id)
1879 *
1880 * Notes
1881 * (1) Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed
1882 */
1883 int SEGGER_RTT_SetTerminal (unsigned char TerminalId) {
1884  unsigned char ac[2];
1885  SEGGER_RTT_BUFFER_UP* pRing;
1886  unsigned Avail;
1887  int r;
1888 
1889  INIT();
1890  r = 0;
1891  ac[0] = 0xFFu;
1892  if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels
1893  ac[1] = _aTerminalId[TerminalId];
1894  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1895  SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing
1897  _ActiveTerminal = TerminalId;
1898  _WriteBlocking(pRing, (const char*)ac, 2u);
1899  } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes
1900  Avail = _GetAvailWriteSpace(pRing);
1901  if (Avail >= 2) {
1902  _ActiveTerminal = TerminalId; // Only change active terminal in case of success
1903  _WriteNoCheck(pRing, (const char*)ac, 2u);
1904  } else {
1905  r = -1;
1906  }
1907  }
1909  } else {
1910  r = -1;
1911  }
1912  return r;
1913 }
1914 
1915 /*********************************************************************
1916 *
1917 * SEGGER_RTT_TerminalOut
1918 *
1919 * Function description
1920 * Writes a string to the given terminal
1921 * without changing the terminal for channel 0.
1922 *
1923 * Parameters
1924 * TerminalId Index of the terminal.
1925 * s String to be printed on the terminal.
1926 *
1927 * Return value
1928 * >= 0 - Number of bytes written.
1929 * < 0 - Error.
1930 *
1931 */
1932 int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) {
1933  int Status;
1934  unsigned FragLen;
1935  unsigned Avail;
1936  SEGGER_RTT_BUFFER_UP* pRing;
1937  //
1938  INIT();
1939  //
1940  // Validate terminal ID.
1941  //
1942  if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels
1943  //
1944  // Get "to-host" ring buffer.
1945  //
1946  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1947  //
1948  // Need to be able to change terminal, write data, change back.
1949  // Compute the fixed and variable sizes.
1950  //
1951  FragLen = STRLEN(s);
1952  //
1953  // How we output depends upon the mode...
1954  //
1955  SEGGER_RTT_LOCK();
1956  Avail = _GetAvailWriteSpace(pRing);
1957  switch (pRing->Flags & SEGGER_RTT_MODE_MASK) {
1959  //
1960  // If we are in skip mode and there is no space for the whole
1961  // of this output, don't bother switching terminals at all.
1962  //
1963  if (Avail < (FragLen + 4u)) {
1964  Status = 0;
1965  } else {
1966  _PostTerminalSwitch(pRing, TerminalId);
1967  Status = (int)_WriteBlocking(pRing, s, FragLen);
1969  }
1970  break;
1972  //
1973  // If we are in trim mode and there is not enough space for everything,
1974  // trim the output but always include the terminal switch. If no room
1975  // for terminal switch, skip that totally.
1976  //
1977  if (Avail < 4u) {
1978  Status = -1;
1979  } else {
1980  _PostTerminalSwitch(pRing, TerminalId);
1981  Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u));
1983  }
1984  break;
1986  //
1987  // If we are in blocking mode, output everything.
1988  //
1989  _PostTerminalSwitch(pRing, TerminalId);
1990  Status = (int)_WriteBlocking(pRing, s, FragLen);
1992  break;
1993  default:
1994  Status = -1;
1995  break;
1996  }
1997  //
1998  // Finish up.
1999  //
2001  } else {
2002  Status = -1;
2003  }
2004  return Status;
2005 }
2006 
2007 /*********************************************************************
2008 *
2009 * SEGGER_RTT_GetAvailWriteSpace
2010 *
2011 * Function description
2012 * Returns the number of bytes available in the ring buffer.
2013 *
2014 * Parameters
2015 * BufferIndex Index of the up buffer.
2016 *
2017 * Return value
2018 * Number of bytes that are free in the selected up buffer.
2019 */
2020 unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex) {
2021  SEGGER_RTT_BUFFER_UP* pRing;
2022 
2023  pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
2024  return _GetAvailWriteSpace(pRing);
2025 }
2026 
2027 
2028 /*********************************************************************
2029 *
2030 * SEGGER_RTT_GetBytesInBuffer()
2031 *
2032 * Function description
2033 * Returns the number of bytes currently used in the up buffer.
2034 *
2035 * Parameters
2036 * BufferIndex Index of the up buffer.
2037 *
2038 * Return value
2039 * Number of bytes that are used in the buffer.
2040 */
2041 unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex) {
2042  unsigned RdOff;
2043  unsigned WrOff;
2044  unsigned r;
2045  volatile SEGGER_RTT_CB* pRTTCB;
2046  //
2047  // Avoid warnings regarding volatile access order. It's not a problem
2048  // in this case, but dampen compiler enthusiasm.
2049  //
2050  pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
2051  RdOff = pRTTCB->aUp[BufferIndex].RdOff;
2052  WrOff = pRTTCB->aUp[BufferIndex].WrOff;
2053  if (RdOff <= WrOff) {
2054  r = WrOff - RdOff;
2055  } else {
2056  r = pRTTCB->aUp[BufferIndex].SizeOfBuffer - (WrOff - RdOff);
2057  }
2058  return r;
2059 }
2060 
2061 /*************************** End of file ****************************/
SEGGER_RTT_BUFFER_UP::WrOff
unsigned WrOff
Definition: SEGGER_RTT.h:234
SEGGER_RTT_HasDataUp
unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex)
Definition: SEGGER_RTT.c:1517
SEGGER_RTT_AllocUpBuffer
int SEGGER_RTT_AllocUpBuffer(const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
Definition: SEGGER_RTT.c:1593
SEGGER_RTT_WriteSkipNoLock
unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
Definition: SEGGER_RTT.c:915
SEGGER_RTT_MODE_DEFAULT
#define SEGGER_RTT_MODE_DEFAULT
Definition: SEGGER_RTT_Conf.h:102
SEGGER_RTT_WriteDownBuffer
unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
Definition: SEGGER_RTT.c:1156
SEGGER_RTT_BUFFER_DOWN::Flags
unsigned Flags
Definition: SEGGER_RTT.h:244
SEGGER_RTT_UNLOCK
#define SEGGER_RTT_UNLOCK()
Definition: SEGGER_RTT_Conf.h:420
SEGGER_RTT_PutCharSkip
unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c)
Definition: SEGGER_RTT.c:1295
STRCPY
#define STRCPY(pDest, pSrc)
Definition: SEGGER_RTT.c:151
SEGGER_RTT_BUFFER_DOWN::sName
const char * sName
Definition: SEGGER_RTT.h:239
SEGGER_RTT_BUFFER_DOWN
Definition: SEGGER_RTT.h:238
RTT__DMB
#define RTT__DMB()
Definition: SEGGER_RTT.h:167
SEGGER_RTT_WriteDownBufferNoLock
unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
Definition: SEGGER_RTT.c:1005
SEGGER_RTT_WriteNoLock
unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
Definition: SEGGER_RTT.c:1080
SEGGER_RTT_SetFlagsDownBuffer
int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags)
Definition: SEGGER_RTT.c:1836
_WriteNoCheck
static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP *pRing, const char *pData, unsigned NumBytes)
Definition: SEGGER_RTT.c:417
_GetAvailWriteSpace
static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP *pRing)
Definition: SEGGER_RTT.c:507
_aTerminalId
static unsigned char _aTerminalId[16]
Definition: SEGGER_RTT.c:253
SEGGER_RTT_GetAvailWriteSpace
unsigned SEGGER_RTT_GetAvailWriteSpace(unsigned BufferIndex)
Definition: SEGGER_RTT.c:2020
SEGGER_RTT_ConfigUpBuffer
int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
Definition: SEGGER_RTT.c:1647
SEGGER_RTT_HasData
unsigned SEGGER_RTT_HasData(unsigned BufferIndex)
Definition: SEGGER_RTT.c:1496
SEGGER_RTT_CB::MaxNumUpBuffers
int MaxNumUpBuffers
Definition: SEGGER_RTT.h:254
SEGGER_RTT_HasKey
int SEGGER_RTT_HasKey(void)
Definition: SEGGER_RTT.c:1468
SEGGER_RTT_ReadUpBuffer
unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void *pBuffer, unsigned BufferSize)
Definition: SEGGER_RTT.c:743
SEGGER_RTT_BUFFER_UP::RdOff
volatile unsigned RdOff
Definition: SEGGER_RTT.h:235
SEGGER_RTT_TerminalOut
int SEGGER_RTT_TerminalOut(unsigned char TerminalId, const char *s)
Definition: SEGGER_RTT.c:1932
SEGGER_RTT_PUT_CB_SECTION
#define SEGGER_RTT_PUT_CB_SECTION(Var)
Definition: SEGGER_RTT.c:237
SEGGER_RTT_SetNameUpBuffer
int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char *sName)
Definition: SEGGER_RTT.c:1737
SEGGER_RTT_GetKey
int SEGGER_RTT_GetKey(void)
Definition: SEGGER_RTT.c:1417
SEGGER_RTT_BUFFER_UP
Definition: SEGGER_RTT.h:225
SEGGER_RTT_BUFFER_UP::sName
const char * sName
Definition: SEGGER_RTT.h:231
SEGGER_RTT_MODE_MASK
#define SEGGER_RTT_MODE_MASK
Definition: SEGGER_RTT.h:366
SEGGER_RTT_CB::aUp
SEGGER_RTT_BUFFER_UP aUp[(3)]
Definition: SEGGER_RTT.h:256
_acUpBuffer
static char _acUpBuffer[((1024))]
Definition: SEGGER_RTT.c:266
SEGGER_RTT_ReadNoLock
unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void *pData, unsigned BufferSize)
Definition: SEGGER_RTT.c:646
SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE
#define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes)
Definition: SEGGER_RTT.h:209
SEGGER_RTT_AllocDownBuffer
int SEGGER_RTT_AllocDownBuffer(const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
Definition: SEGGER_RTT.c:1545
SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
Definition: SEGGER_RTT.h:365
SEGGER_RTT_PutChar
unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c)
Definition: SEGGER_RTT.c:1354
SEGGER_RTT_ConfigDownBuffer
int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
Definition: SEGGER_RTT.c:1696
SEGGER_RTT_WriteWithOverwriteNoLock
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
Definition: SEGGER_RTT.c:814
SEGGER_RTT_Read
unsigned SEGGER_RTT_Read(unsigned BufferIndex, void *pBuffer, unsigned BufferSize)
Definition: SEGGER_RTT.c:775
SEGGER_RTT_PUT_BUFFER_SECTION
#define SEGGER_RTT_PUT_BUFFER_SECTION(Var)
Definition: SEGGER_RTT.c:243
_ActiveTerminal
static unsigned char _ActiveTerminal
Definition: SEGGER_RTT.c:269
_acDownBuffer
static char _acDownBuffer[((16))]
Definition: SEGGER_RTT.c:267
SEGGER_RTT_WaitKey
int SEGGER_RTT_WaitKey(void)
Definition: SEGGER_RTT.c:1445
_SEGGER_RTT
SEGGER_RTT_CB _SEGGER_RTT
Definition: SEGGER_RTT.c:265
SEGGER_RTT_WriteString
unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char *s)
Definition: SEGGER_RTT.c:1215
SEGGER_RTT_LOCK
#define SEGGER_RTT_LOCK()
Definition: SEGGER_RTT_Conf.h:416
SEGGER_RTT_CB::acID
char acID[16]
Definition: SEGGER_RTT.h:253
SEGGER_RTT_MODE_NO_BLOCK_TRIM
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM
Definition: SEGGER_RTT.h:364
SEGGER_RTT_GetBytesInBuffer
unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex)
Definition: SEGGER_RTT.c:2041
_WriteBlocking
static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP *pRing, const char *pBuffer, unsigned NumBytes)
Definition: SEGGER_RTT.c:355
SEGGER_RTT_BUFFER_UP::SizeOfBuffer
unsigned SizeOfBuffer
Definition: SEGGER_RTT.h:233
SEGGER_RTT_SetTerminal
int SEGGER_RTT_SetTerminal(unsigned char TerminalId)
Definition: SEGGER_RTT.c:1883
SEGGER_RTT_CB
Definition: SEGGER_RTT.h:252
SEGGER_RTT_SetNameDownBuffer
int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char *sName)
Definition: SEGGER_RTT.c:1770
SEGGER_RTT_BUFFER_DOWN::WrOff
volatile unsigned WrOff
Definition: SEGGER_RTT.h:242
_PostTerminalSwitch
static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP *pRing, unsigned char TerminalId)
Definition: SEGGER_RTT.c:485
SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
Definition: SEGGER_RTT_Conf.h:86
INIT
#define INIT()
Definition: SEGGER_RTT.c:287
SEGGER_RTT_MEMCPY
#define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes)
Definition: SEGGER_RTT.c:162
SEGGER_RTT_Write
unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
Definition: SEGGER_RTT.c:1185
SEGGER_RTT_BUFFER_UP::pBuffer
char * pBuffer
Definition: SEGGER_RTT.h:232
SEGGER_RTT_CB::aDown
SEGGER_RTT_BUFFER_DOWN aDown[(3)]
Definition: SEGGER_RTT.h:257
SEGGER_RTT_MAX_NUM_UP_BUFFERS
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS
Definition: SEGGER_RTT_Conf.h:78
SEGGER_RTT_BUFFER_DOWN::pBuffer
char * pBuffer
Definition: SEGGER_RTT.h:240
_DoInit
static void _DoInit(void)
Definition: SEGGER_RTT.c:297
SEGGER_RTT_BUFFER_DOWN::RdOff
unsigned RdOff
Definition: SEGGER_RTT.h:243
STRLEN
#define STRLEN(a)
Definition: SEGGER_RTT.c:147
SEGGER_RTT_SetFlagsUpBuffer
int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags)
Definition: SEGGER_RTT.c:1803
SEGGER_RTT_CB_ALIGN
#define SEGGER_RTT_CB_ALIGN(Var)
Definition: SEGGER_RTT.c:224
SEGGER_RTT_CB::MaxNumDownBuffers
int MaxNumDownBuffers
Definition: SEGGER_RTT.h:255
SEGGER_RTT.h
MIN
#define MIN(a, b)
Definition: SEGGER_RTT.c:167
SEGGER_RTT_UNCACHED_OFF
#define SEGGER_RTT_UNCACHED_OFF
Definition: SEGGER_RTT.h:179
BUFFER_SIZE_DOWN
#define BUFFER_SIZE_DOWN
Definition: SEGGER_RTT_Conf.h:94
SEGGER_RTT_BUFFER_UP::Flags
unsigned Flags
Definition: SEGGER_RTT.h:236
SEGGER_RTT_MODE_NO_BLOCK_SKIP
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP
Definition: SEGGER_RTT.h:363
SEGGER_RTT_PutCharSkipNoLock
unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c)
Definition: SEGGER_RTT.c:1245
SEGGER_RTT_Init
void SEGGER_RTT_Init(void)
Definition: SEGGER_RTT.c:1862
SEGGER_RTT_BUFFER_ALIGN
#define SEGGER_RTT_BUFFER_ALIGN(Var)
Definition: SEGGER_RTT.c:230
SEGGER_RTT_BUFFER_DOWN::SizeOfBuffer
unsigned SizeOfBuffer
Definition: SEGGER_RTT.h:241
NULL
#define NULL
Definition: SEGGER_RTT.c:177
BUFFER_SIZE_UP
#define BUFFER_SIZE_UP
Definition: SEGGER_RTT_Conf.h:90
SEGGER_RTT_ReadUpBufferNoLock
unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void *pData, unsigned BufferSize)
Definition: SEGGER_RTT.c:554