DIY Logging Volt/Ampmeter
SEGGER_RTT.c File Reference
#include "SEGGER_RTT.h"
#include <string.h>

Go to the source code of this file.

Macros

#define SEGGER_RTT_ALIGNMENT   SEGGER_RTT_CPU_CACHE_LINE_SIZE
 
#define SEGGER_RTT_BUFFER_ALIGNMENT   SEGGER_RTT_CPU_CACHE_LINE_SIZE
 
#define STRLEN(a)   strlen((a))
 
#define STRCPY(pDest, pSrc)   strcpy((pDest), (pSrc))
 
#define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes)   memcpy((pDest), (pSrc), (NumBytes))
 
#define MIN(a, b)   (((a) < (b)) ? (a) : (b))
 
#define MAX(a, b)   (((a) > (b)) ? (a) : (b))
 
#define NULL   0
 
#define SEGGER_RTT_ALIGN(Var, Alignment)   Var
 
#define SEGGER_RTT_PUT_SECTION(Var, Section)   Var
 
#define SEGGER_RTT_CB_ALIGN(Var)   Var
 
#define SEGGER_RTT_BUFFER_ALIGN(Var)   Var
 
#define SEGGER_RTT_PUT_CB_SECTION(Var)   Var
 
#define SEGGER_RTT_PUT_BUFFER_SECTION(Var)   Var
 
#define INIT()
 

Functions

static void _DoInit (void)
 
static unsigned _WriteBlocking (SEGGER_RTT_BUFFER_UP *pRing, const char *pBuffer, unsigned NumBytes)
 
static void _WriteNoCheck (SEGGER_RTT_BUFFER_UP *pRing, const char *pData, unsigned NumBytes)
 
static void _PostTerminalSwitch (SEGGER_RTT_BUFFER_UP *pRing, unsigned char TerminalId)
 
static unsigned _GetAvailWriteSpace (SEGGER_RTT_BUFFER_UP *pRing)
 
unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void *pData, unsigned BufferSize)
 
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void *pData, unsigned BufferSize)
 
unsigned SEGGER_RTT_ReadUpBuffer (unsigned BufferIndex, void *pBuffer, unsigned BufferSize)
 
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void *pBuffer, unsigned BufferSize)
 
void SEGGER_RTT_WriteWithOverwriteNoLock (unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
 
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
 
unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
 
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
 
unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
 
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void *pBuffer, unsigned NumBytes)
 
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char *s)
 
unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c)
 
unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c)
 
unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c)
 
int SEGGER_RTT_GetKey (void)
 
int SEGGER_RTT_WaitKey (void)
 
int SEGGER_RTT_HasKey (void)
 
unsigned SEGGER_RTT_HasData (unsigned BufferIndex)
 
unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex)
 
int SEGGER_RTT_AllocDownBuffer (const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
 
int SEGGER_RTT_AllocUpBuffer (const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
 
int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
 
int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char *sName, void *pBuffer, unsigned BufferSize, unsigned Flags)
 
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char *sName)
 
int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char *sName)
 
int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags)
 
int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags)
 
void SEGGER_RTT_Init (void)
 
int SEGGER_RTT_SetTerminal (unsigned char TerminalId)
 
int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char *s)
 
unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex)
 
unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex)
 

Variables

static unsigned char _aTerminalId [16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }
 
SEGGER_RTT_CB _SEGGER_RTT
 
static char _acUpBuffer [((1024))]
 
static char _acDownBuffer [((16))]
 
static unsigned char _ActiveTerminal
 

Macro Definition Documentation

◆ INIT

#define INIT ( )
Value:
{ \
volatile SEGGER_RTT_CB* pRTTCBInit; \
pRTTCBInit = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \
do { \
if (pRTTCBInit->acID[0] == '\0') { \
_DoInit(); \
} \
} while (0); \
}

Definition at line 287 of file SEGGER_RTT.c.

◆ MAX

#define MAX (   a,
 
)    (((a) > (b)) ? (a) : (b))

Definition at line 171 of file SEGGER_RTT.c.

◆ MIN

#define MIN (   a,
 
)    (((a) < (b)) ? (a) : (b))

Definition at line 167 of file SEGGER_RTT.c.

◆ NULL

#define NULL   0

Definition at line 177 of file SEGGER_RTT.c.

◆ SEGGER_RTT_ALIGN

#define SEGGER_RTT_ALIGN (   Var,
  Alignment 
)    Var

Definition at line 203 of file SEGGER_RTT.c.

◆ SEGGER_RTT_ALIGNMENT

#define SEGGER_RTT_ALIGNMENT   SEGGER_RTT_CPU_CACHE_LINE_SIZE

