SLRE(Super Light Regular Expression library) Unit Test Code.

Dependencies:   mbed

Committer:
monpetit
Date:
Thu Jul 28 08:10:30 2016 +0000
Revision:
0:3ca3835f816e
initial commit: unit tests are passed.

Who changed what in which revision?

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