This is a FileHandle interface implementation and retarget registration of the stdio interface to the Segger Real-Time Terminal (RTT) instead of the default serial port. Retargeting will automatically take place if this library is added to the project.

Dependents:   3_Test_AFE 1_Test_Flash_ADC_RTT

Committer:
0x6d61726b
Date:
Sat May 18 22:41:10 2019 +0000
Revision:
0:7fca1bf48117
updated to Segger RTT version 6.44i

Who changed what in which revision?

UserRevisionLine numberNew contents of line
0x6d61726b 0:7fca1bf48117 1 /*********************************************************************
0x6d61726b 0:7fca1bf48117 2 * SEGGER Microcontroller GmbH *
0x6d61726b 0:7fca1bf48117 3 * The Embedded Experts *
0x6d61726b 0:7fca1bf48117 4 **********************************************************************
0x6d61726b 0:7fca1bf48117 5 * *
0x6d61726b 0:7fca1bf48117 6 * (c) 1995 - 2019 SEGGER Microcontroller GmbH *
0x6d61726b 0:7fca1bf48117 7 * *
0x6d61726b 0:7fca1bf48117 8 * www.segger.com Support: support@segger.com *
0x6d61726b 0:7fca1bf48117 9 * *
0x6d61726b 0:7fca1bf48117 10 **********************************************************************
0x6d61726b 0:7fca1bf48117 11 * *
0x6d61726b 0:7fca1bf48117 12 * SEGGER RTT * Real Time Transfer for embedded targets *
0x6d61726b 0:7fca1bf48117 13 * *
0x6d61726b 0:7fca1bf48117 14 **********************************************************************
0x6d61726b 0:7fca1bf48117 15 * *
0x6d61726b 0:7fca1bf48117 16 * All rights reserved. *
0x6d61726b 0:7fca1bf48117 17 * *
0x6d61726b 0:7fca1bf48117 18 * SEGGER strongly recommends to not make any changes *
0x6d61726b 0:7fca1bf48117 19 * to or modify the source code of this software in order to stay *
0x6d61726b 0:7fca1bf48117 20 * compatible with the RTT protocol and J-Link. *
0x6d61726b 0:7fca1bf48117 21 * *
0x6d61726b 0:7fca1bf48117 22 * Redistribution and use in source and binary forms, with or *
0x6d61726b 0:7fca1bf48117 23 * without modification, are permitted provided that the following *
0x6d61726b 0:7fca1bf48117 24 * conditions are met: *
0x6d61726b 0:7fca1bf48117 25 * *
0x6d61726b 0:7fca1bf48117 26 * o Redistributions of source code must retain the above copyright *
0x6d61726b 0:7fca1bf48117 27 * notice, this list of conditions and the following disclaimer. *
0x6d61726b 0:7fca1bf48117 28 * *
0x6d61726b 0:7fca1bf48117 29 * o Redistributions in binary form must reproduce the above *
0x6d61726b 0:7fca1bf48117 30 * copyright notice, this list of conditions and the following *
0x6d61726b 0:7fca1bf48117 31 * disclaimer in the documentation and/or other materials provided *
0x6d61726b 0:7fca1bf48117 32 * with the distribution. *
0x6d61726b 0:7fca1bf48117 33 * *
0x6d61726b 0:7fca1bf48117 34 * o Neither the name of SEGGER Microcontroller GmbH *
0x6d61726b 0:7fca1bf48117 35 * nor the names of its contributors may be used to endorse or *
0x6d61726b 0:7fca1bf48117 36 * promote products derived from this software without specific *
0x6d61726b 0:7fca1bf48117 37 * prior written permission. *
0x6d61726b 0:7fca1bf48117 38 * *
0x6d61726b 0:7fca1bf48117 39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
0x6d61726b 0:7fca1bf48117 40 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
0x6d61726b 0:7fca1bf48117 41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
0x6d61726b 0:7fca1bf48117 42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
0x6d61726b 0:7fca1bf48117 43 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
0x6d61726b 0:7fca1bf48117 44 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
0x6d61726b 0:7fca1bf48117 45 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
0x6d61726b 0:7fca1bf48117 46 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
0x6d61726b 0:7fca1bf48117 47 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
0x6d61726b 0:7fca1bf48117 48 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
0x6d61726b 0:7fca1bf48117 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
0x6d61726b 0:7fca1bf48117 50 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
0x6d61726b 0:7fca1bf48117 51 * DAMAGE. *
0x6d61726b 0:7fca1bf48117 52 * *
0x6d61726b 0:7fca1bf48117 53 **********************************************************************
0x6d61726b 0:7fca1bf48117 54 * *
0x6d61726b 0:7fca1bf48117 55 * RTT version: 6.44i *
0x6d61726b 0:7fca1bf48117 56 * *
0x6d61726b 0:7fca1bf48117 57 **********************************************************************
0x6d61726b 0:7fca1bf48117 58 ---------------------------END-OF-HEADER------------------------------
0x6d61726b 0:7fca1bf48117 59 File : SEGGER_RTT.c
0x6d61726b 0:7fca1bf48117 60 Purpose : Implementation of SEGGER real-time transfer (RTT) which
0x6d61726b 0:7fca1bf48117 61 allows real-time communication on targets which support
0x6d61726b 0:7fca1bf48117 62 debugger memory accesses while the CPU is running.
0x6d61726b 0:7fca1bf48117 63 Revision: Rev: 13375
0x6d61726b 0:7fca1bf48117 64
0x6d61726b 0:7fca1bf48117 65 Additional information:
0x6d61726b 0:7fca1bf48117 66 Type "int" is assumed to be 32-bits in size
0x6d61726b 0:7fca1bf48117 67 H->T Host to target communication
0x6d61726b 0:7fca1bf48117 68 T->H Target to host communication
0x6d61726b 0:7fca1bf48117 69
0x6d61726b 0:7fca1bf48117 70 RTT channel 0 is always present and reserved for Terminal usage.
0x6d61726b 0:7fca1bf48117 71 Name is fixed to "Terminal"
0x6d61726b 0:7fca1bf48117 72
0x6d61726b 0:7fca1bf48117 73 Effective buffer size: SizeOfBuffer - 1
0x6d61726b 0:7fca1bf48117 74
0x6d61726b 0:7fca1bf48117 75 WrOff == RdOff: Buffer is empty
0x6d61726b 0:7fca1bf48117 76 WrOff == (RdOff - 1): Buffer is full
0x6d61726b 0:7fca1bf48117 77 WrOff > RdOff: Free space includes wrap-around
0x6d61726b 0:7fca1bf48117 78 WrOff < RdOff: Used space includes wrap-around
0x6d61726b 0:7fca1bf48117 79 (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0):
0x6d61726b 0:7fca1bf48117 80 Buffer full and wrap-around after next byte
0x6d61726b 0:7fca1bf48117 81
0x6d61726b 0:7fca1bf48117 82
0x6d61726b 0:7fca1bf48117 83 ----------------------------------------------------------------------
0x6d61726b 0:7fca1bf48117 84 */
0x6d61726b 0:7fca1bf48117 85
0x6d61726b 0:7fca1bf48117 86 #include "SEGGER_RTT.h"
0x6d61726b 0:7fca1bf48117 87
0x6d61726b 0:7fca1bf48117 88 #include <string.h> // for memcpy
0x6d61726b 0:7fca1bf48117 89
0x6d61726b 0:7fca1bf48117 90 /*********************************************************************
0x6d61726b 0:7fca1bf48117 91 *
0x6d61726b 0:7fca1bf48117 92 * Configuration, default values
0x6d61726b 0:7fca1bf48117 93 *
0x6d61726b 0:7fca1bf48117 94 **********************************************************************
0x6d61726b 0:7fca1bf48117 95 */
0x6d61726b 0:7fca1bf48117 96
0x6d61726b 0:7fca1bf48117 97 #ifndef BUFFER_SIZE_UP
0x6d61726b 0:7fca1bf48117 98 #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host
0x6d61726b 0:7fca1bf48117 99 #endif
0x6d61726b 0:7fca1bf48117 100
0x6d61726b 0:7fca1bf48117 101 #ifndef BUFFER_SIZE_DOWN
0x6d61726b 0:7fca1bf48117 102 #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input)
0x6d61726b 0:7fca1bf48117 103 #endif
0x6d61726b 0:7fca1bf48117 104
0x6d61726b 0:7fca1bf48117 105 #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
0x6d61726b 0:7fca1bf48117 106 #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target
0x6d61726b 0:7fca1bf48117 107 #endif
0x6d61726b 0:7fca1bf48117 108
0x6d61726b 0:7fca1bf48117 109 #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
0x6d61726b 0:7fca1bf48117 110 #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target
0x6d61726b 0:7fca1bf48117 111 #endif
0x6d61726b 0:7fca1bf48117 112
0x6d61726b 0:7fca1bf48117 113 #ifndef SEGGER_RTT_BUFFER_SECTION
0x6d61726b 0:7fca1bf48117 114 #if defined(SEGGER_RTT_SECTION)
0x6d61726b 0:7fca1bf48117 115 #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
0x6d61726b 0:7fca1bf48117 116 #endif
0x6d61726b 0:7fca1bf48117 117 #endif
0x6d61726b 0:7fca1bf48117 118
0x6d61726b 0:7fca1bf48117 119 #ifndef SEGGER_RTT_ALIGNMENT
0x6d61726b 0:7fca1bf48117 120 #define SEGGER_RTT_ALIGNMENT 0
0x6d61726b 0:7fca1bf48117 121 #endif
0x6d61726b 0:7fca1bf48117 122
0x6d61726b 0:7fca1bf48117 123 #ifndef SEGGER_RTT_BUFFER_ALIGNMENT
0x6d61726b 0:7fca1bf48117 124 #define SEGGER_RTT_BUFFER_ALIGNMENT 0
0x6d61726b 0:7fca1bf48117 125 #endif
0x6d61726b 0:7fca1bf48117 126
0x6d61726b 0:7fca1bf48117 127 #ifndef SEGGER_RTT_MODE_DEFAULT
0x6d61726b 0:7fca1bf48117 128 #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP
0x6d61726b 0:7fca1bf48117 129 #endif
0x6d61726b 0:7fca1bf48117 130
0x6d61726b 0:7fca1bf48117 131 #ifndef SEGGER_RTT_LOCK
0x6d61726b 0:7fca1bf48117 132 #define SEGGER_RTT_LOCK()
0x6d61726b 0:7fca1bf48117 133 #endif
0x6d61726b 0:7fca1bf48117 134
0x6d61726b 0:7fca1bf48117 135 #ifndef SEGGER_RTT_UNLOCK
0x6d61726b 0:7fca1bf48117 136 #define SEGGER_RTT_UNLOCK()
0x6d61726b 0:7fca1bf48117 137 #endif
0x6d61726b 0:7fca1bf48117 138
0x6d61726b 0:7fca1bf48117 139 #ifndef STRLEN
0x6d61726b 0:7fca1bf48117 140 #define STRLEN(a) strlen((a))
0x6d61726b 0:7fca1bf48117 141 #endif
0x6d61726b 0:7fca1bf48117 142
0x6d61726b 0:7fca1bf48117 143 #ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 144 #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0
0x6d61726b 0:7fca1bf48117 145 #endif
0x6d61726b 0:7fca1bf48117 146
0x6d61726b 0:7fca1bf48117 147 #ifndef SEGGER_RTT_MEMCPY
0x6d61726b 0:7fca1bf48117 148 #ifdef MEMCPY
0x6d61726b 0:7fca1bf48117 149 #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes))
0x6d61726b 0:7fca1bf48117 150 #else
0x6d61726b 0:7fca1bf48117 151 #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
0x6d61726b 0:7fca1bf48117 152 #endif
0x6d61726b 0:7fca1bf48117 153 #endif
0x6d61726b 0:7fca1bf48117 154
0x6d61726b 0:7fca1bf48117 155 #ifndef MIN
0x6d61726b 0:7fca1bf48117 156 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
0x6d61726b 0:7fca1bf48117 157 #endif
0x6d61726b 0:7fca1bf48117 158
0x6d61726b 0:7fca1bf48117 159 #ifndef MAX
0x6d61726b 0:7fca1bf48117 160 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
0x6d61726b 0:7fca1bf48117 161 #endif
0x6d61726b 0:7fca1bf48117 162 //
0x6d61726b 0:7fca1bf48117 163 // For some environments, NULL may not be defined until certain headers are included
0x6d61726b 0:7fca1bf48117 164 //
0x6d61726b 0:7fca1bf48117 165 #ifndef NULL
0x6d61726b 0:7fca1bf48117 166 #define NULL 0
0x6d61726b 0:7fca1bf48117 167 #endif
0x6d61726b 0:7fca1bf48117 168
0x6d61726b 0:7fca1bf48117 169 /*********************************************************************
0x6d61726b 0:7fca1bf48117 170 *
0x6d61726b 0:7fca1bf48117 171 * Defines, fixed
0x6d61726b 0:7fca1bf48117 172 *
0x6d61726b 0:7fca1bf48117 173 **********************************************************************
0x6d61726b 0:7fca1bf48117 174 */
0x6d61726b 0:7fca1bf48117 175 #if (defined __ICCARM__) || (defined __ICCRX__)
0x6d61726b 0:7fca1bf48117 176 #define RTT_PRAGMA(P) _Pragma(#P)
0x6d61726b 0:7fca1bf48117 177 #endif
0x6d61726b 0:7fca1bf48117 178
0x6d61726b 0:7fca1bf48117 179 #if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT
0x6d61726b 0:7fca1bf48117 180 #if (defined __GNUC__)
0x6d61726b 0:7fca1bf48117 181 #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
0x6d61726b 0:7fca1bf48117 182 #elif (defined __ICCARM__) || (defined __ICCRX__)
0x6d61726b 0:7fca1bf48117 183 #define PRAGMA(A) _Pragma(#A)
0x6d61726b 0:7fca1bf48117 184 #define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \
0x6d61726b 0:7fca1bf48117 185 Var
0x6d61726b 0:7fca1bf48117 186 #elif (defined __CC_ARM)
0x6d61726b 0:7fca1bf48117 187 #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
0x6d61726b 0:7fca1bf48117 188 #else
0x6d61726b 0:7fca1bf48117 189 #error "Alignment not supported for this compiler."
0x6d61726b 0:7fca1bf48117 190 #endif
0x6d61726b 0:7fca1bf48117 191 #else
0x6d61726b 0:7fca1bf48117 192 #define SEGGER_RTT_ALIGN(Var, Alignment) Var
0x6d61726b 0:7fca1bf48117 193 #endif
0x6d61726b 0:7fca1bf48117 194
0x6d61726b 0:7fca1bf48117 195 #if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION)
0x6d61726b 0:7fca1bf48117 196 #if (defined __GNUC__)
0x6d61726b 0:7fca1bf48117 197 #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var
0x6d61726b 0:7fca1bf48117 198 #elif (defined __ICCARM__) || (defined __ICCRX__)
0x6d61726b 0:7fca1bf48117 199 #define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \
0x6d61726b 0:7fca1bf48117 200 Var
0x6d61726b 0:7fca1bf48117 201 #elif (defined __CC_ARM)
0x6d61726b 0:7fca1bf48117 202 #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var
0x6d61726b 0:7fca1bf48117 203 #else
0x6d61726b 0:7fca1bf48117 204 #error "Section placement not supported for this compiler."
0x6d61726b 0:7fca1bf48117 205 #endif
0x6d61726b 0:7fca1bf48117 206 #else
0x6d61726b 0:7fca1bf48117 207 #define SEGGER_RTT_PUT_SECTION(Var, Section) Var
0x6d61726b 0:7fca1bf48117 208 #endif
0x6d61726b 0:7fca1bf48117 209
0x6d61726b 0:7fca1bf48117 210
0x6d61726b 0:7fca1bf48117 211 #if SEGGER_RTT_ALIGNMENT
0x6d61726b 0:7fca1bf48117 212 #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT)
0x6d61726b 0:7fca1bf48117 213 #else
0x6d61726b 0:7fca1bf48117 214 #define SEGGER_RTT_CB_ALIGN(Var) Var
0x6d61726b 0:7fca1bf48117 215 #endif
0x6d61726b 0:7fca1bf48117 216
0x6d61726b 0:7fca1bf48117 217 #if SEGGER_RTT_BUFFER_ALIGNMENT
0x6d61726b 0:7fca1bf48117 218 #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT)
0x6d61726b 0:7fca1bf48117 219 #else
0x6d61726b 0:7fca1bf48117 220 #define SEGGER_RTT_BUFFER_ALIGN(Var) Var
0x6d61726b 0:7fca1bf48117 221 #endif
0x6d61726b 0:7fca1bf48117 222
0x6d61726b 0:7fca1bf48117 223
0x6d61726b 0:7fca1bf48117 224 #if defined(SEGGER_RTT_SECTION)
0x6d61726b 0:7fca1bf48117 225 #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION)
0x6d61726b 0:7fca1bf48117 226 #else
0x6d61726b 0:7fca1bf48117 227 #define SEGGER_RTT_PUT_CB_SECTION(Var) Var
0x6d61726b 0:7fca1bf48117 228 #endif
0x6d61726b 0:7fca1bf48117 229
0x6d61726b 0:7fca1bf48117 230 #if defined(SEGGER_RTT_BUFFER_SECTION)
0x6d61726b 0:7fca1bf48117 231 #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION)
0x6d61726b 0:7fca1bf48117 232 #else
0x6d61726b 0:7fca1bf48117 233 #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var
0x6d61726b 0:7fca1bf48117 234 #endif
0x6d61726b 0:7fca1bf48117 235
0x6d61726b 0:7fca1bf48117 236 /*********************************************************************
0x6d61726b 0:7fca1bf48117 237 *
0x6d61726b 0:7fca1bf48117 238 * Static const data
0x6d61726b 0:7fca1bf48117 239 *
0x6d61726b 0:7fca1bf48117 240 **********************************************************************
0x6d61726b 0:7fca1bf48117 241 */
0x6d61726b 0:7fca1bf48117 242
0x6d61726b 0:7fca1bf48117 243 static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
0x6d61726b 0:7fca1bf48117 244
0x6d61726b 0:7fca1bf48117 245 /*********************************************************************
0x6d61726b 0:7fca1bf48117 246 *
0x6d61726b 0:7fca1bf48117 247 * Static data
0x6d61726b 0:7fca1bf48117 248 *
0x6d61726b 0:7fca1bf48117 249 **********************************************************************
0x6d61726b 0:7fca1bf48117 250 */
0x6d61726b 0:7fca1bf48117 251 //
0x6d61726b 0:7fca1bf48117 252 // RTT Control Block and allocate buffers for channel 0
0x6d61726b 0:7fca1bf48117 253 //
0x6d61726b 0:7fca1bf48117 254 SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
0x6d61726b 0:7fca1bf48117 255
0x6d61726b 0:7fca1bf48117 256 SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP]));
0x6d61726b 0:7fca1bf48117 257 SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN]));
0x6d61726b 0:7fca1bf48117 258
0x6d61726b 0:7fca1bf48117 259 static char _ActiveTerminal;
0x6d61726b 0:7fca1bf48117 260
0x6d61726b 0:7fca1bf48117 261 /*********************************************************************
0x6d61726b 0:7fca1bf48117 262 *
0x6d61726b 0:7fca1bf48117 263 * Static functions
0x6d61726b 0:7fca1bf48117 264 *
0x6d61726b 0:7fca1bf48117 265 **********************************************************************
0x6d61726b 0:7fca1bf48117 266 */
0x6d61726b 0:7fca1bf48117 267
0x6d61726b 0:7fca1bf48117 268 /*********************************************************************
0x6d61726b 0:7fca1bf48117 269 *
0x6d61726b 0:7fca1bf48117 270 * _DoInit()
0x6d61726b 0:7fca1bf48117 271 *
0x6d61726b 0:7fca1bf48117 272 * Function description
0x6d61726b 0:7fca1bf48117 273 * Initializes the control block an buffers.
0x6d61726b 0:7fca1bf48117 274 * May only be called via INIT() to avoid overriding settings.
0x6d61726b 0:7fca1bf48117 275 *
0x6d61726b 0:7fca1bf48117 276 */
0x6d61726b 0:7fca1bf48117 277 #define INIT() do { \
0x6d61726b 0:7fca1bf48117 278 if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \
0x6d61726b 0:7fca1bf48117 279 } while (0)
0x6d61726b 0:7fca1bf48117 280 static void _DoInit(void) {
0x6d61726b 0:7fca1bf48117 281 SEGGER_RTT_CB* p;
0x6d61726b 0:7fca1bf48117 282 //
0x6d61726b 0:7fca1bf48117 283 // Initialize control block
0x6d61726b 0:7fca1bf48117 284 //
0x6d61726b 0:7fca1bf48117 285 p = &_SEGGER_RTT;
0x6d61726b 0:7fca1bf48117 286 p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS;
0x6d61726b 0:7fca1bf48117 287 p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS;
0x6d61726b 0:7fca1bf48117 288 //
0x6d61726b 0:7fca1bf48117 289 // Initialize up buffer 0
0x6d61726b 0:7fca1bf48117 290 //
0x6d61726b 0:7fca1bf48117 291 p->aUp[0].sName = "Terminal";
0x6d61726b 0:7fca1bf48117 292 p->aUp[0].pBuffer = _acUpBuffer;
0x6d61726b 0:7fca1bf48117 293 p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer);
0x6d61726b 0:7fca1bf48117 294 p->aUp[0].RdOff = 0u;
0x6d61726b 0:7fca1bf48117 295 p->aUp[0].WrOff = 0u;
0x6d61726b 0:7fca1bf48117 296 p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT;
0x6d61726b 0:7fca1bf48117 297 //
0x6d61726b 0:7fca1bf48117 298 // Initialize down buffer 0
0x6d61726b 0:7fca1bf48117 299 //
0x6d61726b 0:7fca1bf48117 300 p->aDown[0].sName = "Terminal";
0x6d61726b 0:7fca1bf48117 301 p->aDown[0].pBuffer = _acDownBuffer;
0x6d61726b 0:7fca1bf48117 302 p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer);
0x6d61726b 0:7fca1bf48117 303 p->aDown[0].RdOff = 0u;
0x6d61726b 0:7fca1bf48117 304 p->aDown[0].WrOff = 0u;
0x6d61726b 0:7fca1bf48117 305 p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT;
0x6d61726b 0:7fca1bf48117 306 //
0x6d61726b 0:7fca1bf48117 307 // Finish initialization of the control block.
0x6d61726b 0:7fca1bf48117 308 // Copy Id string in three steps to make sure "SEGGER RTT" is not found
0x6d61726b 0:7fca1bf48117 309 // in initializer memory (usually flash) by J-Link
0x6d61726b 0:7fca1bf48117 310 //
0x6d61726b 0:7fca1bf48117 311 strcpy(&p->acID[7], "RTT");
0x6d61726b 0:7fca1bf48117 312 strcpy(&p->acID[0], "SEGGER");
0x6d61726b 0:7fca1bf48117 313 p->acID[6] = ' ';
0x6d61726b 0:7fca1bf48117 314 }
0x6d61726b 0:7fca1bf48117 315
0x6d61726b 0:7fca1bf48117 316 /*********************************************************************
0x6d61726b 0:7fca1bf48117 317 *
0x6d61726b 0:7fca1bf48117 318 * _WriteBlocking()
0x6d61726b 0:7fca1bf48117 319 *
0x6d61726b 0:7fca1bf48117 320 * Function description
0x6d61726b 0:7fca1bf48117 321 * Stores a specified number of characters in SEGGER RTT ring buffer
0x6d61726b 0:7fca1bf48117 322 * and updates the associated write pointer which is periodically
0x6d61726b 0:7fca1bf48117 323 * read by the host.
0x6d61726b 0:7fca1bf48117 324 * The caller is responsible for managing the write chunk sizes as
0x6d61726b 0:7fca1bf48117 325 * _WriteBlocking() will block until all data has been posted successfully.
0x6d61726b 0:7fca1bf48117 326 *
0x6d61726b 0:7fca1bf48117 327 * Parameters
0x6d61726b 0:7fca1bf48117 328 * pRing Ring buffer to post to.
0x6d61726b 0:7fca1bf48117 329 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
0x6d61726b 0:7fca1bf48117 330 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 331 *
0x6d61726b 0:7fca1bf48117 332 * Return value
0x6d61726b 0:7fca1bf48117 333 * >= 0 - Number of bytes written into buffer.
0x6d61726b 0:7fca1bf48117 334 */
0x6d61726b 0:7fca1bf48117 335 static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) {
0x6d61726b 0:7fca1bf48117 336 unsigned NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 337 unsigned NumBytesWritten;
0x6d61726b 0:7fca1bf48117 338 unsigned RdOff;
0x6d61726b 0:7fca1bf48117 339 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 340 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 341 char* pDst;
0x6d61726b 0:7fca1bf48117 342 #endif
0x6d61726b 0:7fca1bf48117 343 //
0x6d61726b 0:7fca1bf48117 344 // Write data to buffer and handle wrap-around if necessary
0x6d61726b 0:7fca1bf48117 345 //
0x6d61726b 0:7fca1bf48117 346 NumBytesWritten = 0u;
0x6d61726b 0:7fca1bf48117 347 WrOff = pRing->WrOff;
0x6d61726b 0:7fca1bf48117 348 do {
0x6d61726b 0:7fca1bf48117 349 RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime
0x6d61726b 0:7fca1bf48117 350 if (RdOff > WrOff) {
0x6d61726b 0:7fca1bf48117 351 NumBytesToWrite = RdOff - WrOff - 1u;
0x6d61726b 0:7fca1bf48117 352 } else {
0x6d61726b 0:7fca1bf48117 353 NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u);
0x6d61726b 0:7fca1bf48117 354 }
0x6d61726b 0:7fca1bf48117 355 NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around
0x6d61726b 0:7fca1bf48117 356 NumBytesToWrite = MIN(NumBytesToWrite, NumBytes);
0x6d61726b 0:7fca1bf48117 357 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 358 pDst = pRing->pBuffer + WrOff;
0x6d61726b 0:7fca1bf48117 359 NumBytesWritten += NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 360 NumBytes -= NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 361 WrOff += NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 362 while (NumBytesToWrite--) {
0x6d61726b 0:7fca1bf48117 363 *pDst++ = *pBuffer++;
0x6d61726b 0:7fca1bf48117 364 };
0x6d61726b 0:7fca1bf48117 365 #else
0x6d61726b 0:7fca1bf48117 366 SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite);
0x6d61726b 0:7fca1bf48117 367 NumBytesWritten += NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 368 pBuffer += NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 369 NumBytes -= NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 370 WrOff += NumBytesToWrite;
0x6d61726b 0:7fca1bf48117 371 #endif
0x6d61726b 0:7fca1bf48117 372 if (WrOff == pRing->SizeOfBuffer) {
0x6d61726b 0:7fca1bf48117 373 WrOff = 0u;
0x6d61726b 0:7fca1bf48117 374 }
0x6d61726b 0:7fca1bf48117 375 pRing->WrOff = WrOff;
0x6d61726b 0:7fca1bf48117 376 } while (NumBytes);
0x6d61726b 0:7fca1bf48117 377 //
0x6d61726b 0:7fca1bf48117 378 return NumBytesWritten;
0x6d61726b 0:7fca1bf48117 379 }
0x6d61726b 0:7fca1bf48117 380
0x6d61726b 0:7fca1bf48117 381 /*********************************************************************
0x6d61726b 0:7fca1bf48117 382 *
0x6d61726b 0:7fca1bf48117 383 * _WriteNoCheck()
0x6d61726b 0:7fca1bf48117 384 *
0x6d61726b 0:7fca1bf48117 385 * Function description
0x6d61726b 0:7fca1bf48117 386 * Stores a specified number of characters in SEGGER RTT ring buffer
0x6d61726b 0:7fca1bf48117 387 * and updates the associated write pointer which is periodically
0x6d61726b 0:7fca1bf48117 388 * read by the host.
0x6d61726b 0:7fca1bf48117 389 * It is callers responsibility to make sure data actually fits in buffer.
0x6d61726b 0:7fca1bf48117 390 *
0x6d61726b 0:7fca1bf48117 391 * Parameters
0x6d61726b 0:7fca1bf48117 392 * pRing Ring buffer to post to.
0x6d61726b 0:7fca1bf48117 393 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
0x6d61726b 0:7fca1bf48117 394 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 395 *
0x6d61726b 0:7fca1bf48117 396 * Notes
0x6d61726b 0:7fca1bf48117 397 * (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking
0x6d61726b 0:7fca1bf48117 398 */
0x6d61726b 0:7fca1bf48117 399 static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) {
0x6d61726b 0:7fca1bf48117 400 unsigned NumBytesAtOnce;
0x6d61726b 0:7fca1bf48117 401 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 402 unsigned Rem;
0x6d61726b 0:7fca1bf48117 403 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 404 char* pDst;
0x6d61726b 0:7fca1bf48117 405 #endif
0x6d61726b 0:7fca1bf48117 406
0x6d61726b 0:7fca1bf48117 407 WrOff = pRing->WrOff;
0x6d61726b 0:7fca1bf48117 408 Rem = pRing->SizeOfBuffer - WrOff;
0x6d61726b 0:7fca1bf48117 409 if (Rem > NumBytes) {
0x6d61726b 0:7fca1bf48117 410 //
0x6d61726b 0:7fca1bf48117 411 // All data fits before wrap around
0x6d61726b 0:7fca1bf48117 412 //
0x6d61726b 0:7fca1bf48117 413 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 414 pDst = pRing->pBuffer + WrOff;
0x6d61726b 0:7fca1bf48117 415 WrOff += NumBytes;
0x6d61726b 0:7fca1bf48117 416 while (NumBytes--) {
0x6d61726b 0:7fca1bf48117 417 *pDst++ = *pData++;
0x6d61726b 0:7fca1bf48117 418 };
0x6d61726b 0:7fca1bf48117 419 pRing->WrOff = WrOff;
0x6d61726b 0:7fca1bf48117 420 #else
0x6d61726b 0:7fca1bf48117 421 SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes);
0x6d61726b 0:7fca1bf48117 422 pRing->WrOff = WrOff + NumBytes;
0x6d61726b 0:7fca1bf48117 423 #endif
0x6d61726b 0:7fca1bf48117 424 } else {
0x6d61726b 0:7fca1bf48117 425 //
0x6d61726b 0:7fca1bf48117 426 // We reach the end of the buffer, so need to wrap around
0x6d61726b 0:7fca1bf48117 427 //
0x6d61726b 0:7fca1bf48117 428 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 429 pDst = pRing->pBuffer + WrOff;
0x6d61726b 0:7fca1bf48117 430 NumBytesAtOnce = Rem;
0x6d61726b 0:7fca1bf48117 431 while (NumBytesAtOnce--) {
0x6d61726b 0:7fca1bf48117 432 *pDst++ = *pData++;
0x6d61726b 0:7fca1bf48117 433 };
0x6d61726b 0:7fca1bf48117 434 pDst = pRing->pBuffer;
0x6d61726b 0:7fca1bf48117 435 NumBytesAtOnce = NumBytes - Rem;
0x6d61726b 0:7fca1bf48117 436 while (NumBytesAtOnce--) {
0x6d61726b 0:7fca1bf48117 437 *pDst++ = *pData++;
0x6d61726b 0:7fca1bf48117 438 };
0x6d61726b 0:7fca1bf48117 439 pRing->WrOff = NumBytes - Rem;
0x6d61726b 0:7fca1bf48117 440 #else
0x6d61726b 0:7fca1bf48117 441 NumBytesAtOnce = Rem;
0x6d61726b 0:7fca1bf48117 442 SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce);
0x6d61726b 0:7fca1bf48117 443 NumBytesAtOnce = NumBytes - Rem;
0x6d61726b 0:7fca1bf48117 444 SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce);
0x6d61726b 0:7fca1bf48117 445 pRing->WrOff = NumBytesAtOnce;
0x6d61726b 0:7fca1bf48117 446 #endif
0x6d61726b 0:7fca1bf48117 447 }
0x6d61726b 0:7fca1bf48117 448 }
0x6d61726b 0:7fca1bf48117 449
0x6d61726b 0:7fca1bf48117 450 /*********************************************************************
0x6d61726b 0:7fca1bf48117 451 *
0x6d61726b 0:7fca1bf48117 452 * _PostTerminalSwitch()
0x6d61726b 0:7fca1bf48117 453 *
0x6d61726b 0:7fca1bf48117 454 * Function description
0x6d61726b 0:7fca1bf48117 455 * Switch terminal to the given terminal ID. It is the caller's
0x6d61726b 0:7fca1bf48117 456 * responsibility to ensure the terminal ID is correct and there is
0x6d61726b 0:7fca1bf48117 457 * enough space in the buffer for this to complete successfully.
0x6d61726b 0:7fca1bf48117 458 *
0x6d61726b 0:7fca1bf48117 459 * Parameters
0x6d61726b 0:7fca1bf48117 460 * pRing Ring buffer to post to.
0x6d61726b 0:7fca1bf48117 461 * TerminalId Terminal ID to switch to.
0x6d61726b 0:7fca1bf48117 462 */
0x6d61726b 0:7fca1bf48117 463 static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) {
0x6d61726b 0:7fca1bf48117 464 unsigned char ac[2];
0x6d61726b 0:7fca1bf48117 465
0x6d61726b 0:7fca1bf48117 466 ac[0] = 0xFFu;
0x6d61726b 0:7fca1bf48117 467 ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit
0x6d61726b 0:7fca1bf48117 468 _WriteBlocking(pRing, (const char*)ac, 2u);
0x6d61726b 0:7fca1bf48117 469 }
0x6d61726b 0:7fca1bf48117 470
0x6d61726b 0:7fca1bf48117 471 /*********************************************************************
0x6d61726b 0:7fca1bf48117 472 *
0x6d61726b 0:7fca1bf48117 473 * _GetAvailWriteSpace()
0x6d61726b 0:7fca1bf48117 474 *
0x6d61726b 0:7fca1bf48117 475 * Function description
0x6d61726b 0:7fca1bf48117 476 * Returns the number of bytes that can be written to the ring
0x6d61726b 0:7fca1bf48117 477 * buffer without blocking.
0x6d61726b 0:7fca1bf48117 478 *
0x6d61726b 0:7fca1bf48117 479 * Parameters
0x6d61726b 0:7fca1bf48117 480 * pRing Ring buffer to check.
0x6d61726b 0:7fca1bf48117 481 *
0x6d61726b 0:7fca1bf48117 482 * Return value
0x6d61726b 0:7fca1bf48117 483 * Number of bytes that are free in the buffer.
0x6d61726b 0:7fca1bf48117 484 */
0x6d61726b 0:7fca1bf48117 485 static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) {
0x6d61726b 0:7fca1bf48117 486 unsigned RdOff;
0x6d61726b 0:7fca1bf48117 487 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 488 unsigned r;
0x6d61726b 0:7fca1bf48117 489 //
0x6d61726b 0:7fca1bf48117 490 // Avoid warnings regarding volatile access order. It's not a problem
0x6d61726b 0:7fca1bf48117 491 // in this case, but dampen compiler enthusiasm.
0x6d61726b 0:7fca1bf48117 492 //
0x6d61726b 0:7fca1bf48117 493 RdOff = pRing->RdOff;
0x6d61726b 0:7fca1bf48117 494 WrOff = pRing->WrOff;
0x6d61726b 0:7fca1bf48117 495 if (RdOff <= WrOff) {
0x6d61726b 0:7fca1bf48117 496 r = pRing->SizeOfBuffer - 1u - WrOff + RdOff;
0x6d61726b 0:7fca1bf48117 497 } else {
0x6d61726b 0:7fca1bf48117 498 r = RdOff - WrOff - 1u;
0x6d61726b 0:7fca1bf48117 499 }
0x6d61726b 0:7fca1bf48117 500 return r;
0x6d61726b 0:7fca1bf48117 501 }
0x6d61726b 0:7fca1bf48117 502
0x6d61726b 0:7fca1bf48117 503 /*********************************************************************
0x6d61726b 0:7fca1bf48117 504 *
0x6d61726b 0:7fca1bf48117 505 * Public code
0x6d61726b 0:7fca1bf48117 506 *
0x6d61726b 0:7fca1bf48117 507 **********************************************************************
0x6d61726b 0:7fca1bf48117 508 */
0x6d61726b 0:7fca1bf48117 509 /*********************************************************************
0x6d61726b 0:7fca1bf48117 510 *
0x6d61726b 0:7fca1bf48117 511 * SEGGER_RTT_ReadNoLock()
0x6d61726b 0:7fca1bf48117 512 *
0x6d61726b 0:7fca1bf48117 513 * Function description
0x6d61726b 0:7fca1bf48117 514 * Reads characters from SEGGER real-time-terminal control block
0x6d61726b 0:7fca1bf48117 515 * which have been previously stored by the host.
0x6d61726b 0:7fca1bf48117 516 * Do not lock against interrupts and multiple access.
0x6d61726b 0:7fca1bf48117 517 *
0x6d61726b 0:7fca1bf48117 518 * Parameters
0x6d61726b 0:7fca1bf48117 519 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 520 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
0x6d61726b 0:7fca1bf48117 521 * BufferSize Size of the target application buffer.
0x6d61726b 0:7fca1bf48117 522 *
0x6d61726b 0:7fca1bf48117 523 * Return value
0x6d61726b 0:7fca1bf48117 524 * Number of bytes that have been read.
0x6d61726b 0:7fca1bf48117 525 */
0x6d61726b 0:7fca1bf48117 526 unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
0x6d61726b 0:7fca1bf48117 527 unsigned NumBytesRem;
0x6d61726b 0:7fca1bf48117 528 unsigned NumBytesRead;
0x6d61726b 0:7fca1bf48117 529 unsigned RdOff;
0x6d61726b 0:7fca1bf48117 530 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 531 unsigned char* pBuffer;
0x6d61726b 0:7fca1bf48117 532 SEGGER_RTT_BUFFER_DOWN* pRing;
0x6d61726b 0:7fca1bf48117 533 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 534 const char* pSrc;
0x6d61726b 0:7fca1bf48117 535 #endif
0x6d61726b 0:7fca1bf48117 536 //
0x6d61726b 0:7fca1bf48117 537 INIT();
0x6d61726b 0:7fca1bf48117 538 pRing = &_SEGGER_RTT.aDown[BufferIndex];
0x6d61726b 0:7fca1bf48117 539 pBuffer = (unsigned char*)pData;
0x6d61726b 0:7fca1bf48117 540 RdOff = pRing->RdOff;
0x6d61726b 0:7fca1bf48117 541 WrOff = pRing->WrOff;
0x6d61726b 0:7fca1bf48117 542 NumBytesRead = 0u;
0x6d61726b 0:7fca1bf48117 543 //
0x6d61726b 0:7fca1bf48117 544 // Read from current read position to wrap-around of buffer, first
0x6d61726b 0:7fca1bf48117 545 //
0x6d61726b 0:7fca1bf48117 546 if (RdOff > WrOff) {
0x6d61726b 0:7fca1bf48117 547 NumBytesRem = pRing->SizeOfBuffer - RdOff;
0x6d61726b 0:7fca1bf48117 548 NumBytesRem = MIN(NumBytesRem, BufferSize);
0x6d61726b 0:7fca1bf48117 549 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 550 pSrc = pRing->pBuffer + RdOff;
0x6d61726b 0:7fca1bf48117 551 NumBytesRead += NumBytesRem;
0x6d61726b 0:7fca1bf48117 552 BufferSize -= NumBytesRem;
0x6d61726b 0:7fca1bf48117 553 RdOff += NumBytesRem;
0x6d61726b 0:7fca1bf48117 554 while (NumBytesRem--) {
0x6d61726b 0:7fca1bf48117 555 *pBuffer++ = *pSrc++;
0x6d61726b 0:7fca1bf48117 556 };
0x6d61726b 0:7fca1bf48117 557 #else
0x6d61726b 0:7fca1bf48117 558 SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
0x6d61726b 0:7fca1bf48117 559 NumBytesRead += NumBytesRem;
0x6d61726b 0:7fca1bf48117 560 pBuffer += NumBytesRem;
0x6d61726b 0:7fca1bf48117 561 BufferSize -= NumBytesRem;
0x6d61726b 0:7fca1bf48117 562 RdOff += NumBytesRem;
0x6d61726b 0:7fca1bf48117 563 #endif
0x6d61726b 0:7fca1bf48117 564 //
0x6d61726b 0:7fca1bf48117 565 // Handle wrap-around of buffer
0x6d61726b 0:7fca1bf48117 566 //
0x6d61726b 0:7fca1bf48117 567 if (RdOff == pRing->SizeOfBuffer) {
0x6d61726b 0:7fca1bf48117 568 RdOff = 0u;
0x6d61726b 0:7fca1bf48117 569 }
0x6d61726b 0:7fca1bf48117 570 }
0x6d61726b 0:7fca1bf48117 571 //
0x6d61726b 0:7fca1bf48117 572 // Read remaining items of buffer
0x6d61726b 0:7fca1bf48117 573 //
0x6d61726b 0:7fca1bf48117 574 NumBytesRem = WrOff - RdOff;
0x6d61726b 0:7fca1bf48117 575 NumBytesRem = MIN(NumBytesRem, BufferSize);
0x6d61726b 0:7fca1bf48117 576 if (NumBytesRem > 0u) {
0x6d61726b 0:7fca1bf48117 577 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 578 pSrc = pRing->pBuffer + RdOff;
0x6d61726b 0:7fca1bf48117 579 NumBytesRead += NumBytesRem;
0x6d61726b 0:7fca1bf48117 580 BufferSize -= NumBytesRem;
0x6d61726b 0:7fca1bf48117 581 RdOff += NumBytesRem;
0x6d61726b 0:7fca1bf48117 582 while (NumBytesRem--) {
0x6d61726b 0:7fca1bf48117 583 *pBuffer++ = *pSrc++;
0x6d61726b 0:7fca1bf48117 584 };
0x6d61726b 0:7fca1bf48117 585 #else
0x6d61726b 0:7fca1bf48117 586 SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
0x6d61726b 0:7fca1bf48117 587 NumBytesRead += NumBytesRem;
0x6d61726b 0:7fca1bf48117 588 pBuffer += NumBytesRem;
0x6d61726b 0:7fca1bf48117 589 BufferSize -= NumBytesRem;
0x6d61726b 0:7fca1bf48117 590 RdOff += NumBytesRem;
0x6d61726b 0:7fca1bf48117 591 #endif
0x6d61726b 0:7fca1bf48117 592 }
0x6d61726b 0:7fca1bf48117 593 if (NumBytesRead) {
0x6d61726b 0:7fca1bf48117 594 pRing->RdOff = RdOff;
0x6d61726b 0:7fca1bf48117 595 }
0x6d61726b 0:7fca1bf48117 596 //
0x6d61726b 0:7fca1bf48117 597 return NumBytesRead;
0x6d61726b 0:7fca1bf48117 598 }
0x6d61726b 0:7fca1bf48117 599
0x6d61726b 0:7fca1bf48117 600 /*********************************************************************
0x6d61726b 0:7fca1bf48117 601 *
0x6d61726b 0:7fca1bf48117 602 * SEGGER_RTT_Read
0x6d61726b 0:7fca1bf48117 603 *
0x6d61726b 0:7fca1bf48117 604 * Function description
0x6d61726b 0:7fca1bf48117 605 * Reads characters from SEGGER real-time-terminal control block
0x6d61726b 0:7fca1bf48117 606 * which have been previously stored by the host.
0x6d61726b 0:7fca1bf48117 607 *
0x6d61726b 0:7fca1bf48117 608 * Parameters
0x6d61726b 0:7fca1bf48117 609 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 610 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
0x6d61726b 0:7fca1bf48117 611 * BufferSize Size of the target application buffer.
0x6d61726b 0:7fca1bf48117 612 *
0x6d61726b 0:7fca1bf48117 613 * Return value
0x6d61726b 0:7fca1bf48117 614 * Number of bytes that have been read.
0x6d61726b 0:7fca1bf48117 615 */
0x6d61726b 0:7fca1bf48117 616 unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) {
0x6d61726b 0:7fca1bf48117 617 unsigned NumBytesRead;
0x6d61726b 0:7fca1bf48117 618 //
0x6d61726b 0:7fca1bf48117 619 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 620 //
0x6d61726b 0:7fca1bf48117 621 // Call the non-locking read function
0x6d61726b 0:7fca1bf48117 622 //
0x6d61726b 0:7fca1bf48117 623 NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize);
0x6d61726b 0:7fca1bf48117 624 //
0x6d61726b 0:7fca1bf48117 625 // Finish up.
0x6d61726b 0:7fca1bf48117 626 //
0x6d61726b 0:7fca1bf48117 627 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 628 //
0x6d61726b 0:7fca1bf48117 629 return NumBytesRead;
0x6d61726b 0:7fca1bf48117 630 }
0x6d61726b 0:7fca1bf48117 631
0x6d61726b 0:7fca1bf48117 632 /*********************************************************************
0x6d61726b 0:7fca1bf48117 633 *
0x6d61726b 0:7fca1bf48117 634 * SEGGER_RTT_WriteWithOverwriteNoLock
0x6d61726b 0:7fca1bf48117 635 *
0x6d61726b 0:7fca1bf48117 636 * Function description
0x6d61726b 0:7fca1bf48117 637 * Stores a specified number of characters in SEGGER RTT
0x6d61726b 0:7fca1bf48117 638 * control block.
0x6d61726b 0:7fca1bf48117 639 * SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application
0x6d61726b 0:7fca1bf48117 640 * and overwrites data if the data does not fit into the buffer.
0x6d61726b 0:7fca1bf48117 641 *
0x6d61726b 0:7fca1bf48117 642 * Parameters
0x6d61726b 0:7fca1bf48117 643 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 644 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
0x6d61726b 0:7fca1bf48117 645 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 646 *
0x6d61726b 0:7fca1bf48117 647 * Notes
0x6d61726b 0:7fca1bf48117 648 * (1) If there is not enough space in the "Up"-buffer, data is overwritten.
0x6d61726b 0:7fca1bf48117 649 * (2) For performance reasons this function does not call Init()
0x6d61726b 0:7fca1bf48117 650 * and may only be called after RTT has been initialized.
0x6d61726b 0:7fca1bf48117 651 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
0x6d61726b 0:7fca1bf48117 652 * (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link
0x6d61726b 0:7fca1bf48117 653 * connection reads RTT data.
0x6d61726b 0:7fca1bf48117 654 */
0x6d61726b 0:7fca1bf48117 655 void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
0x6d61726b 0:7fca1bf48117 656 const char* pData;
0x6d61726b 0:7fca1bf48117 657 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 658 unsigned Avail;
0x6d61726b 0:7fca1bf48117 659 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 660 char* pDst;
0x6d61726b 0:7fca1bf48117 661 #endif
0x6d61726b 0:7fca1bf48117 662
0x6d61726b 0:7fca1bf48117 663 pData = (const char *)pBuffer;
0x6d61726b 0:7fca1bf48117 664 //
0x6d61726b 0:7fca1bf48117 665 // Get "to-host" ring buffer and copy some elements into local variables.
0x6d61726b 0:7fca1bf48117 666 //
0x6d61726b 0:7fca1bf48117 667 pRing = &_SEGGER_RTT.aUp[BufferIndex];
0x6d61726b 0:7fca1bf48117 668 //
0x6d61726b 0:7fca1bf48117 669 // Check if we will overwrite data and need to adjust the RdOff.
0x6d61726b 0:7fca1bf48117 670 //
0x6d61726b 0:7fca1bf48117 671 if (pRing->WrOff == pRing->RdOff) {
0x6d61726b 0:7fca1bf48117 672 Avail = pRing->SizeOfBuffer - 1u;
0x6d61726b 0:7fca1bf48117 673 } else if ( pRing->WrOff < pRing->RdOff) {
0x6d61726b 0:7fca1bf48117 674 Avail = pRing->RdOff - pRing->WrOff - 1u;
0x6d61726b 0:7fca1bf48117 675 } else {
0x6d61726b 0:7fca1bf48117 676 Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer;
0x6d61726b 0:7fca1bf48117 677 }
0x6d61726b 0:7fca1bf48117 678 if (NumBytes > Avail) {
0x6d61726b 0:7fca1bf48117 679 pRing->RdOff += (NumBytes - Avail);
0x6d61726b 0:7fca1bf48117 680 while (pRing->RdOff >= pRing->SizeOfBuffer) {
0x6d61726b 0:7fca1bf48117 681 pRing->RdOff -= pRing->SizeOfBuffer;
0x6d61726b 0:7fca1bf48117 682 }
0x6d61726b 0:7fca1bf48117 683 }
0x6d61726b 0:7fca1bf48117 684 //
0x6d61726b 0:7fca1bf48117 685 // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds
0x6d61726b 0:7fca1bf48117 686 //
0x6d61726b 0:7fca1bf48117 687 Avail = pRing->SizeOfBuffer - pRing->WrOff;
0x6d61726b 0:7fca1bf48117 688 do {
0x6d61726b 0:7fca1bf48117 689 if (Avail > NumBytes) {
0x6d61726b 0:7fca1bf48117 690 //
0x6d61726b 0:7fca1bf48117 691 // Last round
0x6d61726b 0:7fca1bf48117 692 //
0x6d61726b 0:7fca1bf48117 693 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 694 pDst = pRing->pBuffer + pRing->WrOff;
0x6d61726b 0:7fca1bf48117 695 Avail = NumBytes;
0x6d61726b 0:7fca1bf48117 696 while (NumBytes--) {
0x6d61726b 0:7fca1bf48117 697 *pDst++ = *pData++;
0x6d61726b 0:7fca1bf48117 698 };
0x6d61726b 0:7fca1bf48117 699 pRing->WrOff += Avail;
0x6d61726b 0:7fca1bf48117 700 #else
0x6d61726b 0:7fca1bf48117 701 SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes);
0x6d61726b 0:7fca1bf48117 702 pRing->WrOff += NumBytes;
0x6d61726b 0:7fca1bf48117 703 #endif
0x6d61726b 0:7fca1bf48117 704 break;
0x6d61726b 0:7fca1bf48117 705 } else {
0x6d61726b 0:7fca1bf48117 706 //
0x6d61726b 0:7fca1bf48117 707 // Wrap-around necessary, write until wrap-around and reset WrOff
0x6d61726b 0:7fca1bf48117 708 //
0x6d61726b 0:7fca1bf48117 709 #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
0x6d61726b 0:7fca1bf48117 710 pDst = pRing->pBuffer + pRing->WrOff;
0x6d61726b 0:7fca1bf48117 711 NumBytes -= Avail;
0x6d61726b 0:7fca1bf48117 712 while (Avail--) {
0x6d61726b 0:7fca1bf48117 713 *pDst++ = *pData++;
0x6d61726b 0:7fca1bf48117 714 };
0x6d61726b 0:7fca1bf48117 715 pRing->WrOff = 0;
0x6d61726b 0:7fca1bf48117 716 #else
0x6d61726b 0:7fca1bf48117 717 SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail);
0x6d61726b 0:7fca1bf48117 718 pData += Avail;
0x6d61726b 0:7fca1bf48117 719 pRing->WrOff = 0;
0x6d61726b 0:7fca1bf48117 720 NumBytes -= Avail;
0x6d61726b 0:7fca1bf48117 721 #endif
0x6d61726b 0:7fca1bf48117 722 Avail = (pRing->SizeOfBuffer - 1);
0x6d61726b 0:7fca1bf48117 723 }
0x6d61726b 0:7fca1bf48117 724 } while (NumBytes);
0x6d61726b 0:7fca1bf48117 725 }
0x6d61726b 0:7fca1bf48117 726
0x6d61726b 0:7fca1bf48117 727 /*********************************************************************
0x6d61726b 0:7fca1bf48117 728 *
0x6d61726b 0:7fca1bf48117 729 * SEGGER_RTT_WriteSkipNoLock
0x6d61726b 0:7fca1bf48117 730 *
0x6d61726b 0:7fca1bf48117 731 * Function description
0x6d61726b 0:7fca1bf48117 732 * Stores a specified number of characters in SEGGER RTT
0x6d61726b 0:7fca1bf48117 733 * control block which is then read by the host.
0x6d61726b 0:7fca1bf48117 734 * SEGGER_RTT_WriteSkipNoLock does not lock the application and
0x6d61726b 0:7fca1bf48117 735 * skips all data, if the data does not fit into the buffer.
0x6d61726b 0:7fca1bf48117 736 *
0x6d61726b 0:7fca1bf48117 737 * Parameters
0x6d61726b 0:7fca1bf48117 738 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 739 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
0x6d61726b 0:7fca1bf48117 740 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 741 * MUST be > 0!!!
0x6d61726b 0:7fca1bf48117 742 * This is done for performance reasons, so no initial check has do be done.
0x6d61726b 0:7fca1bf48117 743 *
0x6d61726b 0:7fca1bf48117 744 * Return value
0x6d61726b 0:7fca1bf48117 745 * 1: Data has been copied
0x6d61726b 0:7fca1bf48117 746 * 0: No space, data has not been copied
0x6d61726b 0:7fca1bf48117 747 *
0x6d61726b 0:7fca1bf48117 748 * Notes
0x6d61726b 0:7fca1bf48117 749 * (1) If there is not enough space in the "Up"-buffer, all data is dropped.
0x6d61726b 0:7fca1bf48117 750 * (2) For performance reasons this function does not call Init()
0x6d61726b 0:7fca1bf48117 751 * and may only be called after RTT has been initialized.
0x6d61726b 0:7fca1bf48117 752 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
0x6d61726b 0:7fca1bf48117 753 */
0x6d61726b 0:7fca1bf48117 754 #if (RTT_USE_ASM == 0)
0x6d61726b 0:7fca1bf48117 755 unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
0x6d61726b 0:7fca1bf48117 756 const char* pData;
0x6d61726b 0:7fca1bf48117 757 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 758 unsigned Avail;
0x6d61726b 0:7fca1bf48117 759 unsigned RdOff;
0x6d61726b 0:7fca1bf48117 760 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 761 unsigned Rem;
0x6d61726b 0:7fca1bf48117 762 //
0x6d61726b 0:7fca1bf48117 763 // Cases:
0x6d61726b 0:7fca1bf48117 764 // 1) RdOff <= WrOff => Space until wrap-around is sufficient
0x6d61726b 0:7fca1bf48117 765 // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks)
0x6d61726b 0:7fca1bf48117 766 // 3) RdOff < WrOff => No space in buf
0x6d61726b 0:7fca1bf48117 767 // 4) RdOff > WrOff => Space is sufficient
0x6d61726b 0:7fca1bf48117 768 // 5) RdOff > WrOff => No space in buf
0x6d61726b 0:7fca1bf48117 769 //
0x6d61726b 0:7fca1bf48117 770 // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough
0x6d61726b 0:7fca1bf48117 771 //
0x6d61726b 0:7fca1bf48117 772 pData = (const char *)pBuffer;
0x6d61726b 0:7fca1bf48117 773 pRing = &_SEGGER_RTT.aUp[BufferIndex];
0x6d61726b 0:7fca1bf48117 774 RdOff = pRing->RdOff;
0x6d61726b 0:7fca1bf48117 775 WrOff = pRing->WrOff;
0x6d61726b 0:7fca1bf48117 776 if (RdOff <= WrOff) { // Case 1), 2) or 3)
0x6d61726b 0:7fca1bf48117 777 Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0)
0x6d61726b 0:7fca1bf48117 778 if (Avail >= NumBytes) { // Case 1)?
0x6d61726b 0:7fca1bf48117 779 CopyStraight:
0x6d61726b 0:7fca1bf48117 780 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
0x6d61726b 0:7fca1bf48117 781 pRing->WrOff = WrOff + NumBytes;
0x6d61726b 0:7fca1bf48117 782 return 1;
0x6d61726b 0:7fca1bf48117 783 }
0x6d61726b 0:7fca1bf48117 784 Avail += RdOff; // Space incl. wrap-around
0x6d61726b 0:7fca1bf48117 785 if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit)
0x6d61726b 0:7fca1bf48117 786 Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer
0x6d61726b 0:7fca1bf48117 787 memcpy(pRing->pBuffer + WrOff, pData, Rem); // Copy 1st chunk
0x6d61726b 0:7fca1bf48117 788 NumBytes -= Rem;
0x6d61726b 0:7fca1bf48117 789 //
0x6d61726b 0:7fca1bf48117 790 // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used
0x6d61726b 0:7fca1bf48117 791 // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element
0x6d61726b 0:7fca1bf48117 792 // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks
0x6d61726b 0:7fca1bf48117 793 // Therefore, check if 2nd memcpy is necessary at all
0x6d61726b 0:7fca1bf48117 794 //
0x6d61726b 0:7fca1bf48117 795 if (NumBytes) {
0x6d61726b 0:7fca1bf48117 796 memcpy(pRing->pBuffer, pData + Rem, NumBytes);
0x6d61726b 0:7fca1bf48117 797 }
0x6d61726b 0:7fca1bf48117 798 pRing->WrOff = NumBytes;
0x6d61726b 0:7fca1bf48117 799 return 1;
0x6d61726b 0:7fca1bf48117 800 }
0x6d61726b 0:7fca1bf48117 801 } else { // Potential case 4)
0x6d61726b 0:7fca1bf48117 802 Avail = RdOff - WrOff - 1u;
0x6d61726b 0:7fca1bf48117 803 if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit)
0x6d61726b 0:7fca1bf48117 804 goto CopyStraight;
0x6d61726b 0:7fca1bf48117 805 }
0x6d61726b 0:7fca1bf48117 806 }
0x6d61726b 0:7fca1bf48117 807 return 0; // No space in buffer
0x6d61726b 0:7fca1bf48117 808 }
0x6d61726b 0:7fca1bf48117 809 #endif
0x6d61726b 0:7fca1bf48117 810
0x6d61726b 0:7fca1bf48117 811 /*********************************************************************
0x6d61726b 0:7fca1bf48117 812 *
0x6d61726b 0:7fca1bf48117 813 * SEGGER_RTT_WriteNoLock
0x6d61726b 0:7fca1bf48117 814 *
0x6d61726b 0:7fca1bf48117 815 * Function description
0x6d61726b 0:7fca1bf48117 816 * Stores a specified number of characters in SEGGER RTT
0x6d61726b 0:7fca1bf48117 817 * control block which is then read by the host.
0x6d61726b 0:7fca1bf48117 818 * SEGGER_RTT_WriteNoLock does not lock the application.
0x6d61726b 0:7fca1bf48117 819 *
0x6d61726b 0:7fca1bf48117 820 * Parameters
0x6d61726b 0:7fca1bf48117 821 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 822 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
0x6d61726b 0:7fca1bf48117 823 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 824 *
0x6d61726b 0:7fca1bf48117 825 * Return value
0x6d61726b 0:7fca1bf48117 826 * Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 827 *
0x6d61726b 0:7fca1bf48117 828 * Notes
0x6d61726b 0:7fca1bf48117 829 * (1) Data is stored according to buffer flags.
0x6d61726b 0:7fca1bf48117 830 * (2) For performance reasons this function does not call Init()
0x6d61726b 0:7fca1bf48117 831 * and may only be called after RTT has been initialized.
0x6d61726b 0:7fca1bf48117 832 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
0x6d61726b 0:7fca1bf48117 833 */
0x6d61726b 0:7fca1bf48117 834 unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
0x6d61726b 0:7fca1bf48117 835 unsigned Status;
0x6d61726b 0:7fca1bf48117 836 unsigned Avail;
0x6d61726b 0:7fca1bf48117 837 const char* pData;
0x6d61726b 0:7fca1bf48117 838 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 839
0x6d61726b 0:7fca1bf48117 840 pData = (const char *)pBuffer;
0x6d61726b 0:7fca1bf48117 841 //
0x6d61726b 0:7fca1bf48117 842 // Get "to-host" ring buffer.
0x6d61726b 0:7fca1bf48117 843 //
0x6d61726b 0:7fca1bf48117 844 pRing = &_SEGGER_RTT.aUp[BufferIndex];
0x6d61726b 0:7fca1bf48117 845 //
0x6d61726b 0:7fca1bf48117 846 // How we output depends upon the mode...
0x6d61726b 0:7fca1bf48117 847 //
0x6d61726b 0:7fca1bf48117 848 switch (pRing->Flags) {
0x6d61726b 0:7fca1bf48117 849 case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
0x6d61726b 0:7fca1bf48117 850 //
0x6d61726b 0:7fca1bf48117 851 // If we are in skip mode and there is no space for the whole
0x6d61726b 0:7fca1bf48117 852 // of this output, don't bother.
0x6d61726b 0:7fca1bf48117 853 //
0x6d61726b 0:7fca1bf48117 854 Avail = _GetAvailWriteSpace(pRing);
0x6d61726b 0:7fca1bf48117 855 if (Avail < NumBytes) {
0x6d61726b 0:7fca1bf48117 856 Status = 0u;
0x6d61726b 0:7fca1bf48117 857 } else {
0x6d61726b 0:7fca1bf48117 858 Status = NumBytes;
0x6d61726b 0:7fca1bf48117 859 _WriteNoCheck(pRing, pData, NumBytes);
0x6d61726b 0:7fca1bf48117 860 }
0x6d61726b 0:7fca1bf48117 861 break;
0x6d61726b 0:7fca1bf48117 862 case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
0x6d61726b 0:7fca1bf48117 863 //
0x6d61726b 0:7fca1bf48117 864 // If we are in trim mode, trim to what we can output without blocking.
0x6d61726b 0:7fca1bf48117 865 //
0x6d61726b 0:7fca1bf48117 866 Avail = _GetAvailWriteSpace(pRing);
0x6d61726b 0:7fca1bf48117 867 Status = Avail < NumBytes ? Avail : NumBytes;
0x6d61726b 0:7fca1bf48117 868 _WriteNoCheck(pRing, pData, Status);
0x6d61726b 0:7fca1bf48117 869 break;
0x6d61726b 0:7fca1bf48117 870 case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
0x6d61726b 0:7fca1bf48117 871 //
0x6d61726b 0:7fca1bf48117 872 // If we are in blocking mode, output everything.
0x6d61726b 0:7fca1bf48117 873 //
0x6d61726b 0:7fca1bf48117 874 Status = _WriteBlocking(pRing, pData, NumBytes);
0x6d61726b 0:7fca1bf48117 875 break;
0x6d61726b 0:7fca1bf48117 876 default:
0x6d61726b 0:7fca1bf48117 877 Status = 0u;
0x6d61726b 0:7fca1bf48117 878 break;
0x6d61726b 0:7fca1bf48117 879 }
0x6d61726b 0:7fca1bf48117 880 //
0x6d61726b 0:7fca1bf48117 881 // Finish up.
0x6d61726b 0:7fca1bf48117 882 //
0x6d61726b 0:7fca1bf48117 883 return Status;
0x6d61726b 0:7fca1bf48117 884 }
0x6d61726b 0:7fca1bf48117 885
0x6d61726b 0:7fca1bf48117 886 /*********************************************************************
0x6d61726b 0:7fca1bf48117 887 *
0x6d61726b 0:7fca1bf48117 888 * SEGGER_RTT_Write
0x6d61726b 0:7fca1bf48117 889 *
0x6d61726b 0:7fca1bf48117 890 * Function description
0x6d61726b 0:7fca1bf48117 891 * Stores a specified number of characters in SEGGER RTT
0x6d61726b 0:7fca1bf48117 892 * control block which is then read by the host.
0x6d61726b 0:7fca1bf48117 893 *
0x6d61726b 0:7fca1bf48117 894 * Parameters
0x6d61726b 0:7fca1bf48117 895 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 896 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
0x6d61726b 0:7fca1bf48117 897 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 898 *
0x6d61726b 0:7fca1bf48117 899 * Return value
0x6d61726b 0:7fca1bf48117 900 * Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 901 *
0x6d61726b 0:7fca1bf48117 902 * Notes
0x6d61726b 0:7fca1bf48117 903 * (1) Data is stored according to buffer flags.
0x6d61726b 0:7fca1bf48117 904 */
0x6d61726b 0:7fca1bf48117 905 unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
0x6d61726b 0:7fca1bf48117 906 unsigned Status;
0x6d61726b 0:7fca1bf48117 907 //
0x6d61726b 0:7fca1bf48117 908 INIT();
0x6d61726b 0:7fca1bf48117 909 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 910 //
0x6d61726b 0:7fca1bf48117 911 // Call the non-locking write function
0x6d61726b 0:7fca1bf48117 912 //
0x6d61726b 0:7fca1bf48117 913 Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes);
0x6d61726b 0:7fca1bf48117 914 //
0x6d61726b 0:7fca1bf48117 915 // Finish up.
0x6d61726b 0:7fca1bf48117 916 //
0x6d61726b 0:7fca1bf48117 917 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 918 //
0x6d61726b 0:7fca1bf48117 919 return Status;
0x6d61726b 0:7fca1bf48117 920 }
0x6d61726b 0:7fca1bf48117 921
0x6d61726b 0:7fca1bf48117 922 /*********************************************************************
0x6d61726b 0:7fca1bf48117 923 *
0x6d61726b 0:7fca1bf48117 924 * SEGGER_RTT_WriteString
0x6d61726b 0:7fca1bf48117 925 *
0x6d61726b 0:7fca1bf48117 926 * Function description
0x6d61726b 0:7fca1bf48117 927 * Stores string in SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 928 * This data is read by the host.
0x6d61726b 0:7fca1bf48117 929 *
0x6d61726b 0:7fca1bf48117 930 * Parameters
0x6d61726b 0:7fca1bf48117 931 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 932 * s Pointer to string.
0x6d61726b 0:7fca1bf48117 933 *
0x6d61726b 0:7fca1bf48117 934 * Return value
0x6d61726b 0:7fca1bf48117 935 * Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 936 *
0x6d61726b 0:7fca1bf48117 937 * Notes
0x6d61726b 0:7fca1bf48117 938 * (1) Data is stored according to buffer flags.
0x6d61726b 0:7fca1bf48117 939 * (2) String passed to this function has to be \0 terminated
0x6d61726b 0:7fca1bf48117 940 * (3) \0 termination character is *not* stored in RTT buffer
0x6d61726b 0:7fca1bf48117 941 */
0x6d61726b 0:7fca1bf48117 942 unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
0x6d61726b 0:7fca1bf48117 943 unsigned Len;
0x6d61726b 0:7fca1bf48117 944
0x6d61726b 0:7fca1bf48117 945 Len = STRLEN(s);
0x6d61726b 0:7fca1bf48117 946 return SEGGER_RTT_Write(BufferIndex, s, Len);
0x6d61726b 0:7fca1bf48117 947 }
0x6d61726b 0:7fca1bf48117 948
0x6d61726b 0:7fca1bf48117 949 /*********************************************************************
0x6d61726b 0:7fca1bf48117 950 *
0x6d61726b 0:7fca1bf48117 951 * SEGGER_RTT_PutCharSkipNoLock
0x6d61726b 0:7fca1bf48117 952 *
0x6d61726b 0:7fca1bf48117 953 * Function description
0x6d61726b 0:7fca1bf48117 954 * Stores a single character/byte in SEGGER RTT buffer.
0x6d61726b 0:7fca1bf48117 955 * SEGGER_RTT_PutCharSkipNoLock does not lock the application and
0x6d61726b 0:7fca1bf48117 956 * skips the byte, if it does not fit into the buffer.
0x6d61726b 0:7fca1bf48117 957 *
0x6d61726b 0:7fca1bf48117 958 * Parameters
0x6d61726b 0:7fca1bf48117 959 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 960 * c Byte to be stored.
0x6d61726b 0:7fca1bf48117 961 *
0x6d61726b 0:7fca1bf48117 962 * Return value
0x6d61726b 0:7fca1bf48117 963 * Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 964 *
0x6d61726b 0:7fca1bf48117 965 * Notes
0x6d61726b 0:7fca1bf48117 966 * (1) If there is not enough space in the "Up"-buffer, the character is dropped.
0x6d61726b 0:7fca1bf48117 967 * (2) For performance reasons this function does not call Init()
0x6d61726b 0:7fca1bf48117 968 * and may only be called after RTT has been initialized.
0x6d61726b 0:7fca1bf48117 969 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
0x6d61726b 0:7fca1bf48117 970 */
0x6d61726b 0:7fca1bf48117 971
0x6d61726b 0:7fca1bf48117 972 unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) {
0x6d61726b 0:7fca1bf48117 973 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 974 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 975 unsigned Status;
0x6d61726b 0:7fca1bf48117 976 //
0x6d61726b 0:7fca1bf48117 977 // Get "to-host" ring buffer.
0x6d61726b 0:7fca1bf48117 978 //
0x6d61726b 0:7fca1bf48117 979 pRing = &_SEGGER_RTT.aUp[BufferIndex];
0x6d61726b 0:7fca1bf48117 980 //
0x6d61726b 0:7fca1bf48117 981 // Get write position and handle wrap-around if necessary
0x6d61726b 0:7fca1bf48117 982 //
0x6d61726b 0:7fca1bf48117 983 WrOff = pRing->WrOff + 1;
0x6d61726b 0:7fca1bf48117 984 if (WrOff == pRing->SizeOfBuffer) {
0x6d61726b 0:7fca1bf48117 985 WrOff = 0;
0x6d61726b 0:7fca1bf48117 986 }
0x6d61726b 0:7fca1bf48117 987 //
0x6d61726b 0:7fca1bf48117 988 // Output byte if free space is available
0x6d61726b 0:7fca1bf48117 989 //
0x6d61726b 0:7fca1bf48117 990 if (WrOff != pRing->RdOff) {
0x6d61726b 0:7fca1bf48117 991 pRing->pBuffer[pRing->WrOff] = c;
0x6d61726b 0:7fca1bf48117 992 pRing->WrOff = WrOff;
0x6d61726b 0:7fca1bf48117 993 Status = 1;
0x6d61726b 0:7fca1bf48117 994 } else {
0x6d61726b 0:7fca1bf48117 995 Status = 0;
0x6d61726b 0:7fca1bf48117 996 }
0x6d61726b 0:7fca1bf48117 997 //
0x6d61726b 0:7fca1bf48117 998 return Status;
0x6d61726b 0:7fca1bf48117 999 }
0x6d61726b 0:7fca1bf48117 1000
0x6d61726b 0:7fca1bf48117 1001 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1002 *
0x6d61726b 0:7fca1bf48117 1003 * SEGGER_RTT_PutCharSkip
0x6d61726b 0:7fca1bf48117 1004 *
0x6d61726b 0:7fca1bf48117 1005 * Function description
0x6d61726b 0:7fca1bf48117 1006 * Stores a single character/byte in SEGGER RTT buffer.
0x6d61726b 0:7fca1bf48117 1007 *
0x6d61726b 0:7fca1bf48117 1008 * Parameters
0x6d61726b 0:7fca1bf48117 1009 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 1010 * c Byte to be stored.
0x6d61726b 0:7fca1bf48117 1011 *
0x6d61726b 0:7fca1bf48117 1012 * Return value
0x6d61726b 0:7fca1bf48117 1013 * Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 1014 *
0x6d61726b 0:7fca1bf48117 1015 * Notes
0x6d61726b 0:7fca1bf48117 1016 * (1) If there is not enough space in the "Up"-buffer, the character is dropped.
0x6d61726b 0:7fca1bf48117 1017 */
0x6d61726b 0:7fca1bf48117 1018
0x6d61726b 0:7fca1bf48117 1019 unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) {
0x6d61726b 0:7fca1bf48117 1020 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 1021 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 1022 unsigned Status;
0x6d61726b 0:7fca1bf48117 1023 //
0x6d61726b 0:7fca1bf48117 1024 // Prepare
0x6d61726b 0:7fca1bf48117 1025 //
0x6d61726b 0:7fca1bf48117 1026 INIT();
0x6d61726b 0:7fca1bf48117 1027 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1028 //
0x6d61726b 0:7fca1bf48117 1029 // Get "to-host" ring buffer.
0x6d61726b 0:7fca1bf48117 1030 //
0x6d61726b 0:7fca1bf48117 1031 pRing = &_SEGGER_RTT.aUp[BufferIndex];
0x6d61726b 0:7fca1bf48117 1032 //
0x6d61726b 0:7fca1bf48117 1033 // Get write position and handle wrap-around if necessary
0x6d61726b 0:7fca1bf48117 1034 //
0x6d61726b 0:7fca1bf48117 1035 WrOff = pRing->WrOff + 1;
0x6d61726b 0:7fca1bf48117 1036 if (WrOff == pRing->SizeOfBuffer) {
0x6d61726b 0:7fca1bf48117 1037 WrOff = 0;
0x6d61726b 0:7fca1bf48117 1038 }
0x6d61726b 0:7fca1bf48117 1039 //
0x6d61726b 0:7fca1bf48117 1040 // Output byte if free space is available
0x6d61726b 0:7fca1bf48117 1041 //
0x6d61726b 0:7fca1bf48117 1042 if (WrOff != pRing->RdOff) {
0x6d61726b 0:7fca1bf48117 1043 pRing->pBuffer[pRing->WrOff] = c;
0x6d61726b 0:7fca1bf48117 1044 pRing->WrOff = WrOff;
0x6d61726b 0:7fca1bf48117 1045 Status = 1;
0x6d61726b 0:7fca1bf48117 1046 } else {
0x6d61726b 0:7fca1bf48117 1047 Status = 0;
0x6d61726b 0:7fca1bf48117 1048 }
0x6d61726b 0:7fca1bf48117 1049 //
0x6d61726b 0:7fca1bf48117 1050 // Finish up.
0x6d61726b 0:7fca1bf48117 1051 //
0x6d61726b 0:7fca1bf48117 1052 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1053 //
0x6d61726b 0:7fca1bf48117 1054 return Status;
0x6d61726b 0:7fca1bf48117 1055 }
0x6d61726b 0:7fca1bf48117 1056
0x6d61726b 0:7fca1bf48117 1057 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1058 *
0x6d61726b 0:7fca1bf48117 1059 * SEGGER_RTT_PutChar
0x6d61726b 0:7fca1bf48117 1060 *
0x6d61726b 0:7fca1bf48117 1061 * Function description
0x6d61726b 0:7fca1bf48117 1062 * Stores a single character/byte in SEGGER RTT buffer.
0x6d61726b 0:7fca1bf48117 1063 *
0x6d61726b 0:7fca1bf48117 1064 * Parameters
0x6d61726b 0:7fca1bf48117 1065 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
0x6d61726b 0:7fca1bf48117 1066 * c Byte to be stored.
0x6d61726b 0:7fca1bf48117 1067 *
0x6d61726b 0:7fca1bf48117 1068 * Return value
0x6d61726b 0:7fca1bf48117 1069 * Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 1070 *
0x6d61726b 0:7fca1bf48117 1071 * Notes
0x6d61726b 0:7fca1bf48117 1072 * (1) Data is stored according to buffer flags.
0x6d61726b 0:7fca1bf48117 1073 */
0x6d61726b 0:7fca1bf48117 1074
0x6d61726b 0:7fca1bf48117 1075 unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) {
0x6d61726b 0:7fca1bf48117 1076 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 1077 unsigned WrOff;
0x6d61726b 0:7fca1bf48117 1078 unsigned Status;
0x6d61726b 0:7fca1bf48117 1079 //
0x6d61726b 0:7fca1bf48117 1080 // Prepare
0x6d61726b 0:7fca1bf48117 1081 //
0x6d61726b 0:7fca1bf48117 1082 INIT();
0x6d61726b 0:7fca1bf48117 1083 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1084 //
0x6d61726b 0:7fca1bf48117 1085 // Get "to-host" ring buffer.
0x6d61726b 0:7fca1bf48117 1086 //
0x6d61726b 0:7fca1bf48117 1087 pRing = &_SEGGER_RTT.aUp[BufferIndex];
0x6d61726b 0:7fca1bf48117 1088 //
0x6d61726b 0:7fca1bf48117 1089 // Get write position and handle wrap-around if necessary
0x6d61726b 0:7fca1bf48117 1090 //
0x6d61726b 0:7fca1bf48117 1091 WrOff = pRing->WrOff + 1;
0x6d61726b 0:7fca1bf48117 1092 if (WrOff == pRing->SizeOfBuffer) {
0x6d61726b 0:7fca1bf48117 1093 WrOff = 0;
0x6d61726b 0:7fca1bf48117 1094 }
0x6d61726b 0:7fca1bf48117 1095 //
0x6d61726b 0:7fca1bf48117 1096 // Wait for free space if mode is set to blocking
0x6d61726b 0:7fca1bf48117 1097 //
0x6d61726b 0:7fca1bf48117 1098 if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
0x6d61726b 0:7fca1bf48117 1099 while (WrOff == pRing->RdOff) {
0x6d61726b 0:7fca1bf48117 1100 ;
0x6d61726b 0:7fca1bf48117 1101 }
0x6d61726b 0:7fca1bf48117 1102 }
0x6d61726b 0:7fca1bf48117 1103 //
0x6d61726b 0:7fca1bf48117 1104 // Output byte if free space is available
0x6d61726b 0:7fca1bf48117 1105 //
0x6d61726b 0:7fca1bf48117 1106 if (WrOff != pRing->RdOff) {
0x6d61726b 0:7fca1bf48117 1107 pRing->pBuffer[pRing->WrOff] = c;
0x6d61726b 0:7fca1bf48117 1108 pRing->WrOff = WrOff;
0x6d61726b 0:7fca1bf48117 1109 Status = 1;
0x6d61726b 0:7fca1bf48117 1110 } else {
0x6d61726b 0:7fca1bf48117 1111 Status = 0;
0x6d61726b 0:7fca1bf48117 1112 }
0x6d61726b 0:7fca1bf48117 1113 //
0x6d61726b 0:7fca1bf48117 1114 // Finish up.
0x6d61726b 0:7fca1bf48117 1115 //
0x6d61726b 0:7fca1bf48117 1116 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1117 //
0x6d61726b 0:7fca1bf48117 1118 return Status;
0x6d61726b 0:7fca1bf48117 1119 }
0x6d61726b 0:7fca1bf48117 1120
0x6d61726b 0:7fca1bf48117 1121 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1122 *
0x6d61726b 0:7fca1bf48117 1123 * SEGGER_RTT_GetKey
0x6d61726b 0:7fca1bf48117 1124 *
0x6d61726b 0:7fca1bf48117 1125 * Function description
0x6d61726b 0:7fca1bf48117 1126 * Reads one character from the SEGGER RTT buffer.
0x6d61726b 0:7fca1bf48117 1127 * Host has previously stored data there.
0x6d61726b 0:7fca1bf48117 1128 *
0x6d61726b 0:7fca1bf48117 1129 * Return value
0x6d61726b 0:7fca1bf48117 1130 * < 0 - No character available (buffer empty).
0x6d61726b 0:7fca1bf48117 1131 * >= 0 - Character which has been read. (Possible values: 0 - 255)
0x6d61726b 0:7fca1bf48117 1132 *
0x6d61726b 0:7fca1bf48117 1133 * Notes
0x6d61726b 0:7fca1bf48117 1134 * (1) This function is only specified for accesses to RTT buffer 0.
0x6d61726b 0:7fca1bf48117 1135 */
0x6d61726b 0:7fca1bf48117 1136 int SEGGER_RTT_GetKey(void) {
0x6d61726b 0:7fca1bf48117 1137 char c;
0x6d61726b 0:7fca1bf48117 1138 int r;
0x6d61726b 0:7fca1bf48117 1139
0x6d61726b 0:7fca1bf48117 1140 r = (int)SEGGER_RTT_Read(0u, &c, 1u);
0x6d61726b 0:7fca1bf48117 1141 if (r == 1) {
0x6d61726b 0:7fca1bf48117 1142 r = (int)(unsigned char)c;
0x6d61726b 0:7fca1bf48117 1143 } else {
0x6d61726b 0:7fca1bf48117 1144 r = -1;
0x6d61726b 0:7fca1bf48117 1145 }
0x6d61726b 0:7fca1bf48117 1146 return r;
0x6d61726b 0:7fca1bf48117 1147 }
0x6d61726b 0:7fca1bf48117 1148
0x6d61726b 0:7fca1bf48117 1149 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1150 *
0x6d61726b 0:7fca1bf48117 1151 * SEGGER_RTT_WaitKey
0x6d61726b 0:7fca1bf48117 1152 *
0x6d61726b 0:7fca1bf48117 1153 * Function description
0x6d61726b 0:7fca1bf48117 1154 * Waits until at least one character is avaible in the SEGGER RTT buffer.
0x6d61726b 0:7fca1bf48117 1155 * Once a character is available, it is read and this function returns.
0x6d61726b 0:7fca1bf48117 1156 *
0x6d61726b 0:7fca1bf48117 1157 * Return value
0x6d61726b 0:7fca1bf48117 1158 * >=0 - Character which has been read.
0x6d61726b 0:7fca1bf48117 1159 *
0x6d61726b 0:7fca1bf48117 1160 * Notes
0x6d61726b 0:7fca1bf48117 1161 * (1) This function is only specified for accesses to RTT buffer 0
0x6d61726b 0:7fca1bf48117 1162 * (2) This function is blocking if no character is present in RTT buffer
0x6d61726b 0:7fca1bf48117 1163 */
0x6d61726b 0:7fca1bf48117 1164 int SEGGER_RTT_WaitKey(void) {
0x6d61726b 0:7fca1bf48117 1165 int r;
0x6d61726b 0:7fca1bf48117 1166
0x6d61726b 0:7fca1bf48117 1167 do {
0x6d61726b 0:7fca1bf48117 1168 r = SEGGER_RTT_GetKey();
0x6d61726b 0:7fca1bf48117 1169 } while (r < 0);
0x6d61726b 0:7fca1bf48117 1170 return r;
0x6d61726b 0:7fca1bf48117 1171 }
0x6d61726b 0:7fca1bf48117 1172
0x6d61726b 0:7fca1bf48117 1173 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1174 *
0x6d61726b 0:7fca1bf48117 1175 * SEGGER_RTT_HasKey
0x6d61726b 0:7fca1bf48117 1176 *
0x6d61726b 0:7fca1bf48117 1177 * Function description
0x6d61726b 0:7fca1bf48117 1178 * Checks if at least one character for reading is available in the SEGGER RTT buffer.
0x6d61726b 0:7fca1bf48117 1179 *
0x6d61726b 0:7fca1bf48117 1180 * Return value
0x6d61726b 0:7fca1bf48117 1181 * == 0 - No characters are available to read.
0x6d61726b 0:7fca1bf48117 1182 * == 1 - At least one character is available.
0x6d61726b 0:7fca1bf48117 1183 *
0x6d61726b 0:7fca1bf48117 1184 * Notes
0x6d61726b 0:7fca1bf48117 1185 * (1) This function is only specified for accesses to RTT buffer 0
0x6d61726b 0:7fca1bf48117 1186 */
0x6d61726b 0:7fca1bf48117 1187 int SEGGER_RTT_HasKey(void) {
0x6d61726b 0:7fca1bf48117 1188 unsigned RdOff;
0x6d61726b 0:7fca1bf48117 1189 int r;
0x6d61726b 0:7fca1bf48117 1190
0x6d61726b 0:7fca1bf48117 1191 INIT();
0x6d61726b 0:7fca1bf48117 1192 RdOff = _SEGGER_RTT.aDown[0].RdOff;
0x6d61726b 0:7fca1bf48117 1193 if (RdOff != _SEGGER_RTT.aDown[0].WrOff) {
0x6d61726b 0:7fca1bf48117 1194 r = 1;
0x6d61726b 0:7fca1bf48117 1195 } else {
0x6d61726b 0:7fca1bf48117 1196 r = 0;
0x6d61726b 0:7fca1bf48117 1197 }
0x6d61726b 0:7fca1bf48117 1198 return r;
0x6d61726b 0:7fca1bf48117 1199 }
0x6d61726b 0:7fca1bf48117 1200
0x6d61726b 0:7fca1bf48117 1201 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1202 *
0x6d61726b 0:7fca1bf48117 1203 * SEGGER_RTT_HasData
0x6d61726b 0:7fca1bf48117 1204 *
0x6d61726b 0:7fca1bf48117 1205 * Function description
0x6d61726b 0:7fca1bf48117 1206 * Check if there is data from the host in the given buffer.
0x6d61726b 0:7fca1bf48117 1207 *
0x6d61726b 0:7fca1bf48117 1208 * Return value:
0x6d61726b 0:7fca1bf48117 1209 * ==0: No data
0x6d61726b 0:7fca1bf48117 1210 * !=0: Data in buffer
0x6d61726b 0:7fca1bf48117 1211 *
0x6d61726b 0:7fca1bf48117 1212 */
0x6d61726b 0:7fca1bf48117 1213 unsigned SEGGER_RTT_HasData(unsigned BufferIndex) {
0x6d61726b 0:7fca1bf48117 1214 SEGGER_RTT_BUFFER_DOWN* pRing;
0x6d61726b 0:7fca1bf48117 1215 unsigned v;
0x6d61726b 0:7fca1bf48117 1216
0x6d61726b 0:7fca1bf48117 1217 pRing = &_SEGGER_RTT.aDown[BufferIndex];
0x6d61726b 0:7fca1bf48117 1218 v = pRing->WrOff;
0x6d61726b 0:7fca1bf48117 1219 return v - pRing->RdOff;
0x6d61726b 0:7fca1bf48117 1220 }
0x6d61726b 0:7fca1bf48117 1221
0x6d61726b 0:7fca1bf48117 1222 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1223 *
0x6d61726b 0:7fca1bf48117 1224 * SEGGER_RTT_HasDataUp
0x6d61726b 0:7fca1bf48117 1225 *
0x6d61726b 0:7fca1bf48117 1226 * Function description
0x6d61726b 0:7fca1bf48117 1227 * Check if there is data remaining to be sent in the given buffer.
0x6d61726b 0:7fca1bf48117 1228 *
0x6d61726b 0:7fca1bf48117 1229 * Return value:
0x6d61726b 0:7fca1bf48117 1230 * ==0: No data
0x6d61726b 0:7fca1bf48117 1231 * !=0: Data in buffer
0x6d61726b 0:7fca1bf48117 1232 *
0x6d61726b 0:7fca1bf48117 1233 */
0x6d61726b 0:7fca1bf48117 1234 unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) {
0x6d61726b 0:7fca1bf48117 1235 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 1236 unsigned v;
0x6d61726b 0:7fca1bf48117 1237
0x6d61726b 0:7fca1bf48117 1238 pRing = &_SEGGER_RTT.aUp[BufferIndex];
0x6d61726b 0:7fca1bf48117 1239 v = pRing->RdOff;
0x6d61726b 0:7fca1bf48117 1240 return pRing->WrOff - v;
0x6d61726b 0:7fca1bf48117 1241 }
0x6d61726b 0:7fca1bf48117 1242
0x6d61726b 0:7fca1bf48117 1243 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1244 *
0x6d61726b 0:7fca1bf48117 1245 * SEGGER_RTT_AllocDownBuffer
0x6d61726b 0:7fca1bf48117 1246 *
0x6d61726b 0:7fca1bf48117 1247 * Function description
0x6d61726b 0:7fca1bf48117 1248 * Run-time configuration of the next down-buffer (H->T).
0x6d61726b 0:7fca1bf48117 1249 * The next buffer, which is not used yet is configured.
0x6d61726b 0:7fca1bf48117 1250 * This includes: Buffer address, size, name, flags, ...
0x6d61726b 0:7fca1bf48117 1251 *
0x6d61726b 0:7fca1bf48117 1252 * Parameters
0x6d61726b 0:7fca1bf48117 1253 * sName Pointer to a constant name string.
0x6d61726b 0:7fca1bf48117 1254 * pBuffer Pointer to a buffer to be used.
0x6d61726b 0:7fca1bf48117 1255 * BufferSize Size of the buffer.
0x6d61726b 0:7fca1bf48117 1256 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
0x6d61726b 0:7fca1bf48117 1257 *
0x6d61726b 0:7fca1bf48117 1258 * Return value
0x6d61726b 0:7fca1bf48117 1259 * >= 0 - O.K. Buffer Index
0x6d61726b 0:7fca1bf48117 1260 * < 0 - Error
0x6d61726b 0:7fca1bf48117 1261 */
0x6d61726b 0:7fca1bf48117 1262 int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
0x6d61726b 0:7fca1bf48117 1263 int BufferIndex;
0x6d61726b 0:7fca1bf48117 1264
0x6d61726b 0:7fca1bf48117 1265 INIT();
0x6d61726b 0:7fca1bf48117 1266 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1267 BufferIndex = 0;
0x6d61726b 0:7fca1bf48117 1268 do {
0x6d61726b 0:7fca1bf48117 1269 if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) {
0x6d61726b 0:7fca1bf48117 1270 break;
0x6d61726b 0:7fca1bf48117 1271 }
0x6d61726b 0:7fca1bf48117 1272 BufferIndex++;
0x6d61726b 0:7fca1bf48117 1273 } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers);
0x6d61726b 0:7fca1bf48117 1274 if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) {
0x6d61726b 0:7fca1bf48117 1275 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
0x6d61726b 0:7fca1bf48117 1276 _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
0x6d61726b 0:7fca1bf48117 1277 _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
0x6d61726b 0:7fca1bf48117 1278 _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
0x6d61726b 0:7fca1bf48117 1279 _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
0x6d61726b 0:7fca1bf48117 1280 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
0x6d61726b 0:7fca1bf48117 1281 } else {
0x6d61726b 0:7fca1bf48117 1282 BufferIndex = -1;
0x6d61726b 0:7fca1bf48117 1283 }
0x6d61726b 0:7fca1bf48117 1284 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1285 return BufferIndex;
0x6d61726b 0:7fca1bf48117 1286 }
0x6d61726b 0:7fca1bf48117 1287
0x6d61726b 0:7fca1bf48117 1288 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1289 *
0x6d61726b 0:7fca1bf48117 1290 * SEGGER_RTT_AllocUpBuffer
0x6d61726b 0:7fca1bf48117 1291 *
0x6d61726b 0:7fca1bf48117 1292 * Function description
0x6d61726b 0:7fca1bf48117 1293 * Run-time configuration of the next up-buffer (T->H).
0x6d61726b 0:7fca1bf48117 1294 * The next buffer, which is not used yet is configured.
0x6d61726b 0:7fca1bf48117 1295 * This includes: Buffer address, size, name, flags, ...
0x6d61726b 0:7fca1bf48117 1296 *
0x6d61726b 0:7fca1bf48117 1297 * Parameters
0x6d61726b 0:7fca1bf48117 1298 * sName Pointer to a constant name string.
0x6d61726b 0:7fca1bf48117 1299 * pBuffer Pointer to a buffer to be used.
0x6d61726b 0:7fca1bf48117 1300 * BufferSize Size of the buffer.
0x6d61726b 0:7fca1bf48117 1301 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
0x6d61726b 0:7fca1bf48117 1302 *
0x6d61726b 0:7fca1bf48117 1303 * Return value
0x6d61726b 0:7fca1bf48117 1304 * >= 0 - O.K. Buffer Index
0x6d61726b 0:7fca1bf48117 1305 * < 0 - Error
0x6d61726b 0:7fca1bf48117 1306 */
0x6d61726b 0:7fca1bf48117 1307 int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
0x6d61726b 0:7fca1bf48117 1308 int BufferIndex;
0x6d61726b 0:7fca1bf48117 1309
0x6d61726b 0:7fca1bf48117 1310 INIT();
0x6d61726b 0:7fca1bf48117 1311 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1312 BufferIndex = 0;
0x6d61726b 0:7fca1bf48117 1313 do {
0x6d61726b 0:7fca1bf48117 1314 if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) {
0x6d61726b 0:7fca1bf48117 1315 break;
0x6d61726b 0:7fca1bf48117 1316 }
0x6d61726b 0:7fca1bf48117 1317 BufferIndex++;
0x6d61726b 0:7fca1bf48117 1318 } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers);
0x6d61726b 0:7fca1bf48117 1319 if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) {
0x6d61726b 0:7fca1bf48117 1320 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
0x6d61726b 0:7fca1bf48117 1321 _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
0x6d61726b 0:7fca1bf48117 1322 _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
0x6d61726b 0:7fca1bf48117 1323 _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
0x6d61726b 0:7fca1bf48117 1324 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
0x6d61726b 0:7fca1bf48117 1325 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
0x6d61726b 0:7fca1bf48117 1326 } else {
0x6d61726b 0:7fca1bf48117 1327 BufferIndex = -1;
0x6d61726b 0:7fca1bf48117 1328 }
0x6d61726b 0:7fca1bf48117 1329 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1330 return BufferIndex;
0x6d61726b 0:7fca1bf48117 1331 }
0x6d61726b 0:7fca1bf48117 1332
0x6d61726b 0:7fca1bf48117 1333 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1334 *
0x6d61726b 0:7fca1bf48117 1335 * SEGGER_RTT_ConfigUpBuffer
0x6d61726b 0:7fca1bf48117 1336 *
0x6d61726b 0:7fca1bf48117 1337 * Function description
0x6d61726b 0:7fca1bf48117 1338 * Run-time configuration of a specific up-buffer (T->H).
0x6d61726b 0:7fca1bf48117 1339 * Buffer to be configured is specified by index.
0x6d61726b 0:7fca1bf48117 1340 * This includes: Buffer address, size, name, flags, ...
0x6d61726b 0:7fca1bf48117 1341 *
0x6d61726b 0:7fca1bf48117 1342 * Parameters
0x6d61726b 0:7fca1bf48117 1343 * BufferIndex Index of the buffer to configure.
0x6d61726b 0:7fca1bf48117 1344 * sName Pointer to a constant name string.
0x6d61726b 0:7fca1bf48117 1345 * pBuffer Pointer to a buffer to be used.
0x6d61726b 0:7fca1bf48117 1346 * BufferSize Size of the buffer.
0x6d61726b 0:7fca1bf48117 1347 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
0x6d61726b 0:7fca1bf48117 1348 *
0x6d61726b 0:7fca1bf48117 1349 * Return value
0x6d61726b 0:7fca1bf48117 1350 * >= 0 - O.K.
0x6d61726b 0:7fca1bf48117 1351 * < 0 - Error
0x6d61726b 0:7fca1bf48117 1352 *
0x6d61726b 0:7fca1bf48117 1353 * Additional information
0x6d61726b 0:7fca1bf48117 1354 * Buffer 0 is configured on compile-time.
0x6d61726b 0:7fca1bf48117 1355 * May only be called once per buffer.
0x6d61726b 0:7fca1bf48117 1356 * Buffer name and flags can be reconfigured using the appropriate functions.
0x6d61726b 0:7fca1bf48117 1357 */
0x6d61726b 0:7fca1bf48117 1358 int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
0x6d61726b 0:7fca1bf48117 1359 int r;
0x6d61726b 0:7fca1bf48117 1360
0x6d61726b 0:7fca1bf48117 1361 INIT();
0x6d61726b 0:7fca1bf48117 1362 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
0x6d61726b 0:7fca1bf48117 1363 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1364 if (BufferIndex > 0u) {
0x6d61726b 0:7fca1bf48117 1365 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
0x6d61726b 0:7fca1bf48117 1366 _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
0x6d61726b 0:7fca1bf48117 1367 _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
0x6d61726b 0:7fca1bf48117 1368 _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
0x6d61726b 0:7fca1bf48117 1369 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
0x6d61726b 0:7fca1bf48117 1370 }
0x6d61726b 0:7fca1bf48117 1371 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
0x6d61726b 0:7fca1bf48117 1372 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1373 r = 0;
0x6d61726b 0:7fca1bf48117 1374 } else {
0x6d61726b 0:7fca1bf48117 1375 r = -1;
0x6d61726b 0:7fca1bf48117 1376 }
0x6d61726b 0:7fca1bf48117 1377 return r;
0x6d61726b 0:7fca1bf48117 1378 }
0x6d61726b 0:7fca1bf48117 1379
0x6d61726b 0:7fca1bf48117 1380 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1381 *
0x6d61726b 0:7fca1bf48117 1382 * SEGGER_RTT_ConfigDownBuffer
0x6d61726b 0:7fca1bf48117 1383 *
0x6d61726b 0:7fca1bf48117 1384 * Function description
0x6d61726b 0:7fca1bf48117 1385 * Run-time configuration of a specific down-buffer (H->T).
0x6d61726b 0:7fca1bf48117 1386 * Buffer to be configured is specified by index.
0x6d61726b 0:7fca1bf48117 1387 * This includes: Buffer address, size, name, flags, ...
0x6d61726b 0:7fca1bf48117 1388 *
0x6d61726b 0:7fca1bf48117 1389 * Parameters
0x6d61726b 0:7fca1bf48117 1390 * BufferIndex Index of the buffer to configure.
0x6d61726b 0:7fca1bf48117 1391 * sName Pointer to a constant name string.
0x6d61726b 0:7fca1bf48117 1392 * pBuffer Pointer to a buffer to be used.
0x6d61726b 0:7fca1bf48117 1393 * BufferSize Size of the buffer.
0x6d61726b 0:7fca1bf48117 1394 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
0x6d61726b 0:7fca1bf48117 1395 *
0x6d61726b 0:7fca1bf48117 1396 * Return value
0x6d61726b 0:7fca1bf48117 1397 * >= 0 O.K.
0x6d61726b 0:7fca1bf48117 1398 * < 0 Error
0x6d61726b 0:7fca1bf48117 1399 *
0x6d61726b 0:7fca1bf48117 1400 * Additional information
0x6d61726b 0:7fca1bf48117 1401 * Buffer 0 is configured on compile-time.
0x6d61726b 0:7fca1bf48117 1402 * May only be called once per buffer.
0x6d61726b 0:7fca1bf48117 1403 * Buffer name and flags can be reconfigured using the appropriate functions.
0x6d61726b 0:7fca1bf48117 1404 */
0x6d61726b 0:7fca1bf48117 1405 int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
0x6d61726b 0:7fca1bf48117 1406 int r;
0x6d61726b 0:7fca1bf48117 1407
0x6d61726b 0:7fca1bf48117 1408 INIT();
0x6d61726b 0:7fca1bf48117 1409 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
0x6d61726b 0:7fca1bf48117 1410 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1411 if (BufferIndex > 0u) {
0x6d61726b 0:7fca1bf48117 1412 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
0x6d61726b 0:7fca1bf48117 1413 _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
0x6d61726b 0:7fca1bf48117 1414 _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
0x6d61726b 0:7fca1bf48117 1415 _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
0x6d61726b 0:7fca1bf48117 1416 _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
0x6d61726b 0:7fca1bf48117 1417 }
0x6d61726b 0:7fca1bf48117 1418 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
0x6d61726b 0:7fca1bf48117 1419 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1420 r = 0;
0x6d61726b 0:7fca1bf48117 1421 } else {
0x6d61726b 0:7fca1bf48117 1422 r = -1;
0x6d61726b 0:7fca1bf48117 1423 }
0x6d61726b 0:7fca1bf48117 1424 return r;
0x6d61726b 0:7fca1bf48117 1425 }
0x6d61726b 0:7fca1bf48117 1426
0x6d61726b 0:7fca1bf48117 1427 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1428 *
0x6d61726b 0:7fca1bf48117 1429 * SEGGER_RTT_SetNameUpBuffer
0x6d61726b 0:7fca1bf48117 1430 *
0x6d61726b 0:7fca1bf48117 1431 * Function description
0x6d61726b 0:7fca1bf48117 1432 * Run-time configuration of a specific up-buffer name (T->H).
0x6d61726b 0:7fca1bf48117 1433 * Buffer to be configured is specified by index.
0x6d61726b 0:7fca1bf48117 1434 *
0x6d61726b 0:7fca1bf48117 1435 * Parameters
0x6d61726b 0:7fca1bf48117 1436 * BufferIndex Index of the buffer to renamed.
0x6d61726b 0:7fca1bf48117 1437 * sName Pointer to a constant name string.
0x6d61726b 0:7fca1bf48117 1438 *
0x6d61726b 0:7fca1bf48117 1439 * Return value
0x6d61726b 0:7fca1bf48117 1440 * >= 0 O.K.
0x6d61726b 0:7fca1bf48117 1441 * < 0 Error
0x6d61726b 0:7fca1bf48117 1442 */
0x6d61726b 0:7fca1bf48117 1443 int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) {
0x6d61726b 0:7fca1bf48117 1444 int r;
0x6d61726b 0:7fca1bf48117 1445
0x6d61726b 0:7fca1bf48117 1446 INIT();
0x6d61726b 0:7fca1bf48117 1447 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
0x6d61726b 0:7fca1bf48117 1448 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1449 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
0x6d61726b 0:7fca1bf48117 1450 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1451 r = 0;
0x6d61726b 0:7fca1bf48117 1452 } else {
0x6d61726b 0:7fca1bf48117 1453 r = -1;
0x6d61726b 0:7fca1bf48117 1454 }
0x6d61726b 0:7fca1bf48117 1455 return r;
0x6d61726b 0:7fca1bf48117 1456 }
0x6d61726b 0:7fca1bf48117 1457
0x6d61726b 0:7fca1bf48117 1458 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1459 *
0x6d61726b 0:7fca1bf48117 1460 * SEGGER_RTT_SetNameDownBuffer
0x6d61726b 0:7fca1bf48117 1461 *
0x6d61726b 0:7fca1bf48117 1462 * Function description
0x6d61726b 0:7fca1bf48117 1463 * Run-time configuration of a specific Down-buffer name (T->H).
0x6d61726b 0:7fca1bf48117 1464 * Buffer to be configured is specified by index.
0x6d61726b 0:7fca1bf48117 1465 *
0x6d61726b 0:7fca1bf48117 1466 * Parameters
0x6d61726b 0:7fca1bf48117 1467 * BufferIndex Index of the buffer to renamed.
0x6d61726b 0:7fca1bf48117 1468 * sName Pointer to a constant name string.
0x6d61726b 0:7fca1bf48117 1469 *
0x6d61726b 0:7fca1bf48117 1470 * Return value
0x6d61726b 0:7fca1bf48117 1471 * >= 0 O.K.
0x6d61726b 0:7fca1bf48117 1472 * < 0 Error
0x6d61726b 0:7fca1bf48117 1473 */
0x6d61726b 0:7fca1bf48117 1474 int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
0x6d61726b 0:7fca1bf48117 1475 int r;
0x6d61726b 0:7fca1bf48117 1476
0x6d61726b 0:7fca1bf48117 1477 INIT();
0x6d61726b 0:7fca1bf48117 1478 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
0x6d61726b 0:7fca1bf48117 1479 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1480 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
0x6d61726b 0:7fca1bf48117 1481 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1482 r = 0;
0x6d61726b 0:7fca1bf48117 1483 } else {
0x6d61726b 0:7fca1bf48117 1484 r = -1;
0x6d61726b 0:7fca1bf48117 1485 }
0x6d61726b 0:7fca1bf48117 1486 return r;
0x6d61726b 0:7fca1bf48117 1487 }
0x6d61726b 0:7fca1bf48117 1488
0x6d61726b 0:7fca1bf48117 1489 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1490 *
0x6d61726b 0:7fca1bf48117 1491 * SEGGER_RTT_SetFlagsUpBuffer
0x6d61726b 0:7fca1bf48117 1492 *
0x6d61726b 0:7fca1bf48117 1493 * Function description
0x6d61726b 0:7fca1bf48117 1494 * Run-time configuration of specific up-buffer flags (T->H).
0x6d61726b 0:7fca1bf48117 1495 * Buffer to be configured is specified by index.
0x6d61726b 0:7fca1bf48117 1496 *
0x6d61726b 0:7fca1bf48117 1497 * Parameters
0x6d61726b 0:7fca1bf48117 1498 * BufferIndex Index of the buffer.
0x6d61726b 0:7fca1bf48117 1499 * Flags Flags to set for the buffer.
0x6d61726b 0:7fca1bf48117 1500 *
0x6d61726b 0:7fca1bf48117 1501 * Return value
0x6d61726b 0:7fca1bf48117 1502 * >= 0 O.K.
0x6d61726b 0:7fca1bf48117 1503 * < 0 Error
0x6d61726b 0:7fca1bf48117 1504 */
0x6d61726b 0:7fca1bf48117 1505 int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) {
0x6d61726b 0:7fca1bf48117 1506 int r;
0x6d61726b 0:7fca1bf48117 1507
0x6d61726b 0:7fca1bf48117 1508 INIT();
0x6d61726b 0:7fca1bf48117 1509 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
0x6d61726b 0:7fca1bf48117 1510 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1511 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
0x6d61726b 0:7fca1bf48117 1512 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1513 r = 0;
0x6d61726b 0:7fca1bf48117 1514 } else {
0x6d61726b 0:7fca1bf48117 1515 r = -1;
0x6d61726b 0:7fca1bf48117 1516 }
0x6d61726b 0:7fca1bf48117 1517 return r;
0x6d61726b 0:7fca1bf48117 1518 }
0x6d61726b 0:7fca1bf48117 1519
0x6d61726b 0:7fca1bf48117 1520 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1521 *
0x6d61726b 0:7fca1bf48117 1522 * SEGGER_RTT_SetFlagsDownBuffer
0x6d61726b 0:7fca1bf48117 1523 *
0x6d61726b 0:7fca1bf48117 1524 * Function description
0x6d61726b 0:7fca1bf48117 1525 * Run-time configuration of specific Down-buffer flags (T->H).
0x6d61726b 0:7fca1bf48117 1526 * Buffer to be configured is specified by index.
0x6d61726b 0:7fca1bf48117 1527 *
0x6d61726b 0:7fca1bf48117 1528 * Parameters
0x6d61726b 0:7fca1bf48117 1529 * BufferIndex Index of the buffer to renamed.
0x6d61726b 0:7fca1bf48117 1530 * Flags Flags to set for the buffer.
0x6d61726b 0:7fca1bf48117 1531 *
0x6d61726b 0:7fca1bf48117 1532 * Return value
0x6d61726b 0:7fca1bf48117 1533 * >= 0 O.K.
0x6d61726b 0:7fca1bf48117 1534 * < 0 Error
0x6d61726b 0:7fca1bf48117 1535 */
0x6d61726b 0:7fca1bf48117 1536 int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
0x6d61726b 0:7fca1bf48117 1537 int r;
0x6d61726b 0:7fca1bf48117 1538
0x6d61726b 0:7fca1bf48117 1539 INIT();
0x6d61726b 0:7fca1bf48117 1540 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
0x6d61726b 0:7fca1bf48117 1541 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1542 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
0x6d61726b 0:7fca1bf48117 1543 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1544 r = 0;
0x6d61726b 0:7fca1bf48117 1545 } else {
0x6d61726b 0:7fca1bf48117 1546 r = -1;
0x6d61726b 0:7fca1bf48117 1547 }
0x6d61726b 0:7fca1bf48117 1548 return r;
0x6d61726b 0:7fca1bf48117 1549 }
0x6d61726b 0:7fca1bf48117 1550
0x6d61726b 0:7fca1bf48117 1551 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1552 *
0x6d61726b 0:7fca1bf48117 1553 * SEGGER_RTT_Init
0x6d61726b 0:7fca1bf48117 1554 *
0x6d61726b 0:7fca1bf48117 1555 * Function description
0x6d61726b 0:7fca1bf48117 1556 * Initializes the RTT Control Block.
0x6d61726b 0:7fca1bf48117 1557 * Should be used in RAM targets, at start of the application.
0x6d61726b 0:7fca1bf48117 1558 *
0x6d61726b 0:7fca1bf48117 1559 */
0x6d61726b 0:7fca1bf48117 1560 void SEGGER_RTT_Init (void) {
0x6d61726b 0:7fca1bf48117 1561 _DoInit();
0x6d61726b 0:7fca1bf48117 1562 }
0x6d61726b 0:7fca1bf48117 1563
0x6d61726b 0:7fca1bf48117 1564 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1565 *
0x6d61726b 0:7fca1bf48117 1566 * SEGGER_RTT_SetTerminal
0x6d61726b 0:7fca1bf48117 1567 *
0x6d61726b 0:7fca1bf48117 1568 * Function description
0x6d61726b 0:7fca1bf48117 1569 * Sets the terminal to be used for output on channel 0.
0x6d61726b 0:7fca1bf48117 1570 *
0x6d61726b 0:7fca1bf48117 1571 * Parameters
0x6d61726b 0:7fca1bf48117 1572 * TerminalId Index of the terminal.
0x6d61726b 0:7fca1bf48117 1573 *
0x6d61726b 0:7fca1bf48117 1574 * Return value
0x6d61726b 0:7fca1bf48117 1575 * >= 0 O.K.
0x6d61726b 0:7fca1bf48117 1576 * < 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)
0x6d61726b 0:7fca1bf48117 1577 */
0x6d61726b 0:7fca1bf48117 1578 int SEGGER_RTT_SetTerminal (char TerminalId) {
0x6d61726b 0:7fca1bf48117 1579 unsigned char ac[2];
0x6d61726b 0:7fca1bf48117 1580 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 1581 unsigned Avail;
0x6d61726b 0:7fca1bf48117 1582 int r;
0x6d61726b 0:7fca1bf48117 1583 //
0x6d61726b 0:7fca1bf48117 1584 INIT();
0x6d61726b 0:7fca1bf48117 1585 //
0x6d61726b 0:7fca1bf48117 1586 r = 0;
0x6d61726b 0:7fca1bf48117 1587 ac[0] = 0xFFu;
0x6d61726b 0:7fca1bf48117 1588 if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels
0x6d61726b 0:7fca1bf48117 1589 ac[1] = _aTerminalId[(unsigned char)TerminalId];
0x6d61726b 0:7fca1bf48117 1590 pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed
0x6d61726b 0:7fca1bf48117 1591 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
0x6d61726b 0:7fca1bf48117 1592 if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
0x6d61726b 0:7fca1bf48117 1593 _ActiveTerminal = TerminalId;
0x6d61726b 0:7fca1bf48117 1594 _WriteBlocking(pRing, (const char*)ac, 2u);
0x6d61726b 0:7fca1bf48117 1595 } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes
0x6d61726b 0:7fca1bf48117 1596 Avail = _GetAvailWriteSpace(pRing);
0x6d61726b 0:7fca1bf48117 1597 if (Avail >= 2) {
0x6d61726b 0:7fca1bf48117 1598 _ActiveTerminal = TerminalId; // Only change active terminal in case of success
0x6d61726b 0:7fca1bf48117 1599 _WriteNoCheck(pRing, (const char*)ac, 2u);
0x6d61726b 0:7fca1bf48117 1600 } else {
0x6d61726b 0:7fca1bf48117 1601 r = -1;
0x6d61726b 0:7fca1bf48117 1602 }
0x6d61726b 0:7fca1bf48117 1603 }
0x6d61726b 0:7fca1bf48117 1604 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1605 } else {
0x6d61726b 0:7fca1bf48117 1606 r = -1;
0x6d61726b 0:7fca1bf48117 1607 }
0x6d61726b 0:7fca1bf48117 1608 return r;
0x6d61726b 0:7fca1bf48117 1609 }
0x6d61726b 0:7fca1bf48117 1610
0x6d61726b 0:7fca1bf48117 1611 /*********************************************************************
0x6d61726b 0:7fca1bf48117 1612 *
0x6d61726b 0:7fca1bf48117 1613 * SEGGER_RTT_TerminalOut
0x6d61726b 0:7fca1bf48117 1614 *
0x6d61726b 0:7fca1bf48117 1615 * Function description
0x6d61726b 0:7fca1bf48117 1616 * Writes a string to the given terminal
0x6d61726b 0:7fca1bf48117 1617 * without changing the terminal for channel 0.
0x6d61726b 0:7fca1bf48117 1618 *
0x6d61726b 0:7fca1bf48117 1619 * Parameters
0x6d61726b 0:7fca1bf48117 1620 * TerminalId Index of the terminal.
0x6d61726b 0:7fca1bf48117 1621 * s String to be printed on the terminal.
0x6d61726b 0:7fca1bf48117 1622 *
0x6d61726b 0:7fca1bf48117 1623 * Return value
0x6d61726b 0:7fca1bf48117 1624 * >= 0 - Number of bytes written.
0x6d61726b 0:7fca1bf48117 1625 * < 0 - Error.
0x6d61726b 0:7fca1bf48117 1626 *
0x6d61726b 0:7fca1bf48117 1627 */
0x6d61726b 0:7fca1bf48117 1628 int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) {
0x6d61726b 0:7fca1bf48117 1629 int Status;
0x6d61726b 0:7fca1bf48117 1630 unsigned FragLen;
0x6d61726b 0:7fca1bf48117 1631 unsigned Avail;
0x6d61726b 0:7fca1bf48117 1632 SEGGER_RTT_BUFFER_UP* pRing;
0x6d61726b 0:7fca1bf48117 1633 //
0x6d61726b 0:7fca1bf48117 1634 INIT();
0x6d61726b 0:7fca1bf48117 1635 //
0x6d61726b 0:7fca1bf48117 1636 // Validate terminal ID.
0x6d61726b 0:7fca1bf48117 1637 //
0x6d61726b 0:7fca1bf48117 1638 if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels
0x6d61726b 0:7fca1bf48117 1639 //
0x6d61726b 0:7fca1bf48117 1640 // Get "to-host" ring buffer.
0x6d61726b 0:7fca1bf48117 1641 //
0x6d61726b 0:7fca1bf48117 1642 pRing = &_SEGGER_RTT.aUp[0];
0x6d61726b 0:7fca1bf48117 1643 //
0x6d61726b 0:7fca1bf48117 1644 // Need to be able to change terminal, write data, change back.
0x6d61726b 0:7fca1bf48117 1645 // Compute the fixed and variable sizes.
0x6d61726b 0:7fca1bf48117 1646 //
0x6d61726b 0:7fca1bf48117 1647 FragLen = STRLEN(s);
0x6d61726b 0:7fca1bf48117 1648 //
0x6d61726b 0:7fca1bf48117 1649 // How we output depends upon the mode...
0x6d61726b 0:7fca1bf48117 1650 //
0x6d61726b 0:7fca1bf48117 1651 SEGGER_RTT_LOCK();
0x6d61726b 0:7fca1bf48117 1652 Avail = _GetAvailWriteSpace(pRing);
0x6d61726b 0:7fca1bf48117 1653 switch (pRing->Flags & SEGGER_RTT_MODE_MASK) {
0x6d61726b 0:7fca1bf48117 1654 case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
0x6d61726b 0:7fca1bf48117 1655 //
0x6d61726b 0:7fca1bf48117 1656 // If we are in skip mode and there is no space for the whole
0x6d61726b 0:7fca1bf48117 1657 // of this output, don't bother switching terminals at all.
0x6d61726b 0:7fca1bf48117 1658 //
0x6d61726b 0:7fca1bf48117 1659 if (Avail < (FragLen + 4u)) {
0x6d61726b 0:7fca1bf48117 1660 Status = 0;
0x6d61726b 0:7fca1bf48117 1661 } else {
0x6d61726b 0:7fca1bf48117 1662 _PostTerminalSwitch(pRing, TerminalId);
0x6d61726b 0:7fca1bf48117 1663 Status = (int)_WriteBlocking(pRing, s, FragLen);
0x6d61726b 0:7fca1bf48117 1664 _PostTerminalSwitch(pRing, _ActiveTerminal);
0x6d61726b 0:7fca1bf48117 1665 }
0x6d61726b 0:7fca1bf48117 1666 break;
0x6d61726b 0:7fca1bf48117 1667 case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
0x6d61726b 0:7fca1bf48117 1668 //
0x6d61726b 0:7fca1bf48117 1669 // If we are in trim mode and there is not enough space for everything,
0x6d61726b 0:7fca1bf48117 1670 // trim the output but always include the terminal switch. If no room
0x6d61726b 0:7fca1bf48117 1671 // for terminal switch, skip that totally.
0x6d61726b 0:7fca1bf48117 1672 //
0x6d61726b 0:7fca1bf48117 1673 if (Avail < 4u) {
0x6d61726b 0:7fca1bf48117 1674 Status = -1;
0x6d61726b 0:7fca1bf48117 1675 } else {
0x6d61726b 0:7fca1bf48117 1676 _PostTerminalSwitch(pRing, TerminalId);
0x6d61726b 0:7fca1bf48117 1677 Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u));
0x6d61726b 0:7fca1bf48117 1678 _PostTerminalSwitch(pRing, _ActiveTerminal);
0x6d61726b 0:7fca1bf48117 1679 }
0x6d61726b 0:7fca1bf48117 1680 break;
0x6d61726b 0:7fca1bf48117 1681 case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
0x6d61726b 0:7fca1bf48117 1682 //
0x6d61726b 0:7fca1bf48117 1683 // If we are in blocking mode, output everything.
0x6d61726b 0:7fca1bf48117 1684 //
0x6d61726b 0:7fca1bf48117 1685 _PostTerminalSwitch(pRing, TerminalId);
0x6d61726b 0:7fca1bf48117 1686 Status = (int)_WriteBlocking(pRing, s, FragLen);
0x6d61726b 0:7fca1bf48117 1687 _PostTerminalSwitch(pRing, _ActiveTerminal);
0x6d61726b 0:7fca1bf48117 1688 break;
0x6d61726b 0:7fca1bf48117 1689 default:
0x6d61726b 0:7fca1bf48117 1690 Status = -1;
0x6d61726b 0:7fca1bf48117 1691 break;
0x6d61726b 0:7fca1bf48117 1692 }
0x6d61726b 0:7fca1bf48117 1693 //
0x6d61726b 0:7fca1bf48117 1694 // Finish up.
0x6d61726b 0:7fca1bf48117 1695 //
0x6d61726b 0:7fca1bf48117 1696 SEGGER_RTT_UNLOCK();
0x6d61726b 0:7fca1bf48117 1697 } else {
0x6d61726b 0:7fca1bf48117 1698 Status = -1;
0x6d61726b 0:7fca1bf48117 1699 }
0x6d61726b 0:7fca1bf48117 1700 return Status;
0x6d61726b 0:7fca1bf48117 1701 }
0x6d61726b 0:7fca1bf48117 1702
0x6d61726b 0:7fca1bf48117 1703
0x6d61726b 0:7fca1bf48117 1704 /*************************** End of file ****************************/