Definition at line 127 of file SEGGER_RTT.c.

◆ SEGGER_RTT_BUFFER_ALIGN

#define SEGGER_RTT_BUFFER_ALIGN (   Var)    Var

Definition at line 230 of file SEGGER_RTT.c.

◆ SEGGER_RTT_BUFFER_ALIGNMENT

#define SEGGER_RTT_BUFFER_ALIGNMENT   SEGGER_RTT_CPU_CACHE_LINE_SIZE

Definition at line 131 of file SEGGER_RTT.c.

◆ SEGGER_RTT_CB_ALIGN

#define SEGGER_RTT_CB_ALIGN (   Var)    Var

Definition at line 224 of file SEGGER_RTT.c.

◆ SEGGER_RTT_MEMCPY

#define SEGGER_RTT_MEMCPY (   pDest,
  pSrc,
  NumBytes 
)    memcpy((pDest), (pSrc), (NumBytes))

Definition at line 162 of file SEGGER_RTT.c.

◆ SEGGER_RTT_PUT_BUFFER_SECTION

#define SEGGER_RTT_PUT_BUFFER_SECTION (   Var)    Var

Definition at line 243 of file SEGGER_RTT.c.

◆ SEGGER_RTT_PUT_CB_SECTION

#define SEGGER_RTT_PUT_CB_SECTION (   Var)    Var

Definition at line 237 of file SEGGER_RTT.c.

◆ SEGGER_RTT_PUT_SECTION

#define SEGGER_RTT_PUT_SECTION (   Var,
  Section 
)    Var

Definition at line 218 of file SEGGER_RTT.c.

◆ STRCPY

#define STRCPY (   pDest,
  pSrc 
)    strcpy((pDest), (pSrc))

Definition at line 151 of file SEGGER_RTT.c.

◆ STRLEN

#define STRLEN (   a)    strlen((a))

Definition at line 147 of file SEGGER_RTT.c.

Function Documentation

◆ _DoInit()

static void _DoInit ( void  )
static

Definition at line 297 of file SEGGER_RTT.c.

297  {
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 }

◆ _GetAvailWriteSpace()

static unsigned _GetAvailWriteSpace ( SEGGER_RTT_BUFFER_UP pRing)
static

Definition at line 507 of file SEGGER_RTT.c.

507  {
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 }

◆ _PostTerminalSwitch()

static void _PostTerminalSwitch ( SEGGER_RTT_BUFFER_UP pRing,
unsigned char  TerminalId 
)
static

Definition at line 485 of file SEGGER_RTT.c.

485  {
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 }

◆ _WriteBlocking()

static unsigned _WriteBlocking ( SEGGER_RTT_BUFFER_UP pRing,
const char *  pBuffer,
unsigned  NumBytes 
)
static

Definition at line 355 of file SEGGER_RTT.c.

355  {
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 }

◆ _WriteNoCheck()

static void _WriteNoCheck ( SEGGER_RTT_BUFFER_UP pRing,
const char *  pData,
unsigned  NumBytes 
)
static

Definition at line 417 of file SEGGER_RTT.c.

417  {
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 }

◆ SEGGER_RTT_AllocDownBuffer()

int SEGGER_RTT_AllocDownBuffer ( const char *  sName,
void *  pBuffer,
unsigned  BufferSize,
unsigned  Flags 
)

Definition at line 1545 of file SEGGER_RTT.c.

1545  {
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 }

◆ SEGGER_RTT_AllocUpBuffer()

int SEGGER_RTT_AllocUpBuffer ( const char *  sName,
void *  pBuffer,
unsigned  BufferSize,
unsigned  Flags 
)

Definition at line 1593 of file SEGGER_RTT.c.

1593  {
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 }

◆ SEGGER_RTT_ConfigDownBuffer()

int SEGGER_RTT_ConfigDownBuffer ( unsigned  BufferIndex,
const char *  sName,
void *  pBuffer,
unsigned  BufferSize,
unsigned  Flags 
)

Definition at line 1696 of file SEGGER_RTT.c.

1696  {
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 }

◆ SEGGER_RTT_ConfigUpBuffer()

int SEGGER_RTT_ConfigUpBuffer ( unsigned  BufferIndex,
const char *  sName,
void *  pBuffer,
unsigned  BufferSize,
unsigned  Flags 
)

Definition at line 1647 of file SEGGER_RTT.c.

1647  {
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 }

◆ SEGGER_RTT_GetAvailWriteSpace()

unsigned SEGGER_RTT_GetAvailWriteSpace ( unsigned  BufferIndex)

Definition at line 2020 of file SEGGER_RTT.c.

