Segger rtt lib

Dependents:   acnSensa_LIS acd52832_Indoor_Posit_Peripheral acd52832_Indoor_Posit_Central iBeacon acnsensa ... more

Committer:
jurica238814
Date:
Fri Sep 22 10:36:47 2017 +0000
Revision:
0:e61e7fc7cfe1
SEGER RTT library init commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jurica238814 0:e61e7fc7cfe1 1 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 2 * SEGGER MICROCONTROLLER GmbH & Co. KG *
jurica238814 0:e61e7fc7cfe1 3 * Solutions for real time microcontroller applications *
jurica238814 0:e61e7fc7cfe1 4 **********************************************************************
jurica238814 0:e61e7fc7cfe1 5 * *
jurica238814 0:e61e7fc7cfe1 6 * (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
jurica238814 0:e61e7fc7cfe1 7 * *
jurica238814 0:e61e7fc7cfe1 8 * www.segger.com Support: support@segger.com *
jurica238814 0:e61e7fc7cfe1 9 * *
jurica238814 0:e61e7fc7cfe1 10 **********************************************************************
jurica238814 0:e61e7fc7cfe1 11 * *
jurica238814 0:e61e7fc7cfe1 12 * All rights reserved. *
jurica238814 0:e61e7fc7cfe1 13 * *
jurica238814 0:e61e7fc7cfe1 14 * * This software may in its unmodified form be freely redistributed *
jurica238814 0:e61e7fc7cfe1 15 * in source form. *
jurica238814 0:e61e7fc7cfe1 16 * * The source code may be modified, provided the source code *
jurica238814 0:e61e7fc7cfe1 17 * retains the above copyright notice, this list of conditions and *
jurica238814 0:e61e7fc7cfe1 18 * the following disclaimer. *
jurica238814 0:e61e7fc7cfe1 19 * * Modified versions of this software in source or linkable form *
jurica238814 0:e61e7fc7cfe1 20 * may not be distributed without prior consent of SEGGER. *
jurica238814 0:e61e7fc7cfe1 21 * * This software may only be used for communication with SEGGER *
jurica238814 0:e61e7fc7cfe1 22 * J-Link debug probes. *
jurica238814 0:e61e7fc7cfe1 23 * *
jurica238814 0:e61e7fc7cfe1 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
jurica238814 0:e61e7fc7cfe1 25 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
jurica238814 0:e61e7fc7cfe1 26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
jurica238814 0:e61e7fc7cfe1 27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
jurica238814 0:e61e7fc7cfe1 28 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
jurica238814 0:e61e7fc7cfe1 29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
jurica238814 0:e61e7fc7cfe1 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
jurica238814 0:e61e7fc7cfe1 31 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
jurica238814 0:e61e7fc7cfe1 32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
jurica238814 0:e61e7fc7cfe1 33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
jurica238814 0:e61e7fc7cfe1 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
jurica238814 0:e61e7fc7cfe1 35 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
jurica238814 0:e61e7fc7cfe1 36 * DAMAGE. *
jurica238814 0:e61e7fc7cfe1 37 * *
jurica238814 0:e61e7fc7cfe1 38 **********************************************************************
jurica238814 0:e61e7fc7cfe1 39 ---------------------------END-OF-HEADER------------------------------
jurica238814 0:e61e7fc7cfe1 40 File : SEGGER_RTT.c
jurica238814 0:e61e7fc7cfe1 41 Purpose : Implementation of SEGGER real-time transfer (RTT) which
jurica238814 0:e61e7fc7cfe1 42 allows real-time communication on targets which support
jurica238814 0:e61e7fc7cfe1 43 debugger memory accesses while the CPU is running.
jurica238814 0:e61e7fc7cfe1 44
jurica238814 0:e61e7fc7cfe1 45 Additional information:
jurica238814 0:e61e7fc7cfe1 46 Type "int" is assumed to be 32-bits in size
jurica238814 0:e61e7fc7cfe1 47 H->T Host to target communication
jurica238814 0:e61e7fc7cfe1 48 T->H Target to host communication
jurica238814 0:e61e7fc7cfe1 49
jurica238814 0:e61e7fc7cfe1 50 RTT channel 0 is always present and reserved for Terminal usage.
jurica238814 0:e61e7fc7cfe1 51 Name is fixed to "Terminal"
jurica238814 0:e61e7fc7cfe1 52
jurica238814 0:e61e7fc7cfe1 53 Effective buffer size: SizeOfBuffer - 1
jurica238814 0:e61e7fc7cfe1 54
jurica238814 0:e61e7fc7cfe1 55 WrOff == RdOff: Buffer is empty
jurica238814 0:e61e7fc7cfe1 56 WrOff == (RdOff - 1): Buffer is full
jurica238814 0:e61e7fc7cfe1 57 WrOff > RdOff: Free space includes wrap-around
jurica238814 0:e61e7fc7cfe1 58 WrOff < RdOff: Used space includes wrap-around
jurica238814 0:e61e7fc7cfe1 59 (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0):
jurica238814 0:e61e7fc7cfe1 60 Buffer full and wrap-around after next byte
jurica238814 0:e61e7fc7cfe1 61
jurica238814 0:e61e7fc7cfe1 62
jurica238814 0:e61e7fc7cfe1 63 ----------------------------------------------------------------------
jurica238814 0:e61e7fc7cfe1 64 */
jurica238814 0:e61e7fc7cfe1 65
jurica238814 0:e61e7fc7cfe1 66 #include "SEGGER_RTT.h"
jurica238814 0:e61e7fc7cfe1 67
jurica238814 0:e61e7fc7cfe1 68 #include <string.h> // for memcpy
jurica238814 0:e61e7fc7cfe1 69
jurica238814 0:e61e7fc7cfe1 70 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 71 *
jurica238814 0:e61e7fc7cfe1 72 * Configuration, default values
jurica238814 0:e61e7fc7cfe1 73 *
jurica238814 0:e61e7fc7cfe1 74 **********************************************************************
jurica238814 0:e61e7fc7cfe1 75 */
jurica238814 0:e61e7fc7cfe1 76
jurica238814 0:e61e7fc7cfe1 77 #ifndef BUFFER_SIZE_UP
jurica238814 0:e61e7fc7cfe1 78 #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host
jurica238814 0:e61e7fc7cfe1 79 #endif
jurica238814 0:e61e7fc7cfe1 80
jurica238814 0:e61e7fc7cfe1 81 #ifndef BUFFER_SIZE_DOWN
jurica238814 0:e61e7fc7cfe1 82 #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input)
jurica238814 0:e61e7fc7cfe1 83 #endif
jurica238814 0:e61e7fc7cfe1 84
jurica238814 0:e61e7fc7cfe1 85 #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
jurica238814 0:e61e7fc7cfe1 86 #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target
jurica238814 0:e61e7fc7cfe1 87 #endif
jurica238814 0:e61e7fc7cfe1 88
jurica238814 0:e61e7fc7cfe1 89 #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
jurica238814 0:e61e7fc7cfe1 90 #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target
jurica238814 0:e61e7fc7cfe1 91 #endif
jurica238814 0:e61e7fc7cfe1 92
jurica238814 0:e61e7fc7cfe1 93 #ifndef SEGGER_RTT_BUFFER_SECTION
jurica238814 0:e61e7fc7cfe1 94 #if defined SEGGER_RTT_SECTION
jurica238814 0:e61e7fc7cfe1 95 #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
jurica238814 0:e61e7fc7cfe1 96 #endif
jurica238814 0:e61e7fc7cfe1 97 #endif
jurica238814 0:e61e7fc7cfe1 98
jurica238814 0:e61e7fc7cfe1 99 #ifndef SEGGER_RTT_MODE_DEFAULT
jurica238814 0:e61e7fc7cfe1 100 #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP
jurica238814 0:e61e7fc7cfe1 101 #endif
jurica238814 0:e61e7fc7cfe1 102
jurica238814 0:e61e7fc7cfe1 103 #ifndef SEGGER_RTT_LOCK
jurica238814 0:e61e7fc7cfe1 104 #define SEGGER_RTT_LOCK()
jurica238814 0:e61e7fc7cfe1 105 #endif
jurica238814 0:e61e7fc7cfe1 106
jurica238814 0:e61e7fc7cfe1 107 #ifndef SEGGER_RTT_UNLOCK
jurica238814 0:e61e7fc7cfe1 108 #define SEGGER_RTT_UNLOCK()
jurica238814 0:e61e7fc7cfe1 109 #endif
jurica238814 0:e61e7fc7cfe1 110
jurica238814 0:e61e7fc7cfe1 111 #ifndef STRLEN
jurica238814 0:e61e7fc7cfe1 112 #define STRLEN(a) strlen((a))
jurica238814 0:e61e7fc7cfe1 113 #endif
jurica238814 0:e61e7fc7cfe1 114
jurica238814 0:e61e7fc7cfe1 115 #ifndef MEMCPY
jurica238814 0:e61e7fc7cfe1 116 #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
jurica238814 0:e61e7fc7cfe1 117 #endif
jurica238814 0:e61e7fc7cfe1 118
jurica238814 0:e61e7fc7cfe1 119 #ifndef MIN
jurica238814 0:e61e7fc7cfe1 120 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
jurica238814 0:e61e7fc7cfe1 121 #endif
jurica238814 0:e61e7fc7cfe1 122
jurica238814 0:e61e7fc7cfe1 123 #ifndef MAX
jurica238814 0:e61e7fc7cfe1 124 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
jurica238814 0:e61e7fc7cfe1 125 #endif
jurica238814 0:e61e7fc7cfe1 126 //
jurica238814 0:e61e7fc7cfe1 127 // For some environments, NULL may not be defined until certain headers are included
jurica238814 0:e61e7fc7cfe1 128 //
jurica238814 0:e61e7fc7cfe1 129 #ifndef NULL
jurica238814 0:e61e7fc7cfe1 130 #define NULL 0
jurica238814 0:e61e7fc7cfe1 131 #endif
jurica238814 0:e61e7fc7cfe1 132
jurica238814 0:e61e7fc7cfe1 133 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 134 *
jurica238814 0:e61e7fc7cfe1 135 * Static const data
jurica238814 0:e61e7fc7cfe1 136 *
jurica238814 0:e61e7fc7cfe1 137 **********************************************************************
jurica238814 0:e61e7fc7cfe1 138 */
jurica238814 0:e61e7fc7cfe1 139
jurica238814 0:e61e7fc7cfe1 140 static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
jurica238814 0:e61e7fc7cfe1 141
jurica238814 0:e61e7fc7cfe1 142 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 143 *
jurica238814 0:e61e7fc7cfe1 144 * Static data
jurica238814 0:e61e7fc7cfe1 145 *
jurica238814 0:e61e7fc7cfe1 146 **********************************************************************
jurica238814 0:e61e7fc7cfe1 147 */
jurica238814 0:e61e7fc7cfe1 148 //
jurica238814 0:e61e7fc7cfe1 149 // RTT Control Block and allocate buffers for channel 0
jurica238814 0:e61e7fc7cfe1 150 //
jurica238814 0:e61e7fc7cfe1 151 #ifdef SEGGER_RTT_SECTION
jurica238814 0:e61e7fc7cfe1 152 #if (defined __GNUC__)
jurica238814 0:e61e7fc7cfe1 153 __attribute__ ((section (SEGGER_RTT_SECTION))) SEGGER_RTT_CB _SEGGER_RTT;
jurica238814 0:e61e7fc7cfe1 154 #elif (defined __ICCARM__) || (defined __ICCRX__)
jurica238814 0:e61e7fc7cfe1 155 #pragma location=SEGGER_RTT_SECTION
jurica238814 0:e61e7fc7cfe1 156 SEGGER_RTT_CB _SEGGER_RTT;
jurica238814 0:e61e7fc7cfe1 157 #elif (defined __CC_ARM__)
jurica238814 0:e61e7fc7cfe1 158 __attribute__ ((section (SEGGER_RTT_SECTION), zero_init)) SEGGER_RTT_CB _SEGGER_RTT;
jurica238814 0:e61e7fc7cfe1 159 #else
jurica238814 0:e61e7fc7cfe1 160 SEGGER_RTT_CB _SEGGER_RTT;
jurica238814 0:e61e7fc7cfe1 161 #endif
jurica238814 0:e61e7fc7cfe1 162 #else
jurica238814 0:e61e7fc7cfe1 163 SEGGER_RTT_CB _SEGGER_RTT;
jurica238814 0:e61e7fc7cfe1 164 #endif
jurica238814 0:e61e7fc7cfe1 165
jurica238814 0:e61e7fc7cfe1 166 #ifdef SEGGER_RTT_BUFFER_SECTION
jurica238814 0:e61e7fc7cfe1 167 #if (defined __GNUC__)
jurica238814 0:e61e7fc7cfe1 168 __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acUpBuffer [BUFFER_SIZE_UP];
jurica238814 0:e61e7fc7cfe1 169 __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acDownBuffer[BUFFER_SIZE_DOWN];
jurica238814 0:e61e7fc7cfe1 170 #elif (defined __ICCARM__) || (defined __ICCRX__)
jurica238814 0:e61e7fc7cfe1 171 #pragma location=SEGGER_RTT_BUFFER_SECTION
jurica238814 0:e61e7fc7cfe1 172 static char _acUpBuffer [BUFFER_SIZE_UP];
jurica238814 0:e61e7fc7cfe1 173 #pragma location=SEGGER_RTT_BUFFER_SECTION
jurica238814 0:e61e7fc7cfe1 174 static char _acDownBuffer[BUFFER_SIZE_DOWN];
jurica238814 0:e61e7fc7cfe1 175 #elif (defined __CC_ARM__)
jurica238814 0:e61e7fc7cfe1 176 __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acUpBuffer [BUFFER_SIZE_UP];
jurica238814 0:e61e7fc7cfe1 177 __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acDownBuffer[BUFFER_SIZE_DOWN];
jurica238814 0:e61e7fc7cfe1 178 #else
jurica238814 0:e61e7fc7cfe1 179 static char _acUpBuffer [BUFFER_SIZE_UP];
jurica238814 0:e61e7fc7cfe1 180 static char _acDownBuffer[BUFFER_SIZE_DOWN];
jurica238814 0:e61e7fc7cfe1 181 #endif
jurica238814 0:e61e7fc7cfe1 182 #else
jurica238814 0:e61e7fc7cfe1 183 static char _acUpBuffer [BUFFER_SIZE_UP];
jurica238814 0:e61e7fc7cfe1 184 static char _acDownBuffer[BUFFER_SIZE_DOWN];
jurica238814 0:e61e7fc7cfe1 185 #endif
jurica238814 0:e61e7fc7cfe1 186
jurica238814 0:e61e7fc7cfe1 187 static char _ActiveTerminal;
jurica238814 0:e61e7fc7cfe1 188
jurica238814 0:e61e7fc7cfe1 189 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 190 *
jurica238814 0:e61e7fc7cfe1 191 * Static functions
jurica238814 0:e61e7fc7cfe1 192 *
jurica238814 0:e61e7fc7cfe1 193 **********************************************************************
jurica238814 0:e61e7fc7cfe1 194 */
jurica238814 0:e61e7fc7cfe1 195
jurica238814 0:e61e7fc7cfe1 196 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 197 *
jurica238814 0:e61e7fc7cfe1 198 * _DoInit()
jurica238814 0:e61e7fc7cfe1 199 *
jurica238814 0:e61e7fc7cfe1 200 * Function description
jurica238814 0:e61e7fc7cfe1 201 * Initializes the control block an buffers.
jurica238814 0:e61e7fc7cfe1 202 * May only be called via INIT() to avoid overriding settings.
jurica238814 0:e61e7fc7cfe1 203 *
jurica238814 0:e61e7fc7cfe1 204 */
jurica238814 0:e61e7fc7cfe1 205 #define INIT() do { \
jurica238814 0:e61e7fc7cfe1 206 if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \
jurica238814 0:e61e7fc7cfe1 207 } while (0)
jurica238814 0:e61e7fc7cfe1 208 static void _DoInit(void) {
jurica238814 0:e61e7fc7cfe1 209 SEGGER_RTT_CB* p;
jurica238814 0:e61e7fc7cfe1 210 //
jurica238814 0:e61e7fc7cfe1 211 // Initialize control block
jurica238814 0:e61e7fc7cfe1 212 //
jurica238814 0:e61e7fc7cfe1 213 p = &_SEGGER_RTT;
jurica238814 0:e61e7fc7cfe1 214 p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS;
jurica238814 0:e61e7fc7cfe1 215 p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS;
jurica238814 0:e61e7fc7cfe1 216 //
jurica238814 0:e61e7fc7cfe1 217 // Initialize up buffer 0
jurica238814 0:e61e7fc7cfe1 218 //
jurica238814 0:e61e7fc7cfe1 219 p->aUp[0].sName = "Terminal";
jurica238814 0:e61e7fc7cfe1 220 p->aUp[0].pBuffer = _acUpBuffer;
jurica238814 0:e61e7fc7cfe1 221 p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer);
jurica238814 0:e61e7fc7cfe1 222 p->aUp[0].RdOff = 0u;
jurica238814 0:e61e7fc7cfe1 223 p->aUp[0].WrOff = 0u;
jurica238814 0:e61e7fc7cfe1 224 p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT;
jurica238814 0:e61e7fc7cfe1 225 //
jurica238814 0:e61e7fc7cfe1 226 // Initialize down buffer 0
jurica238814 0:e61e7fc7cfe1 227 //
jurica238814 0:e61e7fc7cfe1 228 p->aDown[0].sName = "Terminal";
jurica238814 0:e61e7fc7cfe1 229 p->aDown[0].pBuffer = _acDownBuffer;
jurica238814 0:e61e7fc7cfe1 230 p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer);
jurica238814 0:e61e7fc7cfe1 231 p->aDown[0].RdOff = 0u;
jurica238814 0:e61e7fc7cfe1 232 p->aDown[0].WrOff = 0u;
jurica238814 0:e61e7fc7cfe1 233 p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT;
jurica238814 0:e61e7fc7cfe1 234 //
jurica238814 0:e61e7fc7cfe1 235 // Finish initialization of the control block.
jurica238814 0:e61e7fc7cfe1 236 // Copy Id string in three steps to make sure "SEGGER RTT" is not found
jurica238814 0:e61e7fc7cfe1 237 // in initializer memory (usually flash) by J-Link
jurica238814 0:e61e7fc7cfe1 238 //
jurica238814 0:e61e7fc7cfe1 239 strcpy(&p->acID[7], "RTT");
jurica238814 0:e61e7fc7cfe1 240 strcpy(&p->acID[0], "SEGGER");
jurica238814 0:e61e7fc7cfe1 241 p->acID[6] = ' ';
jurica238814 0:e61e7fc7cfe1 242 }
jurica238814 0:e61e7fc7cfe1 243
jurica238814 0:e61e7fc7cfe1 244 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 245 *
jurica238814 0:e61e7fc7cfe1 246 * _WriteBlocking()
jurica238814 0:e61e7fc7cfe1 247 *
jurica238814 0:e61e7fc7cfe1 248 * Function description
jurica238814 0:e61e7fc7cfe1 249 * Stores a specified number of characters in SEGGER RTT ring buffer
jurica238814 0:e61e7fc7cfe1 250 * and updates the associated write pointer which is periodically
jurica238814 0:e61e7fc7cfe1 251 * read by the host.
jurica238814 0:e61e7fc7cfe1 252 * The caller is responsible for managing the write chunk sizes as
jurica238814 0:e61e7fc7cfe1 253 * _WriteBlocking() will block until all data has been posted successfully.
jurica238814 0:e61e7fc7cfe1 254 *
jurica238814 0:e61e7fc7cfe1 255 * Parameters
jurica238814 0:e61e7fc7cfe1 256 * pRing Ring buffer to post to.
jurica238814 0:e61e7fc7cfe1 257 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
jurica238814 0:e61e7fc7cfe1 258 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
jurica238814 0:e61e7fc7cfe1 259 *
jurica238814 0:e61e7fc7cfe1 260 * Return value
jurica238814 0:e61e7fc7cfe1 261 * >= 0 - Number of bytes written into buffer.
jurica238814 0:e61e7fc7cfe1 262 */
jurica238814 0:e61e7fc7cfe1 263 static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) {
jurica238814 0:e61e7fc7cfe1 264 unsigned NumBytesToWrite;
jurica238814 0:e61e7fc7cfe1 265 unsigned NumBytesWritten;
jurica238814 0:e61e7fc7cfe1 266 unsigned RdOff;
jurica238814 0:e61e7fc7cfe1 267 unsigned WrOff;
jurica238814 0:e61e7fc7cfe1 268 //
jurica238814 0:e61e7fc7cfe1 269 // Write data to buffer and handle wrap-around if necessary
jurica238814 0:e61e7fc7cfe1 270 //
jurica238814 0:e61e7fc7cfe1 271 NumBytesWritten = 0u;
jurica238814 0:e61e7fc7cfe1 272 WrOff = pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 273 do {
jurica238814 0:e61e7fc7cfe1 274 RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime
jurica238814 0:e61e7fc7cfe1 275 if (RdOff > WrOff) {
jurica238814 0:e61e7fc7cfe1 276 NumBytesToWrite = RdOff - WrOff - 1u;
jurica238814 0:e61e7fc7cfe1 277 } else {
jurica238814 0:e61e7fc7cfe1 278 NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u);
jurica238814 0:e61e7fc7cfe1 279 }
jurica238814 0:e61e7fc7cfe1 280 NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around
jurica238814 0:e61e7fc7cfe1 281 NumBytesToWrite = MIN(NumBytesToWrite, NumBytes);
jurica238814 0:e61e7fc7cfe1 282 memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite);
jurica238814 0:e61e7fc7cfe1 283 NumBytesWritten += NumBytesToWrite;
jurica238814 0:e61e7fc7cfe1 284 pBuffer += NumBytesToWrite;
jurica238814 0:e61e7fc7cfe1 285 NumBytes -= NumBytesToWrite;
jurica238814 0:e61e7fc7cfe1 286 WrOff += NumBytesToWrite;
jurica238814 0:e61e7fc7cfe1 287 if (WrOff == pRing->SizeOfBuffer) {
jurica238814 0:e61e7fc7cfe1 288 WrOff = 0u;
jurica238814 0:e61e7fc7cfe1 289 }
jurica238814 0:e61e7fc7cfe1 290 pRing->WrOff = WrOff;
jurica238814 0:e61e7fc7cfe1 291 } while (NumBytes);
jurica238814 0:e61e7fc7cfe1 292 //
jurica238814 0:e61e7fc7cfe1 293 return NumBytesWritten;
jurica238814 0:e61e7fc7cfe1 294 }
jurica238814 0:e61e7fc7cfe1 295
jurica238814 0:e61e7fc7cfe1 296 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 297 *
jurica238814 0:e61e7fc7cfe1 298 * _WriteNoCheck()
jurica238814 0:e61e7fc7cfe1 299 *
jurica238814 0:e61e7fc7cfe1 300 * Function description
jurica238814 0:e61e7fc7cfe1 301 * Stores a specified number of characters in SEGGER RTT ring buffer
jurica238814 0:e61e7fc7cfe1 302 * and updates the associated write pointer which is periodically
jurica238814 0:e61e7fc7cfe1 303 * read by the host.
jurica238814 0:e61e7fc7cfe1 304 * It is callers responsibility to make sure data actually fits in buffer.
jurica238814 0:e61e7fc7cfe1 305 *
jurica238814 0:e61e7fc7cfe1 306 * Parameters
jurica238814 0:e61e7fc7cfe1 307 * pRing Ring buffer to post to.
jurica238814 0:e61e7fc7cfe1 308 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
jurica238814 0:e61e7fc7cfe1 309 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
jurica238814 0:e61e7fc7cfe1 310 *
jurica238814 0:e61e7fc7cfe1 311 * Notes
jurica238814 0:e61e7fc7cfe1 312 * (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking
jurica238814 0:e61e7fc7cfe1 313 */
jurica238814 0:e61e7fc7cfe1 314 static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) {
jurica238814 0:e61e7fc7cfe1 315 unsigned NumBytesAtOnce;
jurica238814 0:e61e7fc7cfe1 316 unsigned WrOff;
jurica238814 0:e61e7fc7cfe1 317 unsigned Rem;
jurica238814 0:e61e7fc7cfe1 318
jurica238814 0:e61e7fc7cfe1 319 WrOff = pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 320 Rem = pRing->SizeOfBuffer - WrOff;
jurica238814 0:e61e7fc7cfe1 321 if (Rem > NumBytes) {
jurica238814 0:e61e7fc7cfe1 322 //
jurica238814 0:e61e7fc7cfe1 323 // All data fits before wrap around
jurica238814 0:e61e7fc7cfe1 324 //
jurica238814 0:e61e7fc7cfe1 325 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
jurica238814 0:e61e7fc7cfe1 326 pRing->WrOff = WrOff + NumBytes;
jurica238814 0:e61e7fc7cfe1 327 } else {
jurica238814 0:e61e7fc7cfe1 328 //
jurica238814 0:e61e7fc7cfe1 329 // We reach the end of the buffer, so need to wrap around
jurica238814 0:e61e7fc7cfe1 330 //
jurica238814 0:e61e7fc7cfe1 331 NumBytesAtOnce = Rem;
jurica238814 0:e61e7fc7cfe1 332 memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce);
jurica238814 0:e61e7fc7cfe1 333 NumBytesAtOnce = NumBytes - Rem;
jurica238814 0:e61e7fc7cfe1 334 memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce);
jurica238814 0:e61e7fc7cfe1 335 pRing->WrOff = NumBytesAtOnce;
jurica238814 0:e61e7fc7cfe1 336 }
jurica238814 0:e61e7fc7cfe1 337 }
jurica238814 0:e61e7fc7cfe1 338
jurica238814 0:e61e7fc7cfe1 339 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 340 *
jurica238814 0:e61e7fc7cfe1 341 * _PostTerminalSwitch()
jurica238814 0:e61e7fc7cfe1 342 *
jurica238814 0:e61e7fc7cfe1 343 * Function description
jurica238814 0:e61e7fc7cfe1 344 * Switch terminal to the given terminal ID. It is the caller's
jurica238814 0:e61e7fc7cfe1 345 * responsibility to ensure the terminal ID is correct and there is
jurica238814 0:e61e7fc7cfe1 346 * enough space in the buffer for this to complete successfully.
jurica238814 0:e61e7fc7cfe1 347 *
jurica238814 0:e61e7fc7cfe1 348 * Parameters
jurica238814 0:e61e7fc7cfe1 349 * pRing Ring buffer to post to.
jurica238814 0:e61e7fc7cfe1 350 * TerminalId Terminal ID to switch to.
jurica238814 0:e61e7fc7cfe1 351 */
jurica238814 0:e61e7fc7cfe1 352 static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) {
jurica238814 0:e61e7fc7cfe1 353 char ac[2];
jurica238814 0:e61e7fc7cfe1 354
jurica238814 0:e61e7fc7cfe1 355 ac[0] = 0xFFu;
jurica238814 0:e61e7fc7cfe1 356 ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit
jurica238814 0:e61e7fc7cfe1 357 _WriteBlocking(pRing, ac, 2u);
jurica238814 0:e61e7fc7cfe1 358 }
jurica238814 0:e61e7fc7cfe1 359
jurica238814 0:e61e7fc7cfe1 360 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 361 *
jurica238814 0:e61e7fc7cfe1 362 * _GetAvailWriteSpace()
jurica238814 0:e61e7fc7cfe1 363 *
jurica238814 0:e61e7fc7cfe1 364 * Function description
jurica238814 0:e61e7fc7cfe1 365 * Returns the number of bytes that can be written to the ring
jurica238814 0:e61e7fc7cfe1 366 * buffer without blocking.
jurica238814 0:e61e7fc7cfe1 367 *
jurica238814 0:e61e7fc7cfe1 368 * Parameters
jurica238814 0:e61e7fc7cfe1 369 * pRing Ring buffer to check.
jurica238814 0:e61e7fc7cfe1 370 *
jurica238814 0:e61e7fc7cfe1 371 * Return value
jurica238814 0:e61e7fc7cfe1 372 * Number of bytes that are free in the buffer.
jurica238814 0:e61e7fc7cfe1 373 */
jurica238814 0:e61e7fc7cfe1 374 static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) {
jurica238814 0:e61e7fc7cfe1 375 unsigned RdOff;
jurica238814 0:e61e7fc7cfe1 376 unsigned WrOff;
jurica238814 0:e61e7fc7cfe1 377 unsigned r;
jurica238814 0:e61e7fc7cfe1 378 //
jurica238814 0:e61e7fc7cfe1 379 // Avoid warnings regarding volatile access order. It's not a problem
jurica238814 0:e61e7fc7cfe1 380 // in this case, but dampen compiler enthusiasm.
jurica238814 0:e61e7fc7cfe1 381 //
jurica238814 0:e61e7fc7cfe1 382 RdOff = pRing->RdOff;
jurica238814 0:e61e7fc7cfe1 383 WrOff = pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 384 if (RdOff <= WrOff) {
jurica238814 0:e61e7fc7cfe1 385 r = pRing->SizeOfBuffer - 1u - WrOff + RdOff;
jurica238814 0:e61e7fc7cfe1 386 } else {
jurica238814 0:e61e7fc7cfe1 387 r = RdOff - WrOff - 1u;
jurica238814 0:e61e7fc7cfe1 388 }
jurica238814 0:e61e7fc7cfe1 389 return r;
jurica238814 0:e61e7fc7cfe1 390 }
jurica238814 0:e61e7fc7cfe1 391
jurica238814 0:e61e7fc7cfe1 392 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 393 *
jurica238814 0:e61e7fc7cfe1 394 * Public code
jurica238814 0:e61e7fc7cfe1 395 *
jurica238814 0:e61e7fc7cfe1 396 **********************************************************************
jurica238814 0:e61e7fc7cfe1 397 */
jurica238814 0:e61e7fc7cfe1 398 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 399 *
jurica238814 0:e61e7fc7cfe1 400 * SEGGER_RTT_ReadNoLock()
jurica238814 0:e61e7fc7cfe1 401 *
jurica238814 0:e61e7fc7cfe1 402 * Function description
jurica238814 0:e61e7fc7cfe1 403 * Reads characters from SEGGER real-time-terminal control block
jurica238814 0:e61e7fc7cfe1 404 * which have been previously stored by the host.
jurica238814 0:e61e7fc7cfe1 405 * Do not lock against interrupts and multiple access.
jurica238814 0:e61e7fc7cfe1 406 *
jurica238814 0:e61e7fc7cfe1 407 * Parameters
jurica238814 0:e61e7fc7cfe1 408 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
jurica238814 0:e61e7fc7cfe1 409 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
jurica238814 0:e61e7fc7cfe1 410 * BufferSize Size of the target application buffer.
jurica238814 0:e61e7fc7cfe1 411 *
jurica238814 0:e61e7fc7cfe1 412 * Return value
jurica238814 0:e61e7fc7cfe1 413 * Number of bytes that have been read.
jurica238814 0:e61e7fc7cfe1 414 */
jurica238814 0:e61e7fc7cfe1 415 unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
jurica238814 0:e61e7fc7cfe1 416 unsigned NumBytesRem;
jurica238814 0:e61e7fc7cfe1 417 unsigned NumBytesRead;
jurica238814 0:e61e7fc7cfe1 418 unsigned RdOff;
jurica238814 0:e61e7fc7cfe1 419 unsigned WrOff;
jurica238814 0:e61e7fc7cfe1 420 unsigned char* pBuffer;
jurica238814 0:e61e7fc7cfe1 421 SEGGER_RTT_BUFFER_DOWN* pRing;
jurica238814 0:e61e7fc7cfe1 422 //
jurica238814 0:e61e7fc7cfe1 423 INIT();
jurica238814 0:e61e7fc7cfe1 424 pRing = &_SEGGER_RTT.aDown[BufferIndex];
jurica238814 0:e61e7fc7cfe1 425 pBuffer = (unsigned char*)pData;
jurica238814 0:e61e7fc7cfe1 426 RdOff = pRing->RdOff;
jurica238814 0:e61e7fc7cfe1 427 WrOff = pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 428 NumBytesRead = 0u;
jurica238814 0:e61e7fc7cfe1 429 //
jurica238814 0:e61e7fc7cfe1 430 // Read from current read position to wrap-around of buffer, first
jurica238814 0:e61e7fc7cfe1 431 //
jurica238814 0:e61e7fc7cfe1 432 if (RdOff > WrOff) {
jurica238814 0:e61e7fc7cfe1 433 NumBytesRem = pRing->SizeOfBuffer - RdOff;
jurica238814 0:e61e7fc7cfe1 434 NumBytesRem = MIN(NumBytesRem, BufferSize);
jurica238814 0:e61e7fc7cfe1 435 memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
jurica238814 0:e61e7fc7cfe1 436 NumBytesRead += NumBytesRem;
jurica238814 0:e61e7fc7cfe1 437 pBuffer += NumBytesRem;
jurica238814 0:e61e7fc7cfe1 438 BufferSize -= NumBytesRem;
jurica238814 0:e61e7fc7cfe1 439 RdOff += NumBytesRem;
jurica238814 0:e61e7fc7cfe1 440 //
jurica238814 0:e61e7fc7cfe1 441 // Handle wrap-around of buffer
jurica238814 0:e61e7fc7cfe1 442 //
jurica238814 0:e61e7fc7cfe1 443 if (RdOff == pRing->SizeOfBuffer) {
jurica238814 0:e61e7fc7cfe1 444 RdOff = 0u;
jurica238814 0:e61e7fc7cfe1 445 }
jurica238814 0:e61e7fc7cfe1 446 }
jurica238814 0:e61e7fc7cfe1 447 //
jurica238814 0:e61e7fc7cfe1 448 // Read remaining items of buffer
jurica238814 0:e61e7fc7cfe1 449 //
jurica238814 0:e61e7fc7cfe1 450 NumBytesRem = WrOff - RdOff;
jurica238814 0:e61e7fc7cfe1 451 NumBytesRem = MIN(NumBytesRem, BufferSize);
jurica238814 0:e61e7fc7cfe1 452 if (NumBytesRem > 0u) {
jurica238814 0:e61e7fc7cfe1 453 memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
jurica238814 0:e61e7fc7cfe1 454 NumBytesRead += NumBytesRem;
jurica238814 0:e61e7fc7cfe1 455 pBuffer += NumBytesRem;
jurica238814 0:e61e7fc7cfe1 456 BufferSize -= NumBytesRem;
jurica238814 0:e61e7fc7cfe1 457 RdOff += NumBytesRem;
jurica238814 0:e61e7fc7cfe1 458 }
jurica238814 0:e61e7fc7cfe1 459 if (NumBytesRead) {
jurica238814 0:e61e7fc7cfe1 460 pRing->RdOff = RdOff;
jurica238814 0:e61e7fc7cfe1 461 }
jurica238814 0:e61e7fc7cfe1 462 //
jurica238814 0:e61e7fc7cfe1 463 return NumBytesRead;
jurica238814 0:e61e7fc7cfe1 464 }
jurica238814 0:e61e7fc7cfe1 465
jurica238814 0:e61e7fc7cfe1 466 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 467 *
jurica238814 0:e61e7fc7cfe1 468 * SEGGER_RTT_Read
jurica238814 0:e61e7fc7cfe1 469 *
jurica238814 0:e61e7fc7cfe1 470 * Function description
jurica238814 0:e61e7fc7cfe1 471 * Reads characters from SEGGER real-time-terminal control block
jurica238814 0:e61e7fc7cfe1 472 * which have been previously stored by the host.
jurica238814 0:e61e7fc7cfe1 473 *
jurica238814 0:e61e7fc7cfe1 474 * Parameters
jurica238814 0:e61e7fc7cfe1 475 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
jurica238814 0:e61e7fc7cfe1 476 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
jurica238814 0:e61e7fc7cfe1 477 * BufferSize Size of the target application buffer.
jurica238814 0:e61e7fc7cfe1 478 *
jurica238814 0:e61e7fc7cfe1 479 * Return value
jurica238814 0:e61e7fc7cfe1 480 * Number of bytes that have been read.
jurica238814 0:e61e7fc7cfe1 481 */
jurica238814 0:e61e7fc7cfe1 482 unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) {
jurica238814 0:e61e7fc7cfe1 483 unsigned NumBytesRead;
jurica238814 0:e61e7fc7cfe1 484 //
jurica238814 0:e61e7fc7cfe1 485 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 486 //
jurica238814 0:e61e7fc7cfe1 487 // Call the non-locking read function
jurica238814 0:e61e7fc7cfe1 488 //
jurica238814 0:e61e7fc7cfe1 489 NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize);
jurica238814 0:e61e7fc7cfe1 490 //
jurica238814 0:e61e7fc7cfe1 491 // Finish up.
jurica238814 0:e61e7fc7cfe1 492 //
jurica238814 0:e61e7fc7cfe1 493 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 494 //
jurica238814 0:e61e7fc7cfe1 495 return NumBytesRead;
jurica238814 0:e61e7fc7cfe1 496 }
jurica238814 0:e61e7fc7cfe1 497
jurica238814 0:e61e7fc7cfe1 498 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 499 *
jurica238814 0:e61e7fc7cfe1 500 * SEGGER_RTT_WriteWithOverwriteNoLock
jurica238814 0:e61e7fc7cfe1 501 *
jurica238814 0:e61e7fc7cfe1 502 * Function description
jurica238814 0:e61e7fc7cfe1 503 * Stores a specified number of characters in SEGGER RTT
jurica238814 0:e61e7fc7cfe1 504 * control block.
jurica238814 0:e61e7fc7cfe1 505 * SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application
jurica238814 0:e61e7fc7cfe1 506 * and overwrites data if the data does not fit into the buffer.
jurica238814 0:e61e7fc7cfe1 507 *
jurica238814 0:e61e7fc7cfe1 508 * Parameters
jurica238814 0:e61e7fc7cfe1 509 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
jurica238814 0:e61e7fc7cfe1 510 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
jurica238814 0:e61e7fc7cfe1 511 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
jurica238814 0:e61e7fc7cfe1 512 *
jurica238814 0:e61e7fc7cfe1 513 * Notes
jurica238814 0:e61e7fc7cfe1 514 * (1) If there is not enough space in the "Up"-buffer, data is overwritten.
jurica238814 0:e61e7fc7cfe1 515 * (2) For performance reasons this function does not call Init()
jurica238814 0:e61e7fc7cfe1 516 * and may only be called after RTT has been initialized.
jurica238814 0:e61e7fc7cfe1 517 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
jurica238814 0:e61e7fc7cfe1 518 * (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link
jurica238814 0:e61e7fc7cfe1 519 * connection reads RTT data.
jurica238814 0:e61e7fc7cfe1 520 */
jurica238814 0:e61e7fc7cfe1 521 void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
jurica238814 0:e61e7fc7cfe1 522 const char* pData;
jurica238814 0:e61e7fc7cfe1 523 SEGGER_RTT_BUFFER_UP* pRing;
jurica238814 0:e61e7fc7cfe1 524 unsigned Avail;
jurica238814 0:e61e7fc7cfe1 525
jurica238814 0:e61e7fc7cfe1 526 pData = (const char *)pBuffer;
jurica238814 0:e61e7fc7cfe1 527 //
jurica238814 0:e61e7fc7cfe1 528 // Get "to-host" ring buffer and copy some elements into local variables.
jurica238814 0:e61e7fc7cfe1 529 //
jurica238814 0:e61e7fc7cfe1 530 pRing = &_SEGGER_RTT.aUp[BufferIndex];
jurica238814 0:e61e7fc7cfe1 531 //
jurica238814 0:e61e7fc7cfe1 532 // Check if we will overwrite data and need to adjust the RdOff.
jurica238814 0:e61e7fc7cfe1 533 //
jurica238814 0:e61e7fc7cfe1 534 if (pRing->WrOff == pRing->RdOff) {
jurica238814 0:e61e7fc7cfe1 535 Avail = pRing->SizeOfBuffer - 1u;
jurica238814 0:e61e7fc7cfe1 536 } else if ( pRing->WrOff < pRing->RdOff) {
jurica238814 0:e61e7fc7cfe1 537 Avail = pRing->RdOff - pRing->WrOff - 1u;
jurica238814 0:e61e7fc7cfe1 538 } else {
jurica238814 0:e61e7fc7cfe1 539 Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer;
jurica238814 0:e61e7fc7cfe1 540 }
jurica238814 0:e61e7fc7cfe1 541 if (NumBytes > Avail) {
jurica238814 0:e61e7fc7cfe1 542 pRing->RdOff += (NumBytes - Avail);
jurica238814 0:e61e7fc7cfe1 543 while (pRing->RdOff >= pRing->SizeOfBuffer) {
jurica238814 0:e61e7fc7cfe1 544 pRing->RdOff -= pRing->SizeOfBuffer;
jurica238814 0:e61e7fc7cfe1 545 }
jurica238814 0:e61e7fc7cfe1 546 }
jurica238814 0:e61e7fc7cfe1 547 //
jurica238814 0:e61e7fc7cfe1 548 // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds
jurica238814 0:e61e7fc7cfe1 549 //
jurica238814 0:e61e7fc7cfe1 550 Avail = pRing->SizeOfBuffer - pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 551 do {
jurica238814 0:e61e7fc7cfe1 552 if (Avail > NumBytes) {
jurica238814 0:e61e7fc7cfe1 553 //
jurica238814 0:e61e7fc7cfe1 554 // Last round
jurica238814 0:e61e7fc7cfe1 555 //
jurica238814 0:e61e7fc7cfe1 556 #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.
jurica238814 0:e61e7fc7cfe1 557 char* pDst;
jurica238814 0:e61e7fc7cfe1 558 pDst = pRing->pBuffer + pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 559 pRing->WrOff += NumBytes;
jurica238814 0:e61e7fc7cfe1 560 do {
jurica238814 0:e61e7fc7cfe1 561 *pDst++ = *pData++;
jurica238814 0:e61e7fc7cfe1 562 } while (--NumBytes);
jurica238814 0:e61e7fc7cfe1 563 #else
jurica238814 0:e61e7fc7cfe1 564 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
jurica238814 0:e61e7fc7cfe1 565 pRing->WrOff += NumBytes;
jurica238814 0:e61e7fc7cfe1 566 #endif
jurica238814 0:e61e7fc7cfe1 567 break; //Alternatively: NumBytes = 0;
jurica238814 0:e61e7fc7cfe1 568 } else {
jurica238814 0:e61e7fc7cfe1 569 //
jurica238814 0:e61e7fc7cfe1 570 // Wrap-around necessary, write until wrap-around and reset WrOff
jurica238814 0:e61e7fc7cfe1 571 //
jurica238814 0:e61e7fc7cfe1 572 memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail);
jurica238814 0:e61e7fc7cfe1 573 pData += Avail;
jurica238814 0:e61e7fc7cfe1 574 pRing->WrOff = 0;
jurica238814 0:e61e7fc7cfe1 575 NumBytes -= Avail;
jurica238814 0:e61e7fc7cfe1 576 Avail = (pRing->SizeOfBuffer - 1);
jurica238814 0:e61e7fc7cfe1 577 }
jurica238814 0:e61e7fc7cfe1 578 } while (NumBytes);
jurica238814 0:e61e7fc7cfe1 579 }
jurica238814 0:e61e7fc7cfe1 580
jurica238814 0:e61e7fc7cfe1 581 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 582 *
jurica238814 0:e61e7fc7cfe1 583 * SEGGER_RTT_WriteSkipNoLock
jurica238814 0:e61e7fc7cfe1 584 *
jurica238814 0:e61e7fc7cfe1 585 * Function description
jurica238814 0:e61e7fc7cfe1 586 * Stores a specified number of characters in SEGGER RTT
jurica238814 0:e61e7fc7cfe1 587 * control block which is then read by the host.
jurica238814 0:e61e7fc7cfe1 588 * SEGGER_RTT_WriteSkipNoLock does not lock the application and
jurica238814 0:e61e7fc7cfe1 589 * skips all data, if the data does not fit into the buffer.
jurica238814 0:e61e7fc7cfe1 590 *
jurica238814 0:e61e7fc7cfe1 591 * Parameters
jurica238814 0:e61e7fc7cfe1 592 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
jurica238814 0:e61e7fc7cfe1 593 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
jurica238814 0:e61e7fc7cfe1 594 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
jurica238814 0:e61e7fc7cfe1 595 *
jurica238814 0:e61e7fc7cfe1 596 * Return value
jurica238814 0:e61e7fc7cfe1 597 * Number of bytes which have been stored in the "Up"-buffer.
jurica238814 0:e61e7fc7cfe1 598 *
jurica238814 0:e61e7fc7cfe1 599 * Notes
jurica238814 0:e61e7fc7cfe1 600 * (1) If there is not enough space in the "Up"-buffer, all data is dropped.
jurica238814 0:e61e7fc7cfe1 601 * (2) For performance reasons this function does not call Init()
jurica238814 0:e61e7fc7cfe1 602 * and may only be called after RTT has been initialized.
jurica238814 0:e61e7fc7cfe1 603 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
jurica238814 0:e61e7fc7cfe1 604 */
jurica238814 0:e61e7fc7cfe1 605 unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
jurica238814 0:e61e7fc7cfe1 606 const char* pData;
jurica238814 0:e61e7fc7cfe1 607 SEGGER_RTT_BUFFER_UP* pRing;
jurica238814 0:e61e7fc7cfe1 608 unsigned Avail;
jurica238814 0:e61e7fc7cfe1 609 unsigned RdOff;
jurica238814 0:e61e7fc7cfe1 610 unsigned WrOff;
jurica238814 0:e61e7fc7cfe1 611 unsigned Rem;
jurica238814 0:e61e7fc7cfe1 612
jurica238814 0:e61e7fc7cfe1 613 pData = (const char *)pBuffer;
jurica238814 0:e61e7fc7cfe1 614 //
jurica238814 0:e61e7fc7cfe1 615 // Get "to-host" ring buffer and copy some elements into local variables.
jurica238814 0:e61e7fc7cfe1 616 //
jurica238814 0:e61e7fc7cfe1 617 pRing = &_SEGGER_RTT.aUp[BufferIndex];
jurica238814 0:e61e7fc7cfe1 618 RdOff = pRing->RdOff;
jurica238814 0:e61e7fc7cfe1 619 WrOff = pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 620 //
jurica238814 0:e61e7fc7cfe1 621 // Handle the most common cases fastest.
jurica238814 0:e61e7fc7cfe1 622 // Which is:
jurica238814 0:e61e7fc7cfe1 623 // RdOff <= WrOff -> Space until wrap around is free.
jurica238814 0:e61e7fc7cfe1 624 // AND
jurica238814 0:e61e7fc7cfe1 625 // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary.
jurica238814 0:e61e7fc7cfe1 626 //
jurica238814 0:e61e7fc7cfe1 627 // OR
jurica238814 0:e61e7fc7cfe1 628 //
jurica238814 0:e61e7fc7cfe1 629 // RdOff > WrOff -> Space until RdOff - 1 is free.
jurica238814 0:e61e7fc7cfe1 630 // AND
jurica238814 0:e61e7fc7cfe1 631 // WrOff + NumBytes < RdOff -> Data fits into buffer
jurica238814 0:e61e7fc7cfe1 632 //
jurica238814 0:e61e7fc7cfe1 633 if (RdOff <= WrOff) {
jurica238814 0:e61e7fc7cfe1 634 //
jurica238814 0:e61e7fc7cfe1 635 // Get space until WrOff will be at wrap around.
jurica238814 0:e61e7fc7cfe1 636 //
jurica238814 0:e61e7fc7cfe1 637 Avail = pRing->SizeOfBuffer - 1u - WrOff ;
jurica238814 0:e61e7fc7cfe1 638 if (Avail >= NumBytes) {
jurica238814 0:e61e7fc7cfe1 639 #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.
jurica238814 0:e61e7fc7cfe1 640 char* pDst;
jurica238814 0:e61e7fc7cfe1 641 pDst = pRing->pBuffer + WrOff;
jurica238814 0:e61e7fc7cfe1 642 WrOff += NumBytes;
jurica238814 0:e61e7fc7cfe1 643 do {
jurica238814 0:e61e7fc7cfe1 644 *pDst++ = *pData++;
jurica238814 0:e61e7fc7cfe1 645 } while (--NumBytes);
jurica238814 0:e61e7fc7cfe1 646 pRing->WrOff = WrOff + NumBytes;
jurica238814 0:e61e7fc7cfe1 647 #else
jurica238814 0:e61e7fc7cfe1 648 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
jurica238814 0:e61e7fc7cfe1 649 pRing->WrOff = WrOff + NumBytes;
jurica238814 0:e61e7fc7cfe1 650 #endif
jurica238814 0:e61e7fc7cfe1 651 return 1;
jurica238814 0:e61e7fc7cfe1 652 }
jurica238814 0:e61e7fc7cfe1 653 //
jurica238814 0:e61e7fc7cfe1 654 // If data did not fit into space until wrap around calculate complete space in buffer.
jurica238814 0:e61e7fc7cfe1 655 //
jurica238814 0:e61e7fc7cfe1 656 Avail += RdOff;
jurica238814 0:e61e7fc7cfe1 657 //
jurica238814 0:e61e7fc7cfe1 658 // If there is still no space for the whole of this output, don't bother.
jurica238814 0:e61e7fc7cfe1 659 //
jurica238814 0:e61e7fc7cfe1 660 if (Avail >= NumBytes) {
jurica238814 0:e61e7fc7cfe1 661 //
jurica238814 0:e61e7fc7cfe1 662 // OK, we have enough space in buffer. Copy in one or 2 chunks
jurica238814 0:e61e7fc7cfe1 663 //
jurica238814 0:e61e7fc7cfe1 664 Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer
jurica238814 0:e61e7fc7cfe1 665 if (Rem > NumBytes) {
jurica238814 0:e61e7fc7cfe1 666 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
jurica238814 0:e61e7fc7cfe1 667 pRing->WrOff = WrOff + NumBytes;
jurica238814 0:e61e7fc7cfe1 668 } else {
jurica238814 0:e61e7fc7cfe1 669 //
jurica238814 0:e61e7fc7cfe1 670 // We reach the end of the buffer, so need to wrap around
jurica238814 0:e61e7fc7cfe1 671 //
jurica238814 0:e61e7fc7cfe1 672 memcpy(pRing->pBuffer + WrOff, pData, Rem);
jurica238814 0:e61e7fc7cfe1 673 memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem);
jurica238814 0:e61e7fc7cfe1 674 pRing->WrOff = NumBytes - Rem;
jurica238814 0:e61e7fc7cfe1 675 }
jurica238814 0:e61e7fc7cfe1 676 return 1;
jurica238814 0:e61e7fc7cfe1 677 }
jurica238814 0:e61e7fc7cfe1 678 } else {
jurica238814 0:e61e7fc7cfe1 679 Avail = RdOff - WrOff - 1u;
jurica238814 0:e61e7fc7cfe1 680 if (Avail >= NumBytes) {
jurica238814 0:e61e7fc7cfe1 681 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
jurica238814 0:e61e7fc7cfe1 682 pRing->WrOff = WrOff + NumBytes;
jurica238814 0:e61e7fc7cfe1 683 return 1;
jurica238814 0:e61e7fc7cfe1 684 }
jurica238814 0:e61e7fc7cfe1 685 }
jurica238814 0:e61e7fc7cfe1 686 //
jurica238814 0:e61e7fc7cfe1 687 // If we reach this point no data has been written
jurica238814 0:e61e7fc7cfe1 688 //
jurica238814 0:e61e7fc7cfe1 689 return 0;
jurica238814 0:e61e7fc7cfe1 690 }
jurica238814 0:e61e7fc7cfe1 691
jurica238814 0:e61e7fc7cfe1 692 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 693 *
jurica238814 0:e61e7fc7cfe1 694 * SEGGER_RTT_WriteNoLock
jurica238814 0:e61e7fc7cfe1 695 *
jurica238814 0:e61e7fc7cfe1 696 * Function description
jurica238814 0:e61e7fc7cfe1 697 * Stores a specified number of characters in SEGGER RTT
jurica238814 0:e61e7fc7cfe1 698 * control block which is then read by the host.
jurica238814 0:e61e7fc7cfe1 699 * SEGGER_RTT_WriteNoLock does not lock the application.
jurica238814 0:e61e7fc7cfe1 700 *
jurica238814 0:e61e7fc7cfe1 701 * Parameters
jurica238814 0:e61e7fc7cfe1 702 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
jurica238814 0:e61e7fc7cfe1 703 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
jurica238814 0:e61e7fc7cfe1 704 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
jurica238814 0:e61e7fc7cfe1 705 *
jurica238814 0:e61e7fc7cfe1 706 * Return value
jurica238814 0:e61e7fc7cfe1 707 * Number of bytes which have been stored in the "Up"-buffer.
jurica238814 0:e61e7fc7cfe1 708 *
jurica238814 0:e61e7fc7cfe1 709 * Notes
jurica238814 0:e61e7fc7cfe1 710 * (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
jurica238814 0:e61e7fc7cfe1 711 * (2) For performance reasons this function does not call Init()
jurica238814 0:e61e7fc7cfe1 712 * and may only be called after RTT has been initialized.
jurica238814 0:e61e7fc7cfe1 713 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
jurica238814 0:e61e7fc7cfe1 714 */
jurica238814 0:e61e7fc7cfe1 715 unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
jurica238814 0:e61e7fc7cfe1 716 unsigned Status;
jurica238814 0:e61e7fc7cfe1 717 unsigned Avail;
jurica238814 0:e61e7fc7cfe1 718 const char* pData;
jurica238814 0:e61e7fc7cfe1 719 SEGGER_RTT_BUFFER_UP* pRing;
jurica238814 0:e61e7fc7cfe1 720
jurica238814 0:e61e7fc7cfe1 721 pData = (const char *)pBuffer;
jurica238814 0:e61e7fc7cfe1 722 //
jurica238814 0:e61e7fc7cfe1 723 // Get "to-host" ring buffer.
jurica238814 0:e61e7fc7cfe1 724 //
jurica238814 0:e61e7fc7cfe1 725 pRing = &_SEGGER_RTT.aUp[BufferIndex];
jurica238814 0:e61e7fc7cfe1 726 //
jurica238814 0:e61e7fc7cfe1 727 // How we output depends upon the mode...
jurica238814 0:e61e7fc7cfe1 728 //
jurica238814 0:e61e7fc7cfe1 729 switch (pRing->Flags) {
jurica238814 0:e61e7fc7cfe1 730 case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
jurica238814 0:e61e7fc7cfe1 731 //
jurica238814 0:e61e7fc7cfe1 732 // If we are in skip mode and there is no space for the whole
jurica238814 0:e61e7fc7cfe1 733 // of this output, don't bother.
jurica238814 0:e61e7fc7cfe1 734 //
jurica238814 0:e61e7fc7cfe1 735 Avail = _GetAvailWriteSpace(pRing);
jurica238814 0:e61e7fc7cfe1 736 if (Avail < NumBytes) {
jurica238814 0:e61e7fc7cfe1 737 Status = 0u;
jurica238814 0:e61e7fc7cfe1 738 } else {
jurica238814 0:e61e7fc7cfe1 739 Status = NumBytes;
jurica238814 0:e61e7fc7cfe1 740 _WriteNoCheck(pRing, pData, NumBytes);
jurica238814 0:e61e7fc7cfe1 741 }
jurica238814 0:e61e7fc7cfe1 742 break;
jurica238814 0:e61e7fc7cfe1 743 case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
jurica238814 0:e61e7fc7cfe1 744 //
jurica238814 0:e61e7fc7cfe1 745 // If we are in trim mode, trim to what we can output without blocking.
jurica238814 0:e61e7fc7cfe1 746 //
jurica238814 0:e61e7fc7cfe1 747 Avail = _GetAvailWriteSpace(pRing);
jurica238814 0:e61e7fc7cfe1 748 Status = Avail < NumBytes ? Avail : NumBytes;
jurica238814 0:e61e7fc7cfe1 749 _WriteNoCheck(pRing, pData, Status);
jurica238814 0:e61e7fc7cfe1 750 break;
jurica238814 0:e61e7fc7cfe1 751 case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
jurica238814 0:e61e7fc7cfe1 752 //
jurica238814 0:e61e7fc7cfe1 753 // If we are in blocking mode, output everything.
jurica238814 0:e61e7fc7cfe1 754 //
jurica238814 0:e61e7fc7cfe1 755 Status = _WriteBlocking(pRing, pData, NumBytes);
jurica238814 0:e61e7fc7cfe1 756 break;
jurica238814 0:e61e7fc7cfe1 757 default:
jurica238814 0:e61e7fc7cfe1 758 Status = 0u;
jurica238814 0:e61e7fc7cfe1 759 break;
jurica238814 0:e61e7fc7cfe1 760 }
jurica238814 0:e61e7fc7cfe1 761 //
jurica238814 0:e61e7fc7cfe1 762 // Finish up.
jurica238814 0:e61e7fc7cfe1 763 //
jurica238814 0:e61e7fc7cfe1 764 return Status;
jurica238814 0:e61e7fc7cfe1 765 }
jurica238814 0:e61e7fc7cfe1 766
jurica238814 0:e61e7fc7cfe1 767 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 768 *
jurica238814 0:e61e7fc7cfe1 769 * SEGGER_RTT_Write
jurica238814 0:e61e7fc7cfe1 770 *
jurica238814 0:e61e7fc7cfe1 771 * Function description
jurica238814 0:e61e7fc7cfe1 772 * Stores a specified number of characters in SEGGER RTT
jurica238814 0:e61e7fc7cfe1 773 * control block which is then read by the host.
jurica238814 0:e61e7fc7cfe1 774 *
jurica238814 0:e61e7fc7cfe1 775 * Parameters
jurica238814 0:e61e7fc7cfe1 776 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
jurica238814 0:e61e7fc7cfe1 777 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
jurica238814 0:e61e7fc7cfe1 778 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
jurica238814 0:e61e7fc7cfe1 779 *
jurica238814 0:e61e7fc7cfe1 780 * Return value
jurica238814 0:e61e7fc7cfe1 781 * Number of bytes which have been stored in the "Up"-buffer.
jurica238814 0:e61e7fc7cfe1 782 *
jurica238814 0:e61e7fc7cfe1 783 * Notes
jurica238814 0:e61e7fc7cfe1 784 * (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
jurica238814 0:e61e7fc7cfe1 785 */
jurica238814 0:e61e7fc7cfe1 786 unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
jurica238814 0:e61e7fc7cfe1 787 unsigned Status;
jurica238814 0:e61e7fc7cfe1 788 //
jurica238814 0:e61e7fc7cfe1 789 INIT();
jurica238814 0:e61e7fc7cfe1 790 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 791 //
jurica238814 0:e61e7fc7cfe1 792 // Call the non-locking write function
jurica238814 0:e61e7fc7cfe1 793 //
jurica238814 0:e61e7fc7cfe1 794 Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes);
jurica238814 0:e61e7fc7cfe1 795 //
jurica238814 0:e61e7fc7cfe1 796 // Finish up.
jurica238814 0:e61e7fc7cfe1 797 //
jurica238814 0:e61e7fc7cfe1 798 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 799 //
jurica238814 0:e61e7fc7cfe1 800 return Status;
jurica238814 0:e61e7fc7cfe1 801 }
jurica238814 0:e61e7fc7cfe1 802
jurica238814 0:e61e7fc7cfe1 803 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 804 *
jurica238814 0:e61e7fc7cfe1 805 * SEGGER_RTT_WriteString
jurica238814 0:e61e7fc7cfe1 806 *
jurica238814 0:e61e7fc7cfe1 807 * Function description
jurica238814 0:e61e7fc7cfe1 808 * Stores string in SEGGER RTT control block.
jurica238814 0:e61e7fc7cfe1 809 * This data is read by the host.
jurica238814 0:e61e7fc7cfe1 810 *
jurica238814 0:e61e7fc7cfe1 811 * Parameters
jurica238814 0:e61e7fc7cfe1 812 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
jurica238814 0:e61e7fc7cfe1 813 * s Pointer to string.
jurica238814 0:e61e7fc7cfe1 814 *
jurica238814 0:e61e7fc7cfe1 815 * Return value
jurica238814 0:e61e7fc7cfe1 816 * Number of bytes which have been stored in the "Up"-buffer.
jurica238814 0:e61e7fc7cfe1 817 *
jurica238814 0:e61e7fc7cfe1 818 * Notes
jurica238814 0:e61e7fc7cfe1 819 * (1) If there is not enough space in the "Up"-buffer, depending on configuration,
jurica238814 0:e61e7fc7cfe1 820 * remaining characters may be dropped or RTT module waits until there is more space in the buffer.
jurica238814 0:e61e7fc7cfe1 821 * (2) String passed to this function has to be \0 terminated
jurica238814 0:e61e7fc7cfe1 822 * (3) \0 termination character is *not* stored in RTT buffer
jurica238814 0:e61e7fc7cfe1 823 */
jurica238814 0:e61e7fc7cfe1 824 unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
jurica238814 0:e61e7fc7cfe1 825 unsigned Len;
jurica238814 0:e61e7fc7cfe1 826
jurica238814 0:e61e7fc7cfe1 827 Len = STRLEN(s);
jurica238814 0:e61e7fc7cfe1 828 return SEGGER_RTT_Write(BufferIndex, s, Len);
jurica238814 0:e61e7fc7cfe1 829 }
jurica238814 0:e61e7fc7cfe1 830
jurica238814 0:e61e7fc7cfe1 831 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 832 *
jurica238814 0:e61e7fc7cfe1 833 * SEGGER_RTT_GetKey
jurica238814 0:e61e7fc7cfe1 834 *
jurica238814 0:e61e7fc7cfe1 835 * Function description
jurica238814 0:e61e7fc7cfe1 836 * Reads one character from the SEGGER RTT buffer.
jurica238814 0:e61e7fc7cfe1 837 * Host has previously stored data there.
jurica238814 0:e61e7fc7cfe1 838 *
jurica238814 0:e61e7fc7cfe1 839 * Return value
jurica238814 0:e61e7fc7cfe1 840 * < 0 - No character available (buffer empty).
jurica238814 0:e61e7fc7cfe1 841 * >= 0 - Character which has been read. (Possible values: 0 - 255)
jurica238814 0:e61e7fc7cfe1 842 *
jurica238814 0:e61e7fc7cfe1 843 * Notes
jurica238814 0:e61e7fc7cfe1 844 * (1) This function is only specified for accesses to RTT buffer 0.
jurica238814 0:e61e7fc7cfe1 845 */
jurica238814 0:e61e7fc7cfe1 846 int SEGGER_RTT_GetKey(void) {
jurica238814 0:e61e7fc7cfe1 847 char c;
jurica238814 0:e61e7fc7cfe1 848 int r;
jurica238814 0:e61e7fc7cfe1 849
jurica238814 0:e61e7fc7cfe1 850 r = (int)SEGGER_RTT_Read(0u, &c, 1u);
jurica238814 0:e61e7fc7cfe1 851 if (r == 1) {
jurica238814 0:e61e7fc7cfe1 852 r = (int)(unsigned char)c;
jurica238814 0:e61e7fc7cfe1 853 } else {
jurica238814 0:e61e7fc7cfe1 854 r = -1;
jurica238814 0:e61e7fc7cfe1 855 }
jurica238814 0:e61e7fc7cfe1 856 return r;
jurica238814 0:e61e7fc7cfe1 857 }
jurica238814 0:e61e7fc7cfe1 858
jurica238814 0:e61e7fc7cfe1 859 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 860 *
jurica238814 0:e61e7fc7cfe1 861 * SEGGER_RTT_WaitKey
jurica238814 0:e61e7fc7cfe1 862 *
jurica238814 0:e61e7fc7cfe1 863 * Function description
jurica238814 0:e61e7fc7cfe1 864 * Waits until at least one character is avaible in the SEGGER RTT buffer.
jurica238814 0:e61e7fc7cfe1 865 * Once a character is available, it is read and this function returns.
jurica238814 0:e61e7fc7cfe1 866 *
jurica238814 0:e61e7fc7cfe1 867 * Return value
jurica238814 0:e61e7fc7cfe1 868 * >=0 - Character which has been read.
jurica238814 0:e61e7fc7cfe1 869 *
jurica238814 0:e61e7fc7cfe1 870 * Notes
jurica238814 0:e61e7fc7cfe1 871 * (1) This function is only specified for accesses to RTT buffer 0
jurica238814 0:e61e7fc7cfe1 872 * (2) This function is blocking if no character is present in RTT buffer
jurica238814 0:e61e7fc7cfe1 873 */
jurica238814 0:e61e7fc7cfe1 874 int SEGGER_RTT_WaitKey(void) {
jurica238814 0:e61e7fc7cfe1 875 int r;
jurica238814 0:e61e7fc7cfe1 876
jurica238814 0:e61e7fc7cfe1 877 do {
jurica238814 0:e61e7fc7cfe1 878 r = SEGGER_RTT_GetKey();
jurica238814 0:e61e7fc7cfe1 879 } while (r < 0);
jurica238814 0:e61e7fc7cfe1 880 return r;
jurica238814 0:e61e7fc7cfe1 881 }
jurica238814 0:e61e7fc7cfe1 882
jurica238814 0:e61e7fc7cfe1 883 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 884 *
jurica238814 0:e61e7fc7cfe1 885 * SEGGER_RTT_HasKey
jurica238814 0:e61e7fc7cfe1 886 *
jurica238814 0:e61e7fc7cfe1 887 * Function description
jurica238814 0:e61e7fc7cfe1 888 * Checks if at least one character for reading is available in the SEGGER RTT buffer.
jurica238814 0:e61e7fc7cfe1 889 *
jurica238814 0:e61e7fc7cfe1 890 * Return value
jurica238814 0:e61e7fc7cfe1 891 * == 0 - No characters are available to read.
jurica238814 0:e61e7fc7cfe1 892 * == 1 - At least one character is available.
jurica238814 0:e61e7fc7cfe1 893 *
jurica238814 0:e61e7fc7cfe1 894 * Notes
jurica238814 0:e61e7fc7cfe1 895 * (1) This function is only specified for accesses to RTT buffer 0
jurica238814 0:e61e7fc7cfe1 896 */
jurica238814 0:e61e7fc7cfe1 897 int SEGGER_RTT_HasKey(void) {
jurica238814 0:e61e7fc7cfe1 898 unsigned RdOff;
jurica238814 0:e61e7fc7cfe1 899 int r;
jurica238814 0:e61e7fc7cfe1 900
jurica238814 0:e61e7fc7cfe1 901 INIT();
jurica238814 0:e61e7fc7cfe1 902 RdOff = _SEGGER_RTT.aDown[0].RdOff;
jurica238814 0:e61e7fc7cfe1 903 if (RdOff != _SEGGER_RTT.aDown[0].WrOff) {
jurica238814 0:e61e7fc7cfe1 904 r = 1;
jurica238814 0:e61e7fc7cfe1 905 } else {
jurica238814 0:e61e7fc7cfe1 906 r = 0;
jurica238814 0:e61e7fc7cfe1 907 }
jurica238814 0:e61e7fc7cfe1 908 return r;
jurica238814 0:e61e7fc7cfe1 909 }
jurica238814 0:e61e7fc7cfe1 910
jurica238814 0:e61e7fc7cfe1 911 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 912 *
jurica238814 0:e61e7fc7cfe1 913 * SEGGER_RTT_HasData
jurica238814 0:e61e7fc7cfe1 914 *
jurica238814 0:e61e7fc7cfe1 915 * Function description
jurica238814 0:e61e7fc7cfe1 916 * Check if there is data from the host in the given buffer.
jurica238814 0:e61e7fc7cfe1 917 *
jurica238814 0:e61e7fc7cfe1 918 * Return value:
jurica238814 0:e61e7fc7cfe1 919 * ==0: No data
jurica238814 0:e61e7fc7cfe1 920 * !=0: Data in buffer
jurica238814 0:e61e7fc7cfe1 921 *
jurica238814 0:e61e7fc7cfe1 922 */
jurica238814 0:e61e7fc7cfe1 923 unsigned SEGGER_RTT_HasData(unsigned BufferIndex) {
jurica238814 0:e61e7fc7cfe1 924 SEGGER_RTT_BUFFER_DOWN* pRing;
jurica238814 0:e61e7fc7cfe1 925 unsigned v;
jurica238814 0:e61e7fc7cfe1 926
jurica238814 0:e61e7fc7cfe1 927 pRing = &_SEGGER_RTT.aDown[BufferIndex];
jurica238814 0:e61e7fc7cfe1 928 v = pRing->WrOff;
jurica238814 0:e61e7fc7cfe1 929 return v - pRing->RdOff;
jurica238814 0:e61e7fc7cfe1 930 }
jurica238814 0:e61e7fc7cfe1 931
jurica238814 0:e61e7fc7cfe1 932 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 933 *
jurica238814 0:e61e7fc7cfe1 934 * SEGGER_RTT_AllocDownBuffer
jurica238814 0:e61e7fc7cfe1 935 *
jurica238814 0:e61e7fc7cfe1 936 * Function description
jurica238814 0:e61e7fc7cfe1 937 * Run-time configuration of the next down-buffer (H->T).
jurica238814 0:e61e7fc7cfe1 938 * The next buffer, which is not used yet is configured.
jurica238814 0:e61e7fc7cfe1 939 * This includes: Buffer address, size, name, flags, ...
jurica238814 0:e61e7fc7cfe1 940 *
jurica238814 0:e61e7fc7cfe1 941 * Parameters
jurica238814 0:e61e7fc7cfe1 942 * sName Pointer to a constant name string.
jurica238814 0:e61e7fc7cfe1 943 * pBuffer Pointer to a buffer to be used.
jurica238814 0:e61e7fc7cfe1 944 * BufferSize Size of the buffer.
jurica238814 0:e61e7fc7cfe1 945 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
jurica238814 0:e61e7fc7cfe1 946 *
jurica238814 0:e61e7fc7cfe1 947 * Return value
jurica238814 0:e61e7fc7cfe1 948 * >= 0 - O.K. Buffer Index
jurica238814 0:e61e7fc7cfe1 949 * < 0 - Error
jurica238814 0:e61e7fc7cfe1 950 */
jurica238814 0:e61e7fc7cfe1 951 int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
jurica238814 0:e61e7fc7cfe1 952 int BufferIndex;
jurica238814 0:e61e7fc7cfe1 953
jurica238814 0:e61e7fc7cfe1 954 INIT();
jurica238814 0:e61e7fc7cfe1 955 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 956 BufferIndex = 0;
jurica238814 0:e61e7fc7cfe1 957 do {
jurica238814 0:e61e7fc7cfe1 958 if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) {
jurica238814 0:e61e7fc7cfe1 959 break;
jurica238814 0:e61e7fc7cfe1 960 }
jurica238814 0:e61e7fc7cfe1 961 BufferIndex++;
jurica238814 0:e61e7fc7cfe1 962 } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers);
jurica238814 0:e61e7fc7cfe1 963 if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) {
jurica238814 0:e61e7fc7cfe1 964 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
jurica238814 0:e61e7fc7cfe1 965 _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer;
jurica238814 0:e61e7fc7cfe1 966 _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
jurica238814 0:e61e7fc7cfe1 967 _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
jurica238814 0:e61e7fc7cfe1 968 _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
jurica238814 0:e61e7fc7cfe1 969 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
jurica238814 0:e61e7fc7cfe1 970 } else {
jurica238814 0:e61e7fc7cfe1 971 BufferIndex = -1;
jurica238814 0:e61e7fc7cfe1 972 }
jurica238814 0:e61e7fc7cfe1 973 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 974 return BufferIndex;
jurica238814 0:e61e7fc7cfe1 975 }
jurica238814 0:e61e7fc7cfe1 976
jurica238814 0:e61e7fc7cfe1 977 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 978 *
jurica238814 0:e61e7fc7cfe1 979 * SEGGER_RTT_AllocUpBuffer
jurica238814 0:e61e7fc7cfe1 980 *
jurica238814 0:e61e7fc7cfe1 981 * Function description
jurica238814 0:e61e7fc7cfe1 982 * Run-time configuration of the next up-buffer (T->H).
jurica238814 0:e61e7fc7cfe1 983 * The next buffer, which is not used yet is configured.
jurica238814 0:e61e7fc7cfe1 984 * This includes: Buffer address, size, name, flags, ...
jurica238814 0:e61e7fc7cfe1 985 *
jurica238814 0:e61e7fc7cfe1 986 * Parameters
jurica238814 0:e61e7fc7cfe1 987 * sName Pointer to a constant name string.
jurica238814 0:e61e7fc7cfe1 988 * pBuffer Pointer to a buffer to be used.
jurica238814 0:e61e7fc7cfe1 989 * BufferSize Size of the buffer.
jurica238814 0:e61e7fc7cfe1 990 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
jurica238814 0:e61e7fc7cfe1 991 *
jurica238814 0:e61e7fc7cfe1 992 * Return value
jurica238814 0:e61e7fc7cfe1 993 * >= 0 - O.K. Buffer Index
jurica238814 0:e61e7fc7cfe1 994 * < 0 - Error
jurica238814 0:e61e7fc7cfe1 995 */
jurica238814 0:e61e7fc7cfe1 996 int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
jurica238814 0:e61e7fc7cfe1 997 int BufferIndex;
jurica238814 0:e61e7fc7cfe1 998
jurica238814 0:e61e7fc7cfe1 999 INIT();
jurica238814 0:e61e7fc7cfe1 1000 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 1001 BufferIndex = 0;
jurica238814 0:e61e7fc7cfe1 1002 do {
jurica238814 0:e61e7fc7cfe1 1003 if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) {
jurica238814 0:e61e7fc7cfe1 1004 break;
jurica238814 0:e61e7fc7cfe1 1005 }
jurica238814 0:e61e7fc7cfe1 1006 BufferIndex++;
jurica238814 0:e61e7fc7cfe1 1007 } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers);
jurica238814 0:e61e7fc7cfe1 1008 if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) {
jurica238814 0:e61e7fc7cfe1 1009 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
jurica238814 0:e61e7fc7cfe1 1010 _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer;
jurica238814 0:e61e7fc7cfe1 1011 _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
jurica238814 0:e61e7fc7cfe1 1012 _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
jurica238814 0:e61e7fc7cfe1 1013 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
jurica238814 0:e61e7fc7cfe1 1014 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
jurica238814 0:e61e7fc7cfe1 1015 } else {
jurica238814 0:e61e7fc7cfe1 1016 BufferIndex = -1;
jurica238814 0:e61e7fc7cfe1 1017 }
jurica238814 0:e61e7fc7cfe1 1018 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 1019 return BufferIndex;
jurica238814 0:e61e7fc7cfe1 1020 }
jurica238814 0:e61e7fc7cfe1 1021
jurica238814 0:e61e7fc7cfe1 1022 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 1023 *
jurica238814 0:e61e7fc7cfe1 1024 * SEGGER_RTT_ConfigUpBuffer
jurica238814 0:e61e7fc7cfe1 1025 *
jurica238814 0:e61e7fc7cfe1 1026 * Function description
jurica238814 0:e61e7fc7cfe1 1027 * Run-time configuration of a specific up-buffer (T->H).
jurica238814 0:e61e7fc7cfe1 1028 * Buffer to be configured is specified by index.
jurica238814 0:e61e7fc7cfe1 1029 * This includes: Buffer address, size, name, flags, ...
jurica238814 0:e61e7fc7cfe1 1030 *
jurica238814 0:e61e7fc7cfe1 1031 * Parameters
jurica238814 0:e61e7fc7cfe1 1032 * BufferIndex Index of the buffer to configure.
jurica238814 0:e61e7fc7cfe1 1033 * sName Pointer to a constant name string.
jurica238814 0:e61e7fc7cfe1 1034 * pBuffer Pointer to a buffer to be used.
jurica238814 0:e61e7fc7cfe1 1035 * BufferSize Size of the buffer.
jurica238814 0:e61e7fc7cfe1 1036 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
jurica238814 0:e61e7fc7cfe1 1037 *
jurica238814 0:e61e7fc7cfe1 1038 * Return value
jurica238814 0:e61e7fc7cfe1 1039 * >= 0 - O.K.
jurica238814 0:e61e7fc7cfe1 1040 * < 0 - Error
jurica238814 0:e61e7fc7cfe1 1041 */
jurica238814 0:e61e7fc7cfe1 1042 int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
jurica238814 0:e61e7fc7cfe1 1043 int r;
jurica238814 0:e61e7fc7cfe1 1044
jurica238814 0:e61e7fc7cfe1 1045 INIT();
jurica238814 0:e61e7fc7cfe1 1046 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
jurica238814 0:e61e7fc7cfe1 1047 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 1048 if (BufferIndex > 0u) {
jurica238814 0:e61e7fc7cfe1 1049 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
jurica238814 0:e61e7fc7cfe1 1050 _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer;
jurica238814 0:e61e7fc7cfe1 1051 _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
jurica238814 0:e61e7fc7cfe1 1052 _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
jurica238814 0:e61e7fc7cfe1 1053 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
jurica238814 0:e61e7fc7cfe1 1054 }
jurica238814 0:e61e7fc7cfe1 1055 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
jurica238814 0:e61e7fc7cfe1 1056 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 1057 r = 0;
jurica238814 0:e61e7fc7cfe1 1058 } else {
jurica238814 0:e61e7fc7cfe1 1059 r = -1;
jurica238814 0:e61e7fc7cfe1 1060 }
jurica238814 0:e61e7fc7cfe1 1061 return r;
jurica238814 0:e61e7fc7cfe1 1062 }
jurica238814 0:e61e7fc7cfe1 1063
jurica238814 0:e61e7fc7cfe1 1064 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 1065 *
jurica238814 0:e61e7fc7cfe1 1066 * SEGGER_RTT_ConfigDownBuffer
jurica238814 0:e61e7fc7cfe1 1067 *
jurica238814 0:e61e7fc7cfe1 1068 * Function description
jurica238814 0:e61e7fc7cfe1 1069 * Run-time configuration of a specific down-buffer (H->T).
jurica238814 0:e61e7fc7cfe1 1070 * Buffer to be configured is specified by index.
jurica238814 0:e61e7fc7cfe1 1071 * This includes: Buffer address, size, name, flags, ...
jurica238814 0:e61e7fc7cfe1 1072 *
jurica238814 0:e61e7fc7cfe1 1073 * Parameters
jurica238814 0:e61e7fc7cfe1 1074 * BufferIndex Index of the buffer to configure.
jurica238814 0:e61e7fc7cfe1 1075 * sName Pointer to a constant name string.
jurica238814 0:e61e7fc7cfe1 1076 * pBuffer Pointer to a buffer to be used.
jurica238814 0:e61e7fc7cfe1 1077 * BufferSize Size of the buffer.
jurica238814 0:e61e7fc7cfe1 1078 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
jurica238814 0:e61e7fc7cfe1 1079 *
jurica238814 0:e61e7fc7cfe1 1080 * Return value
jurica238814 0:e61e7fc7cfe1 1081 * >= 0 O.K.
jurica238814 0:e61e7fc7cfe1 1082 * < 0 Error
jurica238814 0:e61e7fc7cfe1 1083 */
jurica238814 0:e61e7fc7cfe1 1084 int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
jurica238814 0:e61e7fc7cfe1 1085 int r;
jurica238814 0:e61e7fc7cfe1 1086
jurica238814 0:e61e7fc7cfe1 1087 INIT();
jurica238814 0:e61e7fc7cfe1 1088 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
jurica238814 0:e61e7fc7cfe1 1089 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 1090 if (BufferIndex > 0u) {
jurica238814 0:e61e7fc7cfe1 1091 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
jurica238814 0:e61e7fc7cfe1 1092 _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer;
jurica238814 0:e61e7fc7cfe1 1093 _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
jurica238814 0:e61e7fc7cfe1 1094 _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
jurica238814 0:e61e7fc7cfe1 1095 _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
jurica238814 0:e61e7fc7cfe1 1096 }
jurica238814 0:e61e7fc7cfe1 1097 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
jurica238814 0:e61e7fc7cfe1 1098 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 1099 r = 0;
jurica238814 0:e61e7fc7cfe1 1100 } else {
jurica238814 0:e61e7fc7cfe1 1101 r = -1;
jurica238814 0:e61e7fc7cfe1 1102 }
jurica238814 0:e61e7fc7cfe1 1103 return r;
jurica238814 0:e61e7fc7cfe1 1104 }
jurica238814 0:e61e7fc7cfe1 1105
jurica238814 0:e61e7fc7cfe1 1106 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 1107 *
jurica238814 0:e61e7fc7cfe1 1108 * SEGGER_RTT_SetNameUpBuffer
jurica238814 0:e61e7fc7cfe1 1109 *
jurica238814 0:e61e7fc7cfe1 1110 * Function description
jurica238814 0:e61e7fc7cfe1 1111 * Run-time configuration of a specific up-buffer name (T->H).
jurica238814 0:e61e7fc7cfe1 1112 * Buffer to be configured is specified by index.
jurica238814 0:e61e7fc7cfe1 1113 *
jurica238814 0:e61e7fc7cfe1 1114 * Parameters
jurica238814 0:e61e7fc7cfe1 1115 * BufferIndex Index of the buffer to renamed.
jurica238814 0:e61e7fc7cfe1 1116 * sName Pointer to a constant name string.
jurica238814 0:e61e7fc7cfe1 1117 *
jurica238814 0:e61e7fc7cfe1 1118 * Return value
jurica238814 0:e61e7fc7cfe1 1119 * >= 0 O.K.
jurica238814 0:e61e7fc7cfe1 1120 * < 0 Error
jurica238814 0:e61e7fc7cfe1 1121 */
jurica238814 0:e61e7fc7cfe1 1122 int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) {
jurica238814 0:e61e7fc7cfe1 1123 int r;
jurica238814 0:e61e7fc7cfe1 1124
jurica238814 0:e61e7fc7cfe1 1125 INIT();
jurica238814 0:e61e7fc7cfe1 1126 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
jurica238814 0:e61e7fc7cfe1 1127 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 1128 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
jurica238814 0:e61e7fc7cfe1 1129 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 1130 r = 0;
jurica238814 0:e61e7fc7cfe1 1131 } else {
jurica238814 0:e61e7fc7cfe1 1132 r = -1;
jurica238814 0:e61e7fc7cfe1 1133 }
jurica238814 0:e61e7fc7cfe1 1134 return r;
jurica238814 0:e61e7fc7cfe1 1135 }
jurica238814 0:e61e7fc7cfe1 1136
jurica238814 0:e61e7fc7cfe1 1137 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 1138 *
jurica238814 0:e61e7fc7cfe1 1139 * SEGGER_RTT_SetNameDownBuffer
jurica238814 0:e61e7fc7cfe1 1140 *
jurica238814 0:e61e7fc7cfe1 1141 * Function description
jurica238814 0:e61e7fc7cfe1 1142 * Run-time configuration of a specific Down-buffer name (T->H).
jurica238814 0:e61e7fc7cfe1 1143 * Buffer to be configured is specified by index.
jurica238814 0:e61e7fc7cfe1 1144 *
jurica238814 0:e61e7fc7cfe1 1145 * Parameters
jurica238814 0:e61e7fc7cfe1 1146 * BufferIndex Index of the buffer to renamed.
jurica238814 0:e61e7fc7cfe1 1147 * sName Pointer to a constant name string.
jurica238814 0:e61e7fc7cfe1 1148 *
jurica238814 0:e61e7fc7cfe1 1149 * Return value
jurica238814 0:e61e7fc7cfe1 1150 * >= 0 O.K.
jurica238814 0:e61e7fc7cfe1 1151 * < 0 Error
jurica238814 0:e61e7fc7cfe1 1152 */
jurica238814 0:e61e7fc7cfe1 1153 int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
jurica238814 0:e61e7fc7cfe1 1154 int r;
jurica238814 0:e61e7fc7cfe1 1155
jurica238814 0:e61e7fc7cfe1 1156 INIT();
jurica238814 0:e61e7fc7cfe1 1157 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
jurica238814 0:e61e7fc7cfe1 1158 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 1159 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
jurica238814 0:e61e7fc7cfe1 1160 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 1161 r = 0;
jurica238814 0:e61e7fc7cfe1 1162 } else {
jurica238814 0:e61e7fc7cfe1 1163 r = -1;
jurica238814 0:e61e7fc7cfe1 1164 }
jurica238814 0:e61e7fc7cfe1 1165 return r;
jurica238814 0:e61e7fc7cfe1 1166 }
jurica238814 0:e61e7fc7cfe1 1167
jurica238814 0:e61e7fc7cfe1 1168 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 1169 *
jurica238814 0:e61e7fc7cfe1 1170 * SEGGER_RTT_Init
jurica238814 0:e61e7fc7cfe1 1171 *
jurica238814 0:e61e7fc7cfe1 1172 * Function description
jurica238814 0:e61e7fc7cfe1 1173 * Initializes the RTT Control Block.
jurica238814 0:e61e7fc7cfe1 1174 * Should be used in RAM targets, at start of the application.
jurica238814 0:e61e7fc7cfe1 1175 *
jurica238814 0:e61e7fc7cfe1 1176 */
jurica238814 0:e61e7fc7cfe1 1177 void SEGGER_RTT_Init (void) {
jurica238814 0:e61e7fc7cfe1 1178 _DoInit();
jurica238814 0:e61e7fc7cfe1 1179 }
jurica238814 0:e61e7fc7cfe1 1180
jurica238814 0:e61e7fc7cfe1 1181 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 1182 *
jurica238814 0:e61e7fc7cfe1 1183 * SEGGER_RTT_SetTerminal
jurica238814 0:e61e7fc7cfe1 1184 *
jurica238814 0:e61e7fc7cfe1 1185 * Function description
jurica238814 0:e61e7fc7cfe1 1186 * Sets the terminal to be used for output on channel 0.
jurica238814 0:e61e7fc7cfe1 1187 *
jurica238814 0:e61e7fc7cfe1 1188 * Parameters
jurica238814 0:e61e7fc7cfe1 1189 * TerminalId Index of the terminal.
jurica238814 0:e61e7fc7cfe1 1190 *
jurica238814 0:e61e7fc7cfe1 1191 * Return value
jurica238814 0:e61e7fc7cfe1 1192 * >= 0 O.K.
jurica238814 0:e61e7fc7cfe1 1193 * < 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)
jurica238814 0:e61e7fc7cfe1 1194 */
jurica238814 0:e61e7fc7cfe1 1195 int SEGGER_RTT_SetTerminal (char TerminalId) {
jurica238814 0:e61e7fc7cfe1 1196 char ac[2];
jurica238814 0:e61e7fc7cfe1 1197 SEGGER_RTT_BUFFER_UP* pRing;
jurica238814 0:e61e7fc7cfe1 1198 unsigned Avail;
jurica238814 0:e61e7fc7cfe1 1199 int r;
jurica238814 0:e61e7fc7cfe1 1200 //
jurica238814 0:e61e7fc7cfe1 1201 INIT();
jurica238814 0:e61e7fc7cfe1 1202 //
jurica238814 0:e61e7fc7cfe1 1203 r = 0;
jurica238814 0:e61e7fc7cfe1 1204 ac[0] = 0xFFU;
jurica238814 0:e61e7fc7cfe1 1205 if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels
jurica238814 0:e61e7fc7cfe1 1206 ac[1] = _aTerminalId[(unsigned char)TerminalId];
jurica238814 0:e61e7fc7cfe1 1207 pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed
jurica238814 0:e61e7fc7cfe1 1208 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
jurica238814 0:e61e7fc7cfe1 1209 if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
jurica238814 0:e61e7fc7cfe1 1210 _ActiveTerminal = TerminalId;
jurica238814 0:e61e7fc7cfe1 1211 _WriteBlocking(pRing, ac, 2u);
jurica238814 0:e61e7fc7cfe1 1212 } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes
jurica238814 0:e61e7fc7cfe1 1213 Avail = _GetAvailWriteSpace(pRing);
jurica238814 0:e61e7fc7cfe1 1214 if (Avail >= 2) {
jurica238814 0:e61e7fc7cfe1 1215 _ActiveTerminal = TerminalId; // Only change active terminal in case of success
jurica238814 0:e61e7fc7cfe1 1216 _WriteNoCheck(pRing, ac, 2u);
jurica238814 0:e61e7fc7cfe1 1217 } else {
jurica238814 0:e61e7fc7cfe1 1218 r = -1;
jurica238814 0:e61e7fc7cfe1 1219 }
jurica238814 0:e61e7fc7cfe1 1220 }
jurica238814 0:e61e7fc7cfe1 1221 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 1222 } else {
jurica238814 0:e61e7fc7cfe1 1223 r = -1;
jurica238814 0:e61e7fc7cfe1 1224 }
jurica238814 0:e61e7fc7cfe1 1225 return r;
jurica238814 0:e61e7fc7cfe1 1226 }
jurica238814 0:e61e7fc7cfe1 1227
jurica238814 0:e61e7fc7cfe1 1228 /*********************************************************************
jurica238814 0:e61e7fc7cfe1 1229 *
jurica238814 0:e61e7fc7cfe1 1230 * SEGGER_RTT_TerminalOut
jurica238814 0:e61e7fc7cfe1 1231 *
jurica238814 0:e61e7fc7cfe1 1232 * Function description
jurica238814 0:e61e7fc7cfe1 1233 * Writes a string to the given terminal
jurica238814 0:e61e7fc7cfe1 1234 * without changing the terminal for channel 0.
jurica238814 0:e61e7fc7cfe1 1235 *
jurica238814 0:e61e7fc7cfe1 1236 * Parameters
jurica238814 0:e61e7fc7cfe1 1237 * TerminalId Index of the terminal.
jurica238814 0:e61e7fc7cfe1 1238 * s String to be printed on the terminal.
jurica238814 0:e61e7fc7cfe1 1239 *
jurica238814 0:e61e7fc7cfe1 1240 * Return value
jurica238814 0:e61e7fc7cfe1 1241 * >= 0 - Number of bytes written.
jurica238814 0:e61e7fc7cfe1 1242 * < 0 - Error.
jurica238814 0:e61e7fc7cfe1 1243 *
jurica238814 0:e61e7fc7cfe1 1244 */
jurica238814 0:e61e7fc7cfe1 1245 int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) {
jurica238814 0:e61e7fc7cfe1 1246 int Status;
jurica238814 0:e61e7fc7cfe1 1247 unsigned FragLen;
jurica238814 0:e61e7fc7cfe1 1248 unsigned Avail;
jurica238814 0:e61e7fc7cfe1 1249 SEGGER_RTT_BUFFER_UP* pRing;
jurica238814 0:e61e7fc7cfe1 1250 //
jurica238814 0:e61e7fc7cfe1 1251 INIT();
jurica238814 0:e61e7fc7cfe1 1252 //
jurica238814 0:e61e7fc7cfe1 1253 // Validate terminal ID.
jurica238814 0:e61e7fc7cfe1 1254 //
jurica238814 0:e61e7fc7cfe1 1255 if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels
jurica238814 0:e61e7fc7cfe1 1256 //
jurica238814 0:e61e7fc7cfe1 1257 // Get "to-host" ring buffer.
jurica238814 0:e61e7fc7cfe1 1258 //
jurica238814 0:e61e7fc7cfe1 1259 pRing = &_SEGGER_RTT.aUp[0];
jurica238814 0:e61e7fc7cfe1 1260 //
jurica238814 0:e61e7fc7cfe1 1261 // Need to be able to change terminal, write data, change back.
jurica238814 0:e61e7fc7cfe1 1262 // Compute the fixed and variable sizes.
jurica238814 0:e61e7fc7cfe1 1263 //
jurica238814 0:e61e7fc7cfe1 1264 FragLen = strlen(s);
jurica238814 0:e61e7fc7cfe1 1265 //
jurica238814 0:e61e7fc7cfe1 1266 // How we output depends upon the mode...
jurica238814 0:e61e7fc7cfe1 1267 //
jurica238814 0:e61e7fc7cfe1 1268 SEGGER_RTT_LOCK();
jurica238814 0:e61e7fc7cfe1 1269 Avail = _GetAvailWriteSpace(pRing);
jurica238814 0:e61e7fc7cfe1 1270 switch (pRing->Flags & SEGGER_RTT_MODE_MASK) {
jurica238814 0:e61e7fc7cfe1 1271 case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
jurica238814 0:e61e7fc7cfe1 1272 //
jurica238814 0:e61e7fc7cfe1 1273 // If we are in skip mode and there is no space for the whole
jurica238814 0:e61e7fc7cfe1 1274 // of this output, don't bother switching terminals at all.
jurica238814 0:e61e7fc7cfe1 1275 //
jurica238814 0:e61e7fc7cfe1 1276 if (Avail < (FragLen + 4u)) {
jurica238814 0:e61e7fc7cfe1 1277 Status = 0;
jurica238814 0:e61e7fc7cfe1 1278 } else {
jurica238814 0:e61e7fc7cfe1 1279 _PostTerminalSwitch(pRing, TerminalId);
jurica238814 0:e61e7fc7cfe1 1280 Status = (int)_WriteBlocking(pRing, s, FragLen);
jurica238814 0:e61e7fc7cfe1 1281 _PostTerminalSwitch(pRing, _ActiveTerminal);
jurica238814 0:e61e7fc7cfe1 1282 }
jurica238814 0:e61e7fc7cfe1 1283 break;
jurica238814 0:e61e7fc7cfe1 1284 case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
jurica238814 0:e61e7fc7cfe1 1285 //
jurica238814 0:e61e7fc7cfe1 1286 // If we are in trim mode and there is not enough space for everything,
jurica238814 0:e61e7fc7cfe1 1287 // trim the output but always include the terminal switch. If no room
jurica238814 0:e61e7fc7cfe1 1288 // for terminal switch, skip that totally.
jurica238814 0:e61e7fc7cfe1 1289 //
jurica238814 0:e61e7fc7cfe1 1290 if (Avail < 4u) {
jurica238814 0:e61e7fc7cfe1 1291 Status = -1;
jurica238814 0:e61e7fc7cfe1 1292 } else {
jurica238814 0:e61e7fc7cfe1 1293 _PostTerminalSwitch(pRing, TerminalId);
jurica238814 0:e61e7fc7cfe1 1294 Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u));
jurica238814 0:e61e7fc7cfe1 1295 _PostTerminalSwitch(pRing, _ActiveTerminal);
jurica238814 0:e61e7fc7cfe1 1296 }
jurica238814 0:e61e7fc7cfe1 1297 break;
jurica238814 0:e61e7fc7cfe1 1298 case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
jurica238814 0:e61e7fc7cfe1 1299 //
jurica238814 0:e61e7fc7cfe1 1300 // If we are in blocking mode, output everything.
jurica238814 0:e61e7fc7cfe1 1301 //
jurica238814 0:e61e7fc7cfe1 1302 _PostTerminalSwitch(pRing, TerminalId);
jurica238814 0:e61e7fc7cfe1 1303 Status = (int)_WriteBlocking(pRing, s, FragLen);
jurica238814 0:e61e7fc7cfe1 1304 _PostTerminalSwitch(pRing, _ActiveTerminal);
jurica238814 0:e61e7fc7cfe1 1305 break;
jurica238814 0:e61e7fc7cfe1 1306 default:
jurica238814 0:e61e7fc7cfe1 1307 Status = -1;
jurica238814 0:e61e7fc7cfe1 1308 break;
jurica238814 0:e61e7fc7cfe1 1309 }
jurica238814 0:e61e7fc7cfe1 1310 //
jurica238814 0:e61e7fc7cfe1 1311 // Finish up.
jurica238814 0:e61e7fc7cfe1 1312 //
jurica238814 0:e61e7fc7cfe1 1313 SEGGER_RTT_UNLOCK();
jurica238814 0:e61e7fc7cfe1 1314 } else {
jurica238814 0:e61e7fc7cfe1 1315 Status = -1;
jurica238814 0:e61e7fc7cfe1 1316 }
jurica238814 0:e61e7fc7cfe1 1317 return Status;
jurica238814 0:e61e7fc7cfe1 1318 }
jurica238814 0:e61e7fc7cfe1 1319
jurica238814 0:e61e7fc7cfe1 1320
jurica238814 0:e61e7fc7cfe1 1321 /*************************** End of file ****************************/
jurica238814 0:e61e7fc7cfe1 1322