mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
update segger rtt
This commit is contained in:
parent
2e2100078c
commit
e8246dd367
@ -1,35 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
@ -40,15 +39,12 @@
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT.c
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 12804 $
|
||||
|
||||
Additional information:
|
||||
Type "int" is assumed to be 32-bits in size
|
||||
@ -99,11 +95,19 @@ Additional information:
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_BUFFER_SECTION
|
||||
#if defined SEGGER_RTT_SECTION
|
||||
#if defined(SEGGER_RTT_SECTION)
|
||||
#define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_ALIGNMENT
|
||||
#define SEGGER_RTT_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_BUFFER_ALIGNMENT
|
||||
#define SEGGER_RTT_BUFFER_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_MODE_DEFAULT
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP
|
||||
#endif
|
||||
@ -120,8 +124,16 @@ Additional information:
|
||||
#define STRLEN(a) strlen((a))
|
||||
#endif
|
||||
|
||||
#ifndef MEMCPY
|
||||
#define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
|
||||
#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_MEMCPY
|
||||
#ifdef MEMCPY
|
||||
#define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes))
|
||||
#else
|
||||
#define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
@ -138,6 +150,73 @@ Additional information:
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
#if (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#define RTT_PRAGMA(P) _Pragma(#P)
|
||||
#endif
|
||||
|
||||
#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT
|
||||
#if (defined __GNUC__)
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#define PRAGMA(A) _Pragma(#A)
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \
|
||||
Var
|
||||
#elif (defined __CC_ARM)
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
|
||||
#else
|
||||
#error "Alignment not supported for this compiler."
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) Var
|
||||
#endif
|
||||
|
||||
#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION)
|
||||
#if (defined __GNUC__)
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \
|
||||
Var
|
||||
#elif (defined __CC_ARM)
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var
|
||||
#else
|
||||
#error "Section placement not supported for this compiler."
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) Var
|
||||
#endif
|
||||
|
||||
|
||||
#if SEGGER_RTT_ALIGNMENT
|
||||
#define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT)
|
||||
#else
|
||||
#define SEGGER_RTT_CB_ALIGN(Var) Var
|
||||
#endif
|
||||
|
||||
#if SEGGER_RTT_BUFFER_ALIGNMENT
|
||||
#define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT)
|
||||
#else
|
||||
#define SEGGER_RTT_BUFFER_ALIGN(Var) Var
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SEGGER_RTT_SECTION)
|
||||
#define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION)
|
||||
#else
|
||||
#define SEGGER_RTT_PUT_CB_SECTION(Var) Var
|
||||
#endif
|
||||
|
||||
#if defined(SEGGER_RTT_BUFFER_SECTION)
|
||||
#define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION)
|
||||
#else
|
||||
#define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Static const data
|
||||
@ -156,41 +235,10 @@ static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7'
|
||||
//
|
||||
// RTT Control Block and allocate buffers for channel 0
|
||||
//
|
||||
#ifdef SEGGER_RTT_SECTION
|
||||
#if (defined __GNUC__)
|
||||
__attribute__ ((section (SEGGER_RTT_SECTION))) SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#pragma location=SEGGER_RTT_SECTION
|
||||
SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#elif (defined __CC_ARM__)
|
||||
__attribute__ ((section (SEGGER_RTT_SECTION), zero_init)) SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#else
|
||||
SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#endif
|
||||
#else
|
||||
SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#endif
|
||||
SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
|
||||
|
||||
#ifdef SEGGER_RTT_BUFFER_SECTION
|
||||
#if (defined __GNUC__)
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#pragma location=SEGGER_RTT_BUFFER_SECTION
|
||||
static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
#pragma location=SEGGER_RTT_BUFFER_SECTION
|
||||
static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#elif (defined __CC_ARM__)
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#else
|
||||
static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#endif
|
||||
#else
|
||||
static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#endif
|
||||
SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP]));
|
||||
SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN]));
|
||||
|
||||
static char _ActiveTerminal;
|
||||
|
||||
@ -273,6 +321,9 @@ static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer,
|
||||
unsigned NumBytesWritten;
|
||||
unsigned RdOff;
|
||||
unsigned WrOff;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
//
|
||||
// Write data to buffer and handle wrap-around if necessary
|
||||
//
|
||||
@ -287,11 +338,21 @@ static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer,
|
||||
}
|
||||
NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around
|
||||
NumBytesToWrite = MIN(NumBytesToWrite, NumBytes);
|
||||
memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
NumBytesWritten += NumBytesToWrite;
|
||||
NumBytes -= NumBytesToWrite;
|
||||
WrOff += NumBytesToWrite;
|
||||
while (NumBytesToWrite--) {
|
||||
*pDst++ = *pBuffer++;
|
||||
};
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite);
|
||||
NumBytesWritten += NumBytesToWrite;
|
||||
pBuffer += NumBytesToWrite;
|
||||
NumBytes -= NumBytesToWrite;
|
||||
WrOff += NumBytesToWrite;
|
||||
#endif
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0u;
|
||||
}
|
||||
@ -323,6 +384,9 @@ static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsign
|
||||
unsigned NumBytesAtOnce;
|
||||
unsigned WrOff;
|
||||
unsigned Rem;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
|
||||
WrOff = pRing->WrOff;
|
||||
Rem = pRing->SizeOfBuffer - WrOff;
|
||||
@ -330,17 +394,40 @@ static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsign
|
||||
//
|
||||
// All data fits before wrap around
|
||||
//
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
} else {
|
||||
//
|
||||
// We reach the end of the buffer, so need to wrap around
|
||||
//
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
NumBytesAtOnce = Rem;
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce);
|
||||
while (NumBytesAtOnce--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pDst = pRing->pBuffer;
|
||||
NumBytesAtOnce = NumBytes - Rem;
|
||||
memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce);
|
||||
while (NumBytesAtOnce--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = NumBytes - Rem;
|
||||
#else
|
||||
NumBytesAtOnce = Rem;
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce);
|
||||
NumBytesAtOnce = NumBytes - Rem;
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce);
|
||||
pRing->WrOff = NumBytesAtOnce;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,11 +445,11 @@ static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsign
|
||||
* TerminalId Terminal ID to switch to.
|
||||
*/
|
||||
static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) {
|
||||
char ac[2];
|
||||
unsigned char ac[2];
|
||||
|
||||
ac[0] = 0xFFu;
|
||||
ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit
|
||||
_WriteBlocking(pRing, ac, 2u);
|
||||
_WriteBlocking(pRing, (const char*)ac, 2u);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@ -427,6 +514,9 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe
|
||||
unsigned WrOff;
|
||||
unsigned char* pBuffer;
|
||||
SEGGER_RTT_BUFFER_DOWN* pRing;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
const char* pSrc;
|
||||
#endif
|
||||
//
|
||||
INIT();
|
||||
pRing = &_SEGGER_RTT.aDown[BufferIndex];
|
||||
@ -440,11 +530,21 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe
|
||||
if (RdOff > WrOff) {
|
||||
NumBytesRem = pRing->SizeOfBuffer - RdOff;
|
||||
NumBytesRem = MIN(NumBytesRem, BufferSize);
|
||||
memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pSrc = pRing->pBuffer + RdOff;
|
||||
NumBytesRead += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
while (NumBytesRem--) {
|
||||
*pBuffer++ = *pSrc++;
|
||||
};
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
NumBytesRead += NumBytesRem;
|
||||
pBuffer += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
#endif
|
||||
//
|
||||
// Handle wrap-around of buffer
|
||||
//
|
||||
@ -458,11 +558,21 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe
|
||||
NumBytesRem = WrOff - RdOff;
|
||||
NumBytesRem = MIN(NumBytesRem, BufferSize);
|
||||
if (NumBytesRem > 0u) {
|
||||
memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pSrc = pRing->pBuffer + RdOff;
|
||||
NumBytesRead += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
while (NumBytesRem--) {
|
||||
*pBuffer++ = *pSrc++;
|
||||
};
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
NumBytesRead += NumBytesRem;
|
||||
pBuffer += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
#endif
|
||||
}
|
||||
if (NumBytesRead) {
|
||||
pRing->RdOff = RdOff;
|
||||
@ -530,6 +640,9 @@ void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuff
|
||||
const char* pData;
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned Avail;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
|
||||
pData = (const char *)pBuffer;
|
||||
//
|
||||
@ -561,26 +674,35 @@ void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuff
|
||||
//
|
||||
// Last round
|
||||
//
|
||||
#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead.
|
||||
char* pDst;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + pRing->WrOff;
|
||||
pRing->WrOff += NumBytes;
|
||||
do {
|
||||
Avail = NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
} while (--NumBytes);
|
||||
};
|
||||
pRing->WrOff += Avail;
|
||||
#else
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes);
|
||||
pRing->WrOff += NumBytes;
|
||||
#endif
|
||||
break; //Alternatively: NumBytes = 0;
|
||||
break;
|
||||
} else {
|
||||
//
|
||||
// Wrap-around necessary, write until wrap-around and reset WrOff
|
||||
//
|
||||
memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + pRing->WrOff;
|
||||
NumBytes -= Avail;
|
||||
while (Avail--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = 0;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail);
|
||||
pData += Avail;
|
||||
pRing->WrOff = 0;
|
||||
NumBytes -= Avail;
|
||||
#endif
|
||||
Avail = (pRing->SizeOfBuffer - 1);
|
||||
}
|
||||
} while (NumBytes);
|
||||
@ -617,6 +739,9 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
unsigned RdOff;
|
||||
unsigned WrOff;
|
||||
unsigned Rem;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
|
||||
pData = (const char *)pBuffer;
|
||||
//
|
||||
@ -644,16 +769,15 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
//
|
||||
Avail = pRing->SizeOfBuffer - 1u - WrOff ;
|
||||
if (Avail >= NumBytes) {
|
||||
#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead.
|
||||
char* pDst;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
do {
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
} while (--NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
return 1;
|
||||
@ -671,23 +795,55 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
//
|
||||
Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer
|
||||
if (Rem > NumBytes) {
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
} else {
|
||||
//
|
||||
// We reach the end of the buffer, so need to wrap around
|
||||
//
|
||||
memcpy(pRing->pBuffer + WrOff, pData, Rem);
|
||||
memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
NumBytes -= Rem;
|
||||
WrOff = NumBytes;
|
||||
do {
|
||||
*pDst++ = *pData++;
|
||||
} while (--Rem);
|
||||
pDst = pRing->pBuffer;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, Rem);
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytes - Rem);
|
||||
pRing->WrOff = NumBytes - Rem;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
Avail = RdOff - WrOff - 1u;
|
||||
if (Avail >= NumBytes) {
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -715,7 +871,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
|
||||
* (1) Data is stored according to buffer flags.
|
||||
* (2) For performance reasons this function does not call Init()
|
||||
* and may only be called after RTT has been initialized.
|
||||
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
|
||||
@ -789,7 +945,7 @@ unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsig
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
|
||||
* (1) Data is stored according to buffer flags.
|
||||
*/
|
||||
unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
|
||||
unsigned Status;
|
||||
@ -824,8 +980,7 @@ unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned Nu
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, depending on configuration,
|
||||
* remaining characters may be dropped or RTT module waits until there is more space in the buffer.
|
||||
* (1) Data is stored according to buffer flags.
|
||||
* (2) String passed to this function has to be \0 terminated
|
||||
* (3) \0 termination character is *not* stored in RTT buffer
|
||||
*/
|
||||
@ -836,6 +991,178 @@ unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
|
||||
return SEGGER_RTT_Write(BufferIndex, s, Len);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_PutCharSkipNoLock
|
||||
*
|
||||
* Function description
|
||||
* Stores a single character/byte in SEGGER RTT buffer.
|
||||
* SEGGER_RTT_PutCharSkipNoLock does not lock the application and
|
||||
* skips the byte, if it does not fit into the buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* c Byte to be stored.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, the character is dropped.
|
||||
* (2) For performance reasons this function does not call Init()
|
||||
* and may only be called after RTT has been initialized.
|
||||
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
|
||||
*/
|
||||
|
||||
unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned WrOff;
|
||||
unsigned Status;
|
||||
//
|
||||
// Get "to-host" ring buffer.
|
||||
//
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
//
|
||||
// Get write position and handle wrap-around if necessary
|
||||
//
|
||||
WrOff = pRing->WrOff + 1;
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0;
|
||||
}
|
||||
//
|
||||
// Output byte if free space is available
|
||||
//
|
||||
if (WrOff != pRing->RdOff) {
|
||||
pRing->pBuffer[pRing->WrOff] = c;
|
||||
pRing->WrOff = WrOff;
|
||||
Status = 1;
|
||||
} else {
|
||||
Status = 0;
|
||||
}
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_PutCharSkip
|
||||
*
|
||||
* Function description
|
||||
* Stores a single character/byte in SEGGER RTT buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* c Byte to be stored.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, the character is dropped.
|
||||
*/
|
||||
|
||||
unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned WrOff;
|
||||
unsigned Status;
|
||||
//
|
||||
// Prepare
|
||||
//
|
||||
INIT();
|
||||
SEGGER_RTT_LOCK();
|
||||
//
|
||||
// Get "to-host" ring buffer.
|
||||
//
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
//
|
||||
// Get write position and handle wrap-around if necessary
|
||||
//
|
||||
WrOff = pRing->WrOff + 1;
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0;
|
||||
}
|
||||
//
|
||||
// Output byte if free space is available
|
||||
//
|
||||
if (WrOff != pRing->RdOff) {
|
||||
pRing->pBuffer[pRing->WrOff] = c;
|
||||
pRing->WrOff = WrOff;
|
||||
Status = 1;
|
||||
} else {
|
||||
Status = 0;
|
||||
}
|
||||
//
|
||||
// Finish up.
|
||||
//
|
||||
SEGGER_RTT_UNLOCK();
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_PutChar
|
||||
*
|
||||
* Function description
|
||||
* Stores a single character/byte in SEGGER RTT buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* c Byte to be stored.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) Data is stored according to buffer flags.
|
||||
*/
|
||||
|
||||
unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned WrOff;
|
||||
unsigned Status;
|
||||
//
|
||||
// Prepare
|
||||
//
|
||||
INIT();
|
||||
SEGGER_RTT_LOCK();
|
||||
//
|
||||
// Get "to-host" ring buffer.
|
||||
//
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
//
|
||||
// Get write position and handle wrap-around if necessary
|
||||
//
|
||||
WrOff = pRing->WrOff + 1;
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0;
|
||||
}
|
||||
//
|
||||
// Wait for free space if mode is set to blocking
|
||||
//
|
||||
if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
|
||||
while (WrOff == pRing->RdOff) {
|
||||
;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Output byte if free space is available
|
||||
//
|
||||
if (WrOff != pRing->RdOff) {
|
||||
pRing->pBuffer[pRing->WrOff] = c;
|
||||
pRing->WrOff = WrOff;
|
||||
Status = 1;
|
||||
} else {
|
||||
Status = 0;
|
||||
}
|
||||
//
|
||||
// Finish up.
|
||||
//
|
||||
SEGGER_RTT_UNLOCK();
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_GetKey
|
||||
@ -937,6 +1264,27 @@ unsigned SEGGER_RTT_HasData(unsigned BufferIndex) {
|
||||
return v - pRing->RdOff;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_HasDataUp
|
||||
*
|
||||
* Function description
|
||||
* Check if there is data remaining to be sent in the given buffer.
|
||||
*
|
||||
* Return value:
|
||||
* ==0: No data
|
||||
* !=0: Data in buffer
|
||||
*
|
||||
*/
|
||||
unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned v;
|
||||
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
v = pRing->RdOff;
|
||||
return pRing->WrOff - v;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_AllocDownBuffer
|
||||
@ -970,7 +1318,7 @@ int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned Buffer
|
||||
} while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers);
|
||||
if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) {
|
||||
_SEGGER_RTT.aDown[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
|
||||
@ -1015,7 +1363,7 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi
|
||||
} while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers);
|
||||
if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) {
|
||||
_SEGGER_RTT.aUp[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
|
||||
@ -1046,6 +1394,11 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi
|
||||
* Return value
|
||||
* >= 0 - O.K.
|
||||
* < 0 - Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
int r;
|
||||
@ -1055,7 +1408,7 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu
|
||||
SEGGER_RTT_LOCK();
|
||||
if (BufferIndex > 0u) {
|
||||
_SEGGER_RTT.aUp[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
|
||||
@ -1088,6 +1441,11 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
int r;
|
||||
@ -1097,7 +1455,7 @@ int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* p
|
||||
SEGGER_RTT_LOCK();
|
||||
if (BufferIndex > 0u) {
|
||||
_SEGGER_RTT.aDown[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
|
||||
@ -1173,6 +1531,68 @@ int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_SetFlagsUpBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of specific up-buffer flags (T->H).
|
||||
* Buffer to be configured is specified by index.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer.
|
||||
* Flags Flags to set for the buffer.
|
||||
*
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*/
|
||||
int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) {
|
||||
int r;
|
||||
|
||||
INIT();
|
||||
if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
|
||||
SEGGER_RTT_LOCK();
|
||||
_SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
|
||||
SEGGER_RTT_UNLOCK();
|
||||
r = 0;
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_SetFlagsDownBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of specific Down-buffer flags (T->H).
|
||||
* Buffer to be configured is specified by index.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer to renamed.
|
||||
* Flags Flags to set for the buffer.
|
||||
*
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*/
|
||||
int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
|
||||
int r;
|
||||
|
||||
INIT();
|
||||
if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
|
||||
SEGGER_RTT_LOCK();
|
||||
_SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
|
||||
SEGGER_RTT_UNLOCK();
|
||||
r = 0;
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_Init
|
||||
@ -1201,7 +1621,7 @@ void SEGGER_RTT_Init (void) {
|
||||
* < 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)
|
||||
*/
|
||||
int SEGGER_RTT_SetTerminal (char TerminalId) {
|
||||
char ac[2];
|
||||
unsigned char ac[2];
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned Avail;
|
||||
int r;
|
||||
@ -1209,19 +1629,19 @@ int SEGGER_RTT_SetTerminal (char TerminalId) {
|
||||
INIT();
|
||||
//
|
||||
r = 0;
|
||||
ac[0] = 0xFFU;
|
||||
ac[0] = 0xFFu;
|
||||
if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels
|
||||
ac[1] = _aTerminalId[(unsigned char)TerminalId];
|
||||
pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed
|
||||
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
|
||||
if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
|
||||
_ActiveTerminal = TerminalId;
|
||||
_WriteBlocking(pRing, ac, 2u);
|
||||
_WriteBlocking(pRing, (const char*)ac, 2u);
|
||||
} else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes
|
||||
Avail = _GetAvailWriteSpace(pRing);
|
||||
if (Avail >= 2) {
|
||||
_ActiveTerminal = TerminalId; // Only change active terminal in case of success
|
||||
_WriteNoCheck(pRing, ac, 2u);
|
||||
_WriteNoCheck(pRing, (const char*)ac, 2u);
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
@ -1269,7 +1689,7 @@ int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) {
|
||||
// Need to be able to change terminal, write data, change back.
|
||||
// Compute the fixed and variable sizes.
|
||||
//
|
||||
FragLen = strlen(s);
|
||||
FragLen = STRLEN(s);
|
||||
//
|
||||
// How we output depends upon the mode...
|
||||
//
|
||||
|
@ -1,35 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
@ -40,15 +39,12 @@
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT.h
|
||||
Purpose : Implementation of SEGGER real-time transfer which allows
|
||||
real-time communication on targets which support debugger
|
||||
memory accesses while the CPU is running.
|
||||
Revision: $Rev: 12804 $
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -56,6 +52,8 @@ Purpose : Implementation of SEGGER real-time transfer which allows
|
||||
#define SEGGER_RTT_H
|
||||
|
||||
#include "SEGGER_RTT_Conf.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
@ -127,24 +125,30 @@ extern SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
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_GetKey (void);
|
||||
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
|
||||
int SEGGER_RTT_HasKey (void);
|
||||
void SEGGER_RTT_Init (void);
|
||||
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
|
||||
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
|
||||
int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_WaitKey (void);
|
||||
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
|
||||
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_GetKey (void);
|
||||
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
|
||||
int SEGGER_RTT_HasKey (void);
|
||||
unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex);
|
||||
void SEGGER_RTT_Init (void);
|
||||
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
|
||||
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
|
||||
int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags);
|
||||
int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags);
|
||||
int SEGGER_RTT_WaitKey (void);
|
||||
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
|
||||
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c);
|
||||
unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c);
|
||||
unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c);
|
||||
//
|
||||
// Function macro for performance optimization
|
||||
//
|
||||
@ -166,6 +170,8 @@ int SEGGER_RTT_TerminalOut (char TerminalId, const char* s);
|
||||
**********************************************************************
|
||||
*/
|
||||
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
|
||||
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -189,44 +195,44 @@ int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
|
||||
// Control sequences, based on ANSI.
|
||||
// Can be used to control color, and clear the screen
|
||||
//
|
||||
#define RTT_CTRL_RESET "[0m" // Reset to default colors
|
||||
#define RTT_CTRL_CLEAR "[2J" // Clear screen, reposition cursor to top left
|
||||
#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors
|
||||
#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left
|
||||
|
||||
#define RTT_CTRL_TEXT_BLACK "[2;30m"
|
||||
#define RTT_CTRL_TEXT_RED "[2;31m"
|
||||
#define RTT_CTRL_TEXT_GREEN "[2;32m"
|
||||
#define RTT_CTRL_TEXT_YELLOW "[2;33m"
|
||||
#define RTT_CTRL_TEXT_BLUE "[2;34m"
|
||||
#define RTT_CTRL_TEXT_MAGENTA "[2;35m"
|
||||
#define RTT_CTRL_TEXT_CYAN "[2;36m"
|
||||
#define RTT_CTRL_TEXT_WHITE "[2;37m"
|
||||
#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m"
|
||||
#define RTT_CTRL_TEXT_RED "\x1B[2;31m"
|
||||
#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m"
|
||||
#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m"
|
||||
#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m"
|
||||
#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m"
|
||||
#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m"
|
||||
#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m"
|
||||
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLACK "[1;30m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_RED "[1;31m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_GREEN "[1;32m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "[1;33m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLUE "[1;34m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "[1;35m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_CYAN "[1;36m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_WHITE "[1;37m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m"
|
||||
|
||||
#define RTT_CTRL_BG_BLACK "[24;40m"
|
||||
#define RTT_CTRL_BG_RED "[24;41m"
|
||||
#define RTT_CTRL_BG_GREEN "[24;42m"
|
||||
#define RTT_CTRL_BG_YELLOW "[24;43m"
|
||||
#define RTT_CTRL_BG_BLUE "[24;44m"
|
||||
#define RTT_CTRL_BG_MAGENTA "[24;45m"
|
||||
#define RTT_CTRL_BG_CYAN "[24;46m"
|
||||
#define RTT_CTRL_BG_WHITE "[24;47m"
|
||||
#define RTT_CTRL_BG_BLACK "\x1B[24;40m"
|
||||
#define RTT_CTRL_BG_RED "\x1B[24;41m"
|
||||
#define RTT_CTRL_BG_GREEN "\x1B[24;42m"
|
||||
#define RTT_CTRL_BG_YELLOW "\x1B[24;43m"
|
||||
#define RTT_CTRL_BG_BLUE "\x1B[24;44m"
|
||||
#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m"
|
||||
#define RTT_CTRL_BG_CYAN "\x1B[24;46m"
|
||||
#define RTT_CTRL_BG_WHITE "\x1B[24;47m"
|
||||
|
||||
#define RTT_CTRL_BG_BRIGHT_BLACK "[4;40m"
|
||||
#define RTT_CTRL_BG_BRIGHT_RED "[4;41m"
|
||||
#define RTT_CTRL_BG_BRIGHT_GREEN "[4;42m"
|
||||
#define RTT_CTRL_BG_BRIGHT_YELLOW "[4;43m"
|
||||
#define RTT_CTRL_BG_BRIGHT_BLUE "[4;44m"
|
||||
#define RTT_CTRL_BG_BRIGHT_MAGENTA "[4;45m"
|
||||
#define RTT_CTRL_BG_BRIGHT_CYAN "[4;46m"
|
||||
#define RTT_CTRL_BG_BRIGHT_WHITE "[4;47m"
|
||||
#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m"
|
||||
#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m"
|
||||
#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m"
|
||||
#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m"
|
||||
#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m"
|
||||
#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m"
|
||||
#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m"
|
||||
#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m"
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,35 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
@ -40,22 +39,19 @@
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 12804 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_CONF_H
|
||||
#define SEGGER_RTT_CONF_H
|
||||
|
||||
#ifdef __ICCARM__
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
@ -76,47 +72,67 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT memcpy configuration
|
||||
*
|
||||
* memcpy() is good for large amounts of data,
|
||||
* but the overhead is big for small amounts, which are usually stored via RTT.
|
||||
* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead.
|
||||
*
|
||||
* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions.
|
||||
* This is may be required with memory access restrictions,
|
||||
* such as on Cortex-A devices with MMU.
|
||||
*/
|
||||
#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop
|
||||
//
|
||||
// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets
|
||||
//
|
||||
//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__))
|
||||
// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes))
|
||||
//#endif
|
||||
|
||||
//
|
||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||
//
|
||||
//
|
||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||
// (Higher priority = lower priority number)
|
||||
// Default value for embOS: 128u
|
||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
// In case of doubt mask all interrupts: 0u
|
||||
//
|
||||
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||
//
|
||||
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* Rowley CrossStudio and GCC
|
||||
*/
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) || (defined __clang__)
|
||||
#if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, primask \n\t" \
|
||||
"mov r1, $1 \n\t" \
|
||||
"movs r1, $1 \n\t" \
|
||||
"msr primask, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
}
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
@ -128,15 +144,15 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
: "=r" (LockState) \
|
||||
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__ARM_ARCH_7A__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
@ -161,7 +177,7 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
); \
|
||||
}
|
||||
#else
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
#endif
|
||||
@ -175,8 +191,8 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
|
||||
@ -186,13 +202,41 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_BASEPRI(); \
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RX
|
||||
*/
|
||||
#ifdef __ICCRX__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned long LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RL78
|
||||
*/
|
||||
#ifdef __ICCRL78__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
__istate_t LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for KEIL ARM
|
||||
@ -226,6 +270,32 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for TI ARM
|
||||
*/
|
||||
#ifdef __TI_ARM__
|
||||
#if defined (__TI_ARM_V6M0__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() _set_interrupt_priority(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration fallback
|
||||
|
@ -1,31 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
|
@ -1,35 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
@ -40,15 +39,12 @@
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT.c
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 12804 $
|
||||
|
||||
Additional information:
|
||||
Type "int" is assumed to be 32-bits in size
|
||||
@ -99,11 +95,19 @@ Additional information:
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_BUFFER_SECTION
|
||||
#if defined SEGGER_RTT_SECTION
|
||||
#if defined(SEGGER_RTT_SECTION)
|
||||
#define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_ALIGNMENT
|
||||
#define SEGGER_RTT_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_BUFFER_ALIGNMENT
|
||||
#define SEGGER_RTT_BUFFER_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_MODE_DEFAULT
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP
|
||||
#endif
|
||||
@ -120,8 +124,16 @@ Additional information:
|
||||
#define STRLEN(a) strlen((a))
|
||||
#endif
|
||||
|
||||
#ifndef MEMCPY
|
||||
#define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
|
||||
#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_MEMCPY
|
||||
#ifdef MEMCPY
|
||||
#define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes))
|
||||
#else
|
||||
#define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
@ -138,6 +150,73 @@ Additional information:
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
#if (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#define RTT_PRAGMA(P) _Pragma(#P)
|
||||
#endif
|
||||
|
||||
#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT
|
||||
#if (defined __GNUC__)
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#define PRAGMA(A) _Pragma(#A)
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \
|
||||
Var
|
||||
#elif (defined __CC_ARM)
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
|
||||
#else
|
||||
#error "Alignment not supported for this compiler."
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_RTT_ALIGN(Var, Alignment) Var
|
||||
#endif
|
||||
|
||||
#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION)
|
||||
#if (defined __GNUC__)
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \
|
||||
Var
|
||||
#elif (defined __CC_ARM)
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var
|
||||
#else
|
||||
#error "Section placement not supported for this compiler."
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_RTT_PUT_SECTION(Var, Section) Var
|
||||
#endif
|
||||
|
||||
|
||||
#if SEGGER_RTT_ALIGNMENT
|
||||
#define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT)
|
||||
#else
|
||||
#define SEGGER_RTT_CB_ALIGN(Var) Var
|
||||
#endif
|
||||
|
||||
#if SEGGER_RTT_BUFFER_ALIGNMENT
|
||||
#define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT)
|
||||
#else
|
||||
#define SEGGER_RTT_BUFFER_ALIGN(Var) Var
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SEGGER_RTT_SECTION)
|
||||
#define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION)
|
||||
#else
|
||||
#define SEGGER_RTT_PUT_CB_SECTION(Var) Var
|
||||
#endif
|
||||
|
||||
#if defined(SEGGER_RTT_BUFFER_SECTION)
|
||||
#define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION)
|
||||
#else
|
||||
#define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Static const data
|
||||
@ -156,41 +235,10 @@ static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7'
|
||||
//
|
||||
// RTT Control Block and allocate buffers for channel 0
|
||||
//
|
||||
#ifdef SEGGER_RTT_SECTION
|
||||
#if (defined __GNUC__)
|
||||
__attribute__ ((section (SEGGER_RTT_SECTION))) SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#pragma location=SEGGER_RTT_SECTION
|
||||
SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#elif (defined __CC_ARM__)
|
||||
__attribute__ ((section (SEGGER_RTT_SECTION), zero_init)) SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#else
|
||||
SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#endif
|
||||
#else
|
||||
SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#endif
|
||||
SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
|
||||
|
||||
#ifdef SEGGER_RTT_BUFFER_SECTION
|
||||
#if (defined __GNUC__)
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#elif (defined __ICCARM__) || (defined __ICCRX__)
|
||||
#pragma location=SEGGER_RTT_BUFFER_SECTION
|
||||
static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
#pragma location=SEGGER_RTT_BUFFER_SECTION
|
||||
static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#elif (defined __CC_ARM__)
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
__attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#else
|
||||
static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#endif
|
||||
#else
|
||||
static char _acUpBuffer [BUFFER_SIZE_UP];
|
||||
static char _acDownBuffer[BUFFER_SIZE_DOWN];
|
||||
#endif
|
||||
SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP]));
|
||||
SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN]));
|
||||
|
||||
static char _ActiveTerminal;
|
||||
|
||||
@ -273,6 +321,9 @@ static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer,
|
||||
unsigned NumBytesWritten;
|
||||
unsigned RdOff;
|
||||
unsigned WrOff;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
//
|
||||
// Write data to buffer and handle wrap-around if necessary
|
||||
//
|
||||
@ -287,11 +338,21 @@ static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer,
|
||||
}
|
||||
NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around
|
||||
NumBytesToWrite = MIN(NumBytesToWrite, NumBytes);
|
||||
memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
NumBytesWritten += NumBytesToWrite;
|
||||
NumBytes -= NumBytesToWrite;
|
||||
WrOff += NumBytesToWrite;
|
||||
while (NumBytesToWrite--) {
|
||||
*pDst++ = *pBuffer++;
|
||||
};
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite);
|
||||
NumBytesWritten += NumBytesToWrite;
|
||||
pBuffer += NumBytesToWrite;
|
||||
NumBytes -= NumBytesToWrite;
|
||||
WrOff += NumBytesToWrite;
|
||||
#endif
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0u;
|
||||
}
|
||||
@ -323,6 +384,9 @@ static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsign
|
||||
unsigned NumBytesAtOnce;
|
||||
unsigned WrOff;
|
||||
unsigned Rem;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
|
||||
WrOff = pRing->WrOff;
|
||||
Rem = pRing->SizeOfBuffer - WrOff;
|
||||
@ -330,17 +394,40 @@ static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsign
|
||||
//
|
||||
// All data fits before wrap around
|
||||
//
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
} else {
|
||||
//
|
||||
// We reach the end of the buffer, so need to wrap around
|
||||
//
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
NumBytesAtOnce = Rem;
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce);
|
||||
while (NumBytesAtOnce--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pDst = pRing->pBuffer;
|
||||
NumBytesAtOnce = NumBytes - Rem;
|
||||
memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce);
|
||||
while (NumBytesAtOnce--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = NumBytes - Rem;
|
||||
#else
|
||||
NumBytesAtOnce = Rem;
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce);
|
||||
NumBytesAtOnce = NumBytes - Rem;
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce);
|
||||
pRing->WrOff = NumBytesAtOnce;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,11 +445,11 @@ static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsign
|
||||
* TerminalId Terminal ID to switch to.
|
||||
*/
|
||||
static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) {
|
||||
char ac[2];
|
||||
unsigned char ac[2];
|
||||
|
||||
ac[0] = 0xFFu;
|
||||
ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit
|
||||
_WriteBlocking(pRing, ac, 2u);
|
||||
_WriteBlocking(pRing, (const char*)ac, 2u);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@ -427,6 +514,9 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe
|
||||
unsigned WrOff;
|
||||
unsigned char* pBuffer;
|
||||
SEGGER_RTT_BUFFER_DOWN* pRing;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
const char* pSrc;
|
||||
#endif
|
||||
//
|
||||
INIT();
|
||||
pRing = &_SEGGER_RTT.aDown[BufferIndex];
|
||||
@ -440,11 +530,21 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe
|
||||
if (RdOff > WrOff) {
|
||||
NumBytesRem = pRing->SizeOfBuffer - RdOff;
|
||||
NumBytesRem = MIN(NumBytesRem, BufferSize);
|
||||
memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pSrc = pRing->pBuffer + RdOff;
|
||||
NumBytesRead += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
while (NumBytesRem--) {
|
||||
*pBuffer++ = *pSrc++;
|
||||
};
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
NumBytesRead += NumBytesRem;
|
||||
pBuffer += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
#endif
|
||||
//
|
||||
// Handle wrap-around of buffer
|
||||
//
|
||||
@ -458,11 +558,21 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe
|
||||
NumBytesRem = WrOff - RdOff;
|
||||
NumBytesRem = MIN(NumBytesRem, BufferSize);
|
||||
if (NumBytesRem > 0u) {
|
||||
memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pSrc = pRing->pBuffer + RdOff;
|
||||
NumBytesRead += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
while (NumBytesRem--) {
|
||||
*pBuffer++ = *pSrc++;
|
||||
};
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
|
||||
NumBytesRead += NumBytesRem;
|
||||
pBuffer += NumBytesRem;
|
||||
BufferSize -= NumBytesRem;
|
||||
RdOff += NumBytesRem;
|
||||
#endif
|
||||
}
|
||||
if (NumBytesRead) {
|
||||
pRing->RdOff = RdOff;
|
||||
@ -530,6 +640,9 @@ void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuff
|
||||
const char* pData;
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned Avail;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
|
||||
pData = (const char *)pBuffer;
|
||||
//
|
||||
@ -561,26 +674,35 @@ void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuff
|
||||
//
|
||||
// Last round
|
||||
//
|
||||
#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead.
|
||||
char* pDst;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + pRing->WrOff;
|
||||
pRing->WrOff += NumBytes;
|
||||
do {
|
||||
Avail = NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
} while (--NumBytes);
|
||||
};
|
||||
pRing->WrOff += Avail;
|
||||
#else
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes);
|
||||
pRing->WrOff += NumBytes;
|
||||
#endif
|
||||
break; //Alternatively: NumBytes = 0;
|
||||
break;
|
||||
} else {
|
||||
//
|
||||
// Wrap-around necessary, write until wrap-around and reset WrOff
|
||||
//
|
||||
memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + pRing->WrOff;
|
||||
NumBytes -= Avail;
|
||||
while (Avail--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = 0;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail);
|
||||
pData += Avail;
|
||||
pRing->WrOff = 0;
|
||||
NumBytes -= Avail;
|
||||
#endif
|
||||
Avail = (pRing->SizeOfBuffer - 1);
|
||||
}
|
||||
} while (NumBytes);
|
||||
@ -617,6 +739,9 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
unsigned RdOff;
|
||||
unsigned WrOff;
|
||||
unsigned Rem;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
char* pDst;
|
||||
#endif
|
||||
|
||||
pData = (const char *)pBuffer;
|
||||
//
|
||||
@ -644,16 +769,15 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
//
|
||||
Avail = pRing->SizeOfBuffer - 1u - WrOff ;
|
||||
if (Avail >= NumBytes) {
|
||||
#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead.
|
||||
char* pDst;
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
do {
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
} while (--NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
return 1;
|
||||
@ -671,23 +795,55 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
//
|
||||
Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer
|
||||
if (Rem > NumBytes) {
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
} else {
|
||||
//
|
||||
// We reach the end of the buffer, so need to wrap around
|
||||
//
|
||||
memcpy(pRing->pBuffer + WrOff, pData, Rem);
|
||||
memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
NumBytes -= Rem;
|
||||
WrOff = NumBytes;
|
||||
do {
|
||||
*pDst++ = *pData++;
|
||||
} while (--Rem);
|
||||
pDst = pRing->pBuffer;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, Rem);
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytes - Rem);
|
||||
pRing->WrOff = NumBytes - Rem;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
Avail = RdOff - WrOff - 1u;
|
||||
if (Avail >= NumBytes) {
|
||||
memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
#if SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||
pDst = pRing->pBuffer + WrOff;
|
||||
WrOff += NumBytes;
|
||||
while (NumBytes--) {
|
||||
*pDst++ = *pData++;
|
||||
};
|
||||
pRing->WrOff = WrOff;
|
||||
#else
|
||||
SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||
pRing->WrOff = WrOff + NumBytes;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -715,7 +871,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
|
||||
* (1) Data is stored according to buffer flags.
|
||||
* (2) For performance reasons this function does not call Init()
|
||||
* and may only be called after RTT has been initialized.
|
||||
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
|
||||
@ -789,7 +945,7 @@ unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsig
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
|
||||
* (1) Data is stored according to buffer flags.
|
||||
*/
|
||||
unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
|
||||
unsigned Status;
|
||||
@ -824,8 +980,7 @@ unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned Nu
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, depending on configuration,
|
||||
* remaining characters may be dropped or RTT module waits until there is more space in the buffer.
|
||||
* (1) Data is stored according to buffer flags.
|
||||
* (2) String passed to this function has to be \0 terminated
|
||||
* (3) \0 termination character is *not* stored in RTT buffer
|
||||
*/
|
||||
@ -836,6 +991,178 @@ unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
|
||||
return SEGGER_RTT_Write(BufferIndex, s, Len);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_PutCharSkipNoLock
|
||||
*
|
||||
* Function description
|
||||
* Stores a single character/byte in SEGGER RTT buffer.
|
||||
* SEGGER_RTT_PutCharSkipNoLock does not lock the application and
|
||||
* skips the byte, if it does not fit into the buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* c Byte to be stored.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, the character is dropped.
|
||||
* (2) For performance reasons this function does not call Init()
|
||||
* and may only be called after RTT has been initialized.
|
||||
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
|
||||
*/
|
||||
|
||||
unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned WrOff;
|
||||
unsigned Status;
|
||||
//
|
||||
// Get "to-host" ring buffer.
|
||||
//
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
//
|
||||
// Get write position and handle wrap-around if necessary
|
||||
//
|
||||
WrOff = pRing->WrOff + 1;
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0;
|
||||
}
|
||||
//
|
||||
// Output byte if free space is available
|
||||
//
|
||||
if (WrOff != pRing->RdOff) {
|
||||
pRing->pBuffer[pRing->WrOff] = c;
|
||||
pRing->WrOff = WrOff;
|
||||
Status = 1;
|
||||
} else {
|
||||
Status = 0;
|
||||
}
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_PutCharSkip
|
||||
*
|
||||
* Function description
|
||||
* Stores a single character/byte in SEGGER RTT buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* c Byte to be stored.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, the character is dropped.
|
||||
*/
|
||||
|
||||
unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned WrOff;
|
||||
unsigned Status;
|
||||
//
|
||||
// Prepare
|
||||
//
|
||||
INIT();
|
||||
SEGGER_RTT_LOCK();
|
||||
//
|
||||
// Get "to-host" ring buffer.
|
||||
//
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
//
|
||||
// Get write position and handle wrap-around if necessary
|
||||
//
|
||||
WrOff = pRing->WrOff + 1;
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0;
|
||||
}
|
||||
//
|
||||
// Output byte if free space is available
|
||||
//
|
||||
if (WrOff != pRing->RdOff) {
|
||||
pRing->pBuffer[pRing->WrOff] = c;
|
||||
pRing->WrOff = WrOff;
|
||||
Status = 1;
|
||||
} else {
|
||||
Status = 0;
|
||||
}
|
||||
//
|
||||
// Finish up.
|
||||
//
|
||||
SEGGER_RTT_UNLOCK();
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_PutChar
|
||||
*
|
||||
* Function description
|
||||
* Stores a single character/byte in SEGGER RTT buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* c Byte to be stored.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) Data is stored according to buffer flags.
|
||||
*/
|
||||
|
||||
unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned WrOff;
|
||||
unsigned Status;
|
||||
//
|
||||
// Prepare
|
||||
//
|
||||
INIT();
|
||||
SEGGER_RTT_LOCK();
|
||||
//
|
||||
// Get "to-host" ring buffer.
|
||||
//
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
//
|
||||
// Get write position and handle wrap-around if necessary
|
||||
//
|
||||
WrOff = pRing->WrOff + 1;
|
||||
if (WrOff == pRing->SizeOfBuffer) {
|
||||
WrOff = 0;
|
||||
}
|
||||
//
|
||||
// Wait for free space if mode is set to blocking
|
||||
//
|
||||
if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
|
||||
while (WrOff == pRing->RdOff) {
|
||||
;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Output byte if free space is available
|
||||
//
|
||||
if (WrOff != pRing->RdOff) {
|
||||
pRing->pBuffer[pRing->WrOff] = c;
|
||||
pRing->WrOff = WrOff;
|
||||
Status = 1;
|
||||
} else {
|
||||
Status = 0;
|
||||
}
|
||||
//
|
||||
// Finish up.
|
||||
//
|
||||
SEGGER_RTT_UNLOCK();
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_GetKey
|
||||
@ -937,6 +1264,27 @@ unsigned SEGGER_RTT_HasData(unsigned BufferIndex) {
|
||||
return v - pRing->RdOff;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_HasDataUp
|
||||
*
|
||||
* Function description
|
||||
* Check if there is data remaining to be sent in the given buffer.
|
||||
*
|
||||
* Return value:
|
||||
* ==0: No data
|
||||
* !=0: Data in buffer
|
||||
*
|
||||
*/
|
||||
unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) {
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned v;
|
||||
|
||||
pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||
v = pRing->RdOff;
|
||||
return pRing->WrOff - v;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_AllocDownBuffer
|
||||
@ -970,7 +1318,7 @@ int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned Buffer
|
||||
} while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers);
|
||||
if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) {
|
||||
_SEGGER_RTT.aDown[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
|
||||
@ -1015,7 +1363,7 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi
|
||||
} while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers);
|
||||
if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) {
|
||||
_SEGGER_RTT.aUp[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
|
||||
@ -1046,6 +1394,11 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi
|
||||
* Return value
|
||||
* >= 0 - O.K.
|
||||
* < 0 - Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
int r;
|
||||
@ -1055,7 +1408,7 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu
|
||||
SEGGER_RTT_LOCK();
|
||||
if (BufferIndex > 0u) {
|
||||
_SEGGER_RTT.aUp[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
|
||||
@ -1088,6 +1441,11 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
int r;
|
||||
@ -1097,7 +1455,7 @@ int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* p
|
||||
SEGGER_RTT_LOCK();
|
||||
if (BufferIndex > 0u) {
|
||||
_SEGGER_RTT.aDown[BufferIndex].sName = sName;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
|
||||
_SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
|
||||
_SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
|
||||
_SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
|
||||
@ -1173,6 +1531,68 @@ int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_SetFlagsUpBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of specific up-buffer flags (T->H).
|
||||
* Buffer to be configured is specified by index.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer.
|
||||
* Flags Flags to set for the buffer.
|
||||
*
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*/
|
||||
int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) {
|
||||
int r;
|
||||
|
||||
INIT();
|
||||
if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
|
||||
SEGGER_RTT_LOCK();
|
||||
_SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
|
||||
SEGGER_RTT_UNLOCK();
|
||||
r = 0;
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_SetFlagsDownBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of specific Down-buffer flags (T->H).
|
||||
* Buffer to be configured is specified by index.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer to renamed.
|
||||
* Flags Flags to set for the buffer.
|
||||
*
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*/
|
||||
int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
|
||||
int r;
|
||||
|
||||
INIT();
|
||||
if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
|
||||
SEGGER_RTT_LOCK();
|
||||
_SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
|
||||
SEGGER_RTT_UNLOCK();
|
||||
r = 0;
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_Init
|
||||
@ -1201,7 +1621,7 @@ void SEGGER_RTT_Init (void) {
|
||||
* < 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)
|
||||
*/
|
||||
int SEGGER_RTT_SetTerminal (char TerminalId) {
|
||||
char ac[2];
|
||||
unsigned char ac[2];
|
||||
SEGGER_RTT_BUFFER_UP* pRing;
|
||||
unsigned Avail;
|
||||
int r;
|
||||
@ -1209,19 +1629,19 @@ int SEGGER_RTT_SetTerminal (char TerminalId) {
|
||||
INIT();
|
||||
//
|
||||
r = 0;
|
||||
ac[0] = 0xFFU;
|
||||
ac[0] = 0xFFu;
|
||||
if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels
|
||||
ac[1] = _aTerminalId[(unsigned char)TerminalId];
|
||||
pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed
|
||||
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
|
||||
if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
|
||||
_ActiveTerminal = TerminalId;
|
||||
_WriteBlocking(pRing, ac, 2u);
|
||||
_WriteBlocking(pRing, (const char*)ac, 2u);
|
||||
} else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes
|
||||
Avail = _GetAvailWriteSpace(pRing);
|
||||
if (Avail >= 2) {
|
||||
_ActiveTerminal = TerminalId; // Only change active terminal in case of success
|
||||
_WriteNoCheck(pRing, ac, 2u);
|
||||
_WriteNoCheck(pRing, (const char*)ac, 2u);
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
@ -1269,7 +1689,7 @@ int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) {
|
||||
// Need to be able to change terminal, write data, change back.
|
||||
// Compute the fixed and variable sizes.
|
||||
//
|
||||
FragLen = strlen(s);
|
||||
FragLen = STRLEN(s);
|
||||
//
|
||||
// How we output depends upon the mode...
|
||||
//
|
||||
|
@ -1,35 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
@ -40,15 +39,12 @@
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT.h
|
||||
Purpose : Implementation of SEGGER real-time transfer which allows
|
||||
real-time communication on targets which support debugger
|
||||
memory accesses while the CPU is running.
|
||||
Revision: $Rev: 12804 $
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -56,6 +52,8 @@ Purpose : Implementation of SEGGER real-time transfer which allows
|
||||
#define SEGGER_RTT_H
|
||||
|
||||
#include "SEGGER_RTT_Conf.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
@ -127,24 +125,30 @@ extern SEGGER_RTT_CB _SEGGER_RTT;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
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_GetKey (void);
|
||||
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
|
||||
int SEGGER_RTT_HasKey (void);
|
||||
void SEGGER_RTT_Init (void);
|
||||
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
|
||||
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
|
||||
int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_WaitKey (void);
|
||||
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
|
||||
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_GetKey (void);
|
||||
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
|
||||
int SEGGER_RTT_HasKey (void);
|
||||
unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex);
|
||||
void SEGGER_RTT_Init (void);
|
||||
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
|
||||
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
|
||||
int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags);
|
||||
int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags);
|
||||
int SEGGER_RTT_WaitKey (void);
|
||||
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
|
||||
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c);
|
||||
unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c);
|
||||
unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c);
|
||||
//
|
||||
// Function macro for performance optimization
|
||||
//
|
||||
@ -166,6 +170,8 @@ int SEGGER_RTT_TerminalOut (char TerminalId, const char* s);
|
||||
**********************************************************************
|
||||
*/
|
||||
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
|
||||
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -189,44 +195,44 @@ int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
|
||||
// Control sequences, based on ANSI.
|
||||
// Can be used to control color, and clear the screen
|
||||
//
|
||||
#define RTT_CTRL_RESET "[0m" // Reset to default colors
|
||||
#define RTT_CTRL_CLEAR "[2J" // Clear screen, reposition cursor to top left
|
||||
#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors
|
||||
#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left
|
||||
|
||||
#define RTT_CTRL_TEXT_BLACK "[2;30m"
|
||||
#define RTT_CTRL_TEXT_RED "[2;31m"
|
||||
#define RTT_CTRL_TEXT_GREEN "[2;32m"
|
||||
#define RTT_CTRL_TEXT_YELLOW "[2;33m"
|
||||
#define RTT_CTRL_TEXT_BLUE "[2;34m"
|
||||
#define RTT_CTRL_TEXT_MAGENTA "[2;35m"
|
||||
#define RTT_CTRL_TEXT_CYAN "[2;36m"
|
||||
#define RTT_CTRL_TEXT_WHITE "[2;37m"
|
||||
#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m"
|
||||
#define RTT_CTRL_TEXT_RED "\x1B[2;31m"
|
||||
#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m"
|
||||
#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m"
|
||||
#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m"
|
||||
#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m"
|
||||
#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m"
|
||||
#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m"
|
||||
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLACK "[1;30m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_RED "[1;31m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_GREEN "[1;32m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "[1;33m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLUE "[1;34m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "[1;35m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_CYAN "[1;36m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_WHITE "[1;37m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m"
|
||||
|
||||
#define RTT_CTRL_BG_BLACK "[24;40m"
|
||||
#define RTT_CTRL_BG_RED "[24;41m"
|
||||
#define RTT_CTRL_BG_GREEN "[24;42m"
|
||||
#define RTT_CTRL_BG_YELLOW "[24;43m"
|
||||
#define RTT_CTRL_BG_BLUE "[24;44m"
|
||||
#define RTT_CTRL_BG_MAGENTA "[24;45m"
|
||||
#define RTT_CTRL_BG_CYAN "[24;46m"
|
||||
#define RTT_CTRL_BG_WHITE "[24;47m"
|
||||
#define RTT_CTRL_BG_BLACK "\x1B[24;40m"
|
||||
#define RTT_CTRL_BG_RED "\x1B[24;41m"
|
||||
#define RTT_CTRL_BG_GREEN "\x1B[24;42m"
|
||||
#define RTT_CTRL_BG_YELLOW "\x1B[24;43m"
|
||||
#define RTT_CTRL_BG_BLUE "\x1B[24;44m"
|
||||
#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m"
|
||||
#define RTT_CTRL_BG_CYAN "\x1B[24;46m"
|
||||
#define RTT_CTRL_BG_WHITE "\x1B[24;47m"
|
||||
|
||||
#define RTT_CTRL_BG_BRIGHT_BLACK "[4;40m"
|
||||
#define RTT_CTRL_BG_BRIGHT_RED "[4;41m"
|
||||
#define RTT_CTRL_BG_BRIGHT_GREEN "[4;42m"
|
||||
#define RTT_CTRL_BG_BRIGHT_YELLOW "[4;43m"
|
||||
#define RTT_CTRL_BG_BRIGHT_BLUE "[4;44m"
|
||||
#define RTT_CTRL_BG_BRIGHT_MAGENTA "[4;45m"
|
||||
#define RTT_CTRL_BG_BRIGHT_CYAN "[4;46m"
|
||||
#define RTT_CTRL_BG_BRIGHT_WHITE "[4;47m"
|
||||
#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m"
|
||||
#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m"
|
||||
#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m"
|
||||
#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m"
|
||||
#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m"
|
||||
#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m"
|
||||
#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m"
|
||||
#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m"
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,35 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
@ -40,22 +39,19 @@
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 12804 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_CONF_H
|
||||
#define SEGGER_RTT_CONF_H
|
||||
|
||||
#ifdef __ICCARM__
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
@ -76,47 +72,67 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT memcpy configuration
|
||||
*
|
||||
* memcpy() is good for large amounts of data,
|
||||
* but the overhead is big for small amounts, which are usually stored via RTT.
|
||||
* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead.
|
||||
*
|
||||
* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions.
|
||||
* This is may be required with memory access restrictions,
|
||||
* such as on Cortex-A devices with MMU.
|
||||
*/
|
||||
#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop
|
||||
//
|
||||
// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets
|
||||
//
|
||||
//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__))
|
||||
// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes))
|
||||
//#endif
|
||||
|
||||
//
|
||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||
//
|
||||
//
|
||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||
// (Higher priority = lower priority number)
|
||||
// Default value for embOS: 128u
|
||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
// In case of doubt mask all interrupts: 0u
|
||||
//
|
||||
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||
//
|
||||
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* Rowley CrossStudio and GCC
|
||||
*/
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) || (defined __clang__)
|
||||
#if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, primask \n\t" \
|
||||
"mov r1, $1 \n\t" \
|
||||
"movs r1, $1 \n\t" \
|
||||
"msr primask, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
}
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
@ -128,15 +144,15 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
: "=r" (LockState) \
|
||||
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__ARM_ARCH_7A__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
@ -161,7 +177,7 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
); \
|
||||
}
|
||||
#else
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
#endif
|
||||
@ -175,8 +191,8 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
|
||||
@ -186,13 +202,41 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_BASEPRI(); \
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RX
|
||||
*/
|
||||
#ifdef __ICCRX__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned long LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RL78
|
||||
*/
|
||||
#ifdef __ICCRL78__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
__istate_t LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for KEIL ARM
|
||||
@ -226,6 +270,32 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for TI ARM
|
||||
*/
|
||||
#ifdef __TI_ARM__
|
||||
#if defined (__TI_ARM_V6M0__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() _set_interrupt_priority(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration fallback
|
||||
|
@ -1,31 +1,34 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
* SEGGER Microcontroller GmbH *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* (c) 2014 - 2018 SEGGER Microcontroller GmbH *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* - Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* - Neither the name of SEGGER Microcontroller GmbH *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* DISCLAIMED. *
|
||||
* IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
|
Loading…
x
Reference in New Issue
Block a user