2020  {
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 }

◆ SEGGER_RTT_GetBytesInBuffer()

unsigned SEGGER_RTT_GetBytesInBuffer ( unsigned  BufferIndex)

Definition at line 2041 of file SEGGER_RTT.c.

2041  {
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 }

◆ SEGGER_RTT_GetKey()

int SEGGER_RTT_GetKey ( void  )

Definition at line 1417 of file SEGGER_RTT.c.

1417  {
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 }

◆ SEGGER_RTT_HasData()

unsigned SEGGER_RTT_HasData ( unsigned  BufferIndex)

Definition at line 1496 of file SEGGER_RTT.c.

1496  {
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 }

◆ SEGGER_RTT_HasDataUp()

unsigned SEGGER_RTT_HasDataUp ( unsigned  BufferIndex)

Definition at line 1517 of file SEGGER_RTT.c.

1517  {
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 }

◆ SEGGER_RTT_HasKey()

int SEGGER_RTT_HasKey ( void  )

Definition at line 1468 of file SEGGER_RTT.c.

1468  {
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 }

◆ SEGGER_RTT_Init()

void SEGGER_RTT_Init ( void  )

Definition at line 1862 of file SEGGER_RTT.c.

1862  {
1863  _DoInit();
1864 }

◆ SEGGER_RTT_PutChar()

unsigned SEGGER_RTT_PutChar ( unsigned  BufferIndex,
char  c 
)

Definition at line 1354 of file SEGGER_RTT.c.

1354  {
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 }

◆ SEGGER_RTT_PutCharSkip()

unsigned SEGGER_RTT_PutCharSkip ( unsigned  BufferIndex,
char  c 
)

Definition at line 1295 of file SEGGER_RTT.c.

1295  {
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 }

◆ SEGGER_RTT_PutCharSkipNoLock()

unsigned SEGGER_RTT_PutCharSkipNoLock ( unsigned  BufferIndex,
char  c 
)

Definition at line 1245 of file SEGGER_RTT.c.

1245  {
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 }

◆ SEGGER_RTT_Read()

unsigned SEGGER_RTT_Read ( unsigned  BufferIndex,
void *  pBuffer,
unsigned  BufferSize 
)

Definition at line 775 of file SEGGER_RTT.c.

775  {
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 }

◆ SEGGER_RTT_ReadNoLock()

unsigned SEGGER_RTT_ReadNoLock ( unsigned  BufferIndex,
void *  pData,
unsigned  BufferSize 
)

Definition at line 646 of file SEGGER_RTT.c.

646  {
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 }

◆ SEGGER_RTT_ReadUpBuffer()

unsigned SEGGER_RTT_ReadUpBuffer ( unsigned  BufferIndex,
void *  pBuffer,
unsigned  BufferSize 
)

Definition at line 743 of file SEGGER_RTT.c.

743  {
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 }

◆ SEGGER_RTT_ReadUpBufferNoLock()

unsigned SEGGER_RTT_ReadUpBufferNoLock ( unsigned  BufferIndex,
void *  pData,
unsigned  BufferSize 
)

Definition at line 554 of file SEGGER_RTT.c.

554  {
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 }

◆ SEGGER_RTT_SetFlagsDownBuffer()

int SEGGER_RTT_SetFlagsDownBuffer ( unsigned  BufferIndex,
unsigned  Flags 
)

Definition at line 1836 of file SEGGER_RTT.c.

1836  {
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 }

◆ SEGGER_RTT_SetFlagsUpBuffer()

int SEGGER_RTT_SetFlagsUpBuffer ( unsigned  BufferIndex,
unsigned  Flags 
)

Definition at line 1803 of file SEGGER_RTT.c.

1803  {
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 }

◆ SEGGER_RTT_SetNameDownBuffer()

int SEGGER_RTT_SetNameDownBuffer ( unsigned  BufferIndex,
const char *  sName 
)

Definition at line 1770 of file SEGGER_RTT.c.

1770  {
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 }

◆ SEGGER_RTT_SetNameUpBuffer()

int SEGGER_RTT_SetNameUpBuffer ( unsigned  BufferIndex,
const char *  sName 
)

Definition at line 1737 of file SEGGER_RTT.c.

1737  {
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 }

◆ SEGGER_RTT_SetTerminal()

int SEGGER_RTT_SetTerminal ( unsigned char  TerminalId)

Definition at line 1883 of file SEGGER_RTT.c.

1883  {
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 }

◆ SEGGER_RTT_TerminalOut()

int SEGGER_RTT_TerminalOut ( unsigned char  TerminalId,
const char *  s 
)

Definition at line 1932 of file SEGGER_RTT.c.

1932  {
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 }

◆ SEGGER_RTT_WaitKey()

int SEGGER_RTT_WaitKey ( void  )

Definition at line 1445 of file SEGGER_RTT.c.

1445  {
1446  int r;
1447 
1448  do {
1449  r = SEGGER_RTT_GetKey();
1450  } while (r < 0);
1451  return r;
1452 }

◆ SEGGER_RTT_Write()

unsigned SEGGER_RTT_Write ( unsigned  BufferIndex,
const void *  pBuffer,
unsigned  NumBytes 
)

Definition at line 1185 of file SEGGER_RTT.c.

1185  {
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 }

◆ SEGGER_RTT_WriteDownBuffer()

unsigned SEGGER_RTT_WriteDownBuffer ( unsigned  BufferIndex,
const void *  pBuffer,
unsigned  NumBytes 
)

Definition at line 1156 of file SEGGER_RTT.c.

1156  {
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 }

◆ SEGGER_RTT_WriteDownBufferNoLock()

unsigned SEGGER_RTT_WriteDownBufferNoLock ( unsigned  BufferIndex,
const void *  pBuffer,
unsigned  NumBytes 
)

Definition at line 1005 of file SEGGER_RTT.c.

1005  {
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 }

◆ SEGGER_RTT_WriteNoLock()

unsigned SEGGER_RTT_WriteNoLock ( unsigned  BufferIndex,
const void *  pBuffer,
unsigned  NumBytes 
)

Definition at line 1080 of file SEGGER_RTT.c.

1080  {
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 }

◆ SEGGER_RTT_WriteSkipNoLock()

unsigned SEGGER_RTT_WriteSkipNoLock ( unsigned  BufferIndex,
const void *  pBuffer,
unsigned  NumBytes 
)

Definition at line 915 of file SEGGER_RTT.c.

915  {
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 }

◆ SEGGER_RTT_WriteString()

unsigned SEGGER_RTT_WriteString ( unsigned  BufferIndex,
const char *  s 
)

Definition at line 1215 of file SEGGER_RTT.c.

1215  {
1216  unsigned Len;
1217 
1218  Len = STRLEN(s);
1219  return SEGGER_RTT_Write(BufferIndex, s, Len);
1220 }

◆ SEGGER_RTT_WriteWithOverwriteNoLock()

void SEGGER_RTT_WriteWithOverwriteNoLock ( unsigned  BufferIndex,
const void *  pBuffer,
unsigned  NumBytes 
)

Definition at line 814 of file SEGGER_RTT.c.

814  {
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 }

Variable Documentation

◆ _acDownBuffer

char _acDownBuffer[((16))]
static

Definition at line 267 of file SEGGER_RTT.c.

◆ _ActiveTerminal

unsigned char _ActiveTerminal
static

Definition at line 269 of file SEGGER_RTT.c.

◆ _acUpBuffer

char _acUpBuffer[((1024))]
static

Definition at line 266 of file SEGGER_RTT.c.

◆ _aTerminalId

unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }
static

Definition at line 253 of file SEGGER_RTT.c.

◆ _SEGGER_RTT

SEGGER_RTT_CB _SEGGER_RTT

Definition at line 265 of file SEGGER_RTT.c.

SEGGER_RTT_BUFFER_UP::WrOff
unsigned WrOff
Definition: SEGGER_RTT.h:234
SEGGER_RTT_MODE_DEFAULT
#define SEGGER_RTT_MODE_DEFAULT
Definition: SEGGER_RTT_Conf.h:102
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
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
_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_CB::MaxNumUpBuffers
int MaxNumUpBuffers
Definition: SEGGER_RTT.h:254
SEGGER_RTT_BUFFER_UP::RdOff
volatile unsigned RdOff
Definition: SEGGER_RTT.h:235
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_MODE_BLOCK_IF_FIFO_FULL
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
Definition: SEGGER_RTT.h:365
SEGGER_RTT_Read
unsigned SEGGER_RTT_Read(unsigned BufferIndex, void *pBuffer, unsigned BufferSize)
Definition: SEGGER_RTT.c:775
_ActiveTerminal
static unsigned char _ActiveTerminal
Definition: SEGGER_RTT.c:269
_acDownBuffer
static char _acDownBuffer[((16))]
Definition: SEGGER_RTT.c:267
_SEGGER_RTT
SEGGER_RTT_CB _SEGGER_RTT
Definition: SEGGER_RTT.c:265
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
_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_CB
Definition: SEGGER_RTT.h:252
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_CB::MaxNumDownBuffers
int MaxNumDownBuffers
Definition: SEGGER_RTT.h:255
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_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