RTT Debugger Library

Dependents:   BREAK_SENSOR_LED MPU9250_simple MPU9250_tap_better Sensor_tap_BLE ... more

Committer:
Anythingconnected
Date:
Mon Dec 18 10:17:08 2017 +0000
Revision:
0:7dcd871d726b
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Anythingconnected 0:7dcd871d726b 1 /*********************************************************************
Anythingconnected 0:7dcd871d726b 2 * SEGGER MICROCONTROLLER GmbH & Co. KG *
Anythingconnected 0:7dcd871d726b 3 * Solutions for real time microcontroller applications *
Anythingconnected 0:7dcd871d726b 4 **********************************************************************
Anythingconnected 0:7dcd871d726b 5 * *
Anythingconnected 0:7dcd871d726b 6 * (c) 2014-2014 SEGGER Microcontroller GmbH & Co. KG *
Anythingconnected 0:7dcd871d726b 7 * *
Anythingconnected 0:7dcd871d726b 8 * Internet: www.segger.com Support: support@segger.com *
Anythingconnected 0:7dcd871d726b 9 * *
Anythingconnected 0:7dcd871d726b 10 **********************************************************************
Anythingconnected 0:7dcd871d726b 11 ----------------------------------------------------------------------
Anythingconnected 0:7dcd871d726b 12 File : SEGGER_RTT.c
Anythingconnected 0:7dcd871d726b 13 Date : 17 Dec 2014
Anythingconnected 0:7dcd871d726b 14 Purpose : Implementation of SEGGER real-time terminal (RTT) which allows
Anythingconnected 0:7dcd871d726b 15 real-time terminal communication on targets which support
Anythingconnected 0:7dcd871d726b 16 debugger memory accesses while the CPU is running.
Anythingconnected 0:7dcd871d726b 17
Anythingconnected 0:7dcd871d726b 18 Type "int" is assumed to be 32-bits in size
Anythingconnected 0:7dcd871d726b 19 H->T Host to target communication
Anythingconnected 0:7dcd871d726b 20 T->H Target to host communication
Anythingconnected 0:7dcd871d726b 21
Anythingconnected 0:7dcd871d726b 22 RTT channel 0 is always present and reserved for Terminal usage.
Anythingconnected 0:7dcd871d726b 23 Name is fixed to "Terminal"
Anythingconnected 0:7dcd871d726b 24
Anythingconnected 0:7dcd871d726b 25 ---------------------------END-OF-HEADER------------------------------
Anythingconnected 0:7dcd871d726b 26 */
Anythingconnected 0:7dcd871d726b 27
Anythingconnected 0:7dcd871d726b 28 #include "SEGGER_RTT_Conf.h"
Anythingconnected 0:7dcd871d726b 29 #include "SEGGER_RTT.h"
Anythingconnected 0:7dcd871d726b 30
Anythingconnected 0:7dcd871d726b 31 #include <string.h> // for memcpy
Anythingconnected 0:7dcd871d726b 32
Anythingconnected 0:7dcd871d726b 33 /*********************************************************************
Anythingconnected 0:7dcd871d726b 34 *
Anythingconnected 0:7dcd871d726b 35 * Defines, configurable
Anythingconnected 0:7dcd871d726b 36 *
Anythingconnected 0:7dcd871d726b 37 **********************************************************************
Anythingconnected 0:7dcd871d726b 38 */
Anythingconnected 0:7dcd871d726b 39
Anythingconnected 0:7dcd871d726b 40 #ifndef BUFFER_SIZE_UP
Anythingconnected 0:7dcd871d726b 41 #define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host
Anythingconnected 0:7dcd871d726b 42 #endif
Anythingconnected 0:7dcd871d726b 43
Anythingconnected 0:7dcd871d726b 44 #ifndef BUFFER_SIZE_DOWN
Anythingconnected 0:7dcd871d726b 45 #define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input)
Anythingconnected 0:7dcd871d726b 46 #endif
Anythingconnected 0:7dcd871d726b 47
Anythingconnected 0:7dcd871d726b 48 #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
Anythingconnected 0:7dcd871d726b 49 #define SEGGER_RTT_MAX_NUM_UP_BUFFERS (1) // Number of up-buffers (T->H) available on this target
Anythingconnected 0:7dcd871d726b 50 #endif
Anythingconnected 0:7dcd871d726b 51
Anythingconnected 0:7dcd871d726b 52 #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
Anythingconnected 0:7dcd871d726b 53 #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (1) // Number of down-buffers (H->T) available on this target
Anythingconnected 0:7dcd871d726b 54 #endif
Anythingconnected 0:7dcd871d726b 55
Anythingconnected 0:7dcd871d726b 56 #ifndef SEGGER_RTT_LOCK
Anythingconnected 0:7dcd871d726b 57 #define SEGGER_RTT_LOCK()
Anythingconnected 0:7dcd871d726b 58 #endif
Anythingconnected 0:7dcd871d726b 59
Anythingconnected 0:7dcd871d726b 60 #ifndef SEGGER_RTT_UNLOCK
Anythingconnected 0:7dcd871d726b 61 #define SEGGER_RTT_UNLOCK()
Anythingconnected 0:7dcd871d726b 62 #endif
Anythingconnected 0:7dcd871d726b 63
Anythingconnected 0:7dcd871d726b 64 #ifndef SEGGER_RTT_IN_RAM
Anythingconnected 0:7dcd871d726b 65 #define SEGGER_RTT_IN_RAM (0)
Anythingconnected 0:7dcd871d726b 66 #endif
Anythingconnected 0:7dcd871d726b 67
Anythingconnected 0:7dcd871d726b 68 /*********************************************************************
Anythingconnected 0:7dcd871d726b 69 *
Anythingconnected 0:7dcd871d726b 70 * Defines, fixed
Anythingconnected 0:7dcd871d726b 71 *
Anythingconnected 0:7dcd871d726b 72 **********************************************************************
Anythingconnected 0:7dcd871d726b 73 */
Anythingconnected 0:7dcd871d726b 74
Anythingconnected 0:7dcd871d726b 75 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
Anythingconnected 0:7dcd871d726b 76 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
Anythingconnected 0:7dcd871d726b 77
Anythingconnected 0:7dcd871d726b 78 #define MEMCPY(a, b, c) memcpy((a),(b),(c))
Anythingconnected 0:7dcd871d726b 79
Anythingconnected 0:7dcd871d726b 80 //
Anythingconnected 0:7dcd871d726b 81 // For some environments, NULL may not be defined until certain headers are included
Anythingconnected 0:7dcd871d726b 82 //
Anythingconnected 0:7dcd871d726b 83 #ifndef NULL
Anythingconnected 0:7dcd871d726b 84 #define NULL 0
Anythingconnected 0:7dcd871d726b 85 #endif
Anythingconnected 0:7dcd871d726b 86
Anythingconnected 0:7dcd871d726b 87 /*********************************************************************
Anythingconnected 0:7dcd871d726b 88 *
Anythingconnected 0:7dcd871d726b 89 * Types
Anythingconnected 0:7dcd871d726b 90 *
Anythingconnected 0:7dcd871d726b 91 **********************************************************************
Anythingconnected 0:7dcd871d726b 92 */
Anythingconnected 0:7dcd871d726b 93
Anythingconnected 0:7dcd871d726b 94 //
Anythingconnected 0:7dcd871d726b 95 // Description for a circular buffer (also called "ring buffer")
Anythingconnected 0:7dcd871d726b 96 // which is used as up- (T->H) or down-buffer (H->T)
Anythingconnected 0:7dcd871d726b 97 //
Anythingconnected 0:7dcd871d726b 98 typedef struct {
Anythingconnected 0:7dcd871d726b 99 const char* sName; // Optional name. Standard names so far are: "Terminal", "VCom"
Anythingconnected 0:7dcd871d726b 100 char* pBuffer; // Pointer to start of buffer
Anythingconnected 0:7dcd871d726b 101 int SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
Anythingconnected 0:7dcd871d726b 102 volatile int WrOff; // Position of next item to be written by either host (down-buffer) or target (up-buffer). Must be volatile since it may be modified by host (down-buffer)
Anythingconnected 0:7dcd871d726b 103 volatile int RdOff; // Position of next item to be read by target (down-buffer) or host (up-buffer). Must be volatile since it may be modified by host (up-buffer)
Anythingconnected 0:7dcd871d726b 104 int Flags; // Contains configuration flags
Anythingconnected 0:7dcd871d726b 105 } RING_BUFFER;
Anythingconnected 0:7dcd871d726b 106
Anythingconnected 0:7dcd871d726b 107 //
Anythingconnected 0:7dcd871d726b 108 // RTT control block which describes the number of buffers available
Anythingconnected 0:7dcd871d726b 109 // as well as the configuration for each buffer
Anythingconnected 0:7dcd871d726b 110 //
Anythingconnected 0:7dcd871d726b 111 //
Anythingconnected 0:7dcd871d726b 112 typedef struct {
Anythingconnected 0:7dcd871d726b 113 char acID[16]; // Initialized to "SEGGER RTT"
Anythingconnected 0:7dcd871d726b 114 int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
Anythingconnected 0:7dcd871d726b 115 int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
Anythingconnected 0:7dcd871d726b 116 RING_BUFFER aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host
Anythingconnected 0:7dcd871d726b 117 RING_BUFFER aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target
Anythingconnected 0:7dcd871d726b 118 } SEGGER_RTT_CB;
Anythingconnected 0:7dcd871d726b 119
Anythingconnected 0:7dcd871d726b 120 /*********************************************************************
Anythingconnected 0:7dcd871d726b 121 *
Anythingconnected 0:7dcd871d726b 122 * Static data
Anythingconnected 0:7dcd871d726b 123 *
Anythingconnected 0:7dcd871d726b 124 **********************************************************************
Anythingconnected 0:7dcd871d726b 125 */
Anythingconnected 0:7dcd871d726b 126 //
Anythingconnected 0:7dcd871d726b 127 // Allocate buffers for channel 0
Anythingconnected 0:7dcd871d726b 128 //
Anythingconnected 0:7dcd871d726b 129 static char _acUpBuffer [BUFFER_SIZE_UP];
Anythingconnected 0:7dcd871d726b 130 static char _acDownBuffer[BUFFER_SIZE_DOWN];
Anythingconnected 0:7dcd871d726b 131 //
Anythingconnected 0:7dcd871d726b 132 // Initialize SEGGER Real-time-Terminal control block (CB)
Anythingconnected 0:7dcd871d726b 133 //
Anythingconnected 0:7dcd871d726b 134 static SEGGER_RTT_CB _SEGGER_RTT = {
Anythingconnected 0:7dcd871d726b 135 #if SEGGER_RTT_IN_RAM
Anythingconnected 0:7dcd871d726b 136 "SEGGER RTTI",
Anythingconnected 0:7dcd871d726b 137 #else
Anythingconnected 0:7dcd871d726b 138 "SEGGER RTT",
Anythingconnected 0:7dcd871d726b 139 #endif
Anythingconnected 0:7dcd871d726b 140 SEGGER_RTT_MAX_NUM_UP_BUFFERS,
Anythingconnected 0:7dcd871d726b 141 SEGGER_RTT_MAX_NUM_DOWN_BUFFERS,
Anythingconnected 0:7dcd871d726b 142 {{ "Terminal", &_acUpBuffer[0], sizeof(_acUpBuffer), 0, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP }},
Anythingconnected 0:7dcd871d726b 143 {{ "Terminal", &_acDownBuffer[0], sizeof(_acDownBuffer), 0, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP }},
Anythingconnected 0:7dcd871d726b 144 };
Anythingconnected 0:7dcd871d726b 145
Anythingconnected 0:7dcd871d726b 146 static char _ActiveTerminal;
Anythingconnected 0:7dcd871d726b 147
Anythingconnected 0:7dcd871d726b 148 /*********************************************************************
Anythingconnected 0:7dcd871d726b 149 *
Anythingconnected 0:7dcd871d726b 150 * Static code
Anythingconnected 0:7dcd871d726b 151 *
Anythingconnected 0:7dcd871d726b 152 **********************************************************************
Anythingconnected 0:7dcd871d726b 153 */
Anythingconnected 0:7dcd871d726b 154
Anythingconnected 0:7dcd871d726b 155 /*********************************************************************
Anythingconnected 0:7dcd871d726b 156 *
Anythingconnected 0:7dcd871d726b 157 * _strlen
Anythingconnected 0:7dcd871d726b 158 *
Anythingconnected 0:7dcd871d726b 159 * Function description
Anythingconnected 0:7dcd871d726b 160 * ANSI compatible function to determine the length of a string
Anythingconnected 0:7dcd871d726b 161 *
Anythingconnected 0:7dcd871d726b 162 * Return value
Anythingconnected 0:7dcd871d726b 163 * Length of string in bytes.
Anythingconnected 0:7dcd871d726b 164 *
Anythingconnected 0:7dcd871d726b 165 * Parameters
Anythingconnected 0:7dcd871d726b 166 * s Pointer to \0 terminated string.
Anythingconnected 0:7dcd871d726b 167 *
Anythingconnected 0:7dcd871d726b 168 * Notes
Anythingconnected 0:7dcd871d726b 169 * (1) s needs to point to an \0 terminated string. Otherwise proper functionality of this function is not guaranteed.
Anythingconnected 0:7dcd871d726b 170 */
Anythingconnected 0:7dcd871d726b 171 static int _strlen(const char* s) {
Anythingconnected 0:7dcd871d726b 172 int Len;
Anythingconnected 0:7dcd871d726b 173
Anythingconnected 0:7dcd871d726b 174 Len = 0;
Anythingconnected 0:7dcd871d726b 175 if (s == NULL) {
Anythingconnected 0:7dcd871d726b 176 return 0;
Anythingconnected 0:7dcd871d726b 177 }
Anythingconnected 0:7dcd871d726b 178 do {
Anythingconnected 0:7dcd871d726b 179 if (*s == 0) {
Anythingconnected 0:7dcd871d726b 180 break;
Anythingconnected 0:7dcd871d726b 181 }
Anythingconnected 0:7dcd871d726b 182 Len++;
Anythingconnected 0:7dcd871d726b 183 s++;
Anythingconnected 0:7dcd871d726b 184 } while (1);
Anythingconnected 0:7dcd871d726b 185 return Len;
Anythingconnected 0:7dcd871d726b 186 }
Anythingconnected 0:7dcd871d726b 187
Anythingconnected 0:7dcd871d726b 188 /*********************************************************************
Anythingconnected 0:7dcd871d726b 189 *
Anythingconnected 0:7dcd871d726b 190 * _Init
Anythingconnected 0:7dcd871d726b 191 *
Anythingconnected 0:7dcd871d726b 192 * Function description
Anythingconnected 0:7dcd871d726b 193 * In case SEGGER_RTT_IN_RAM is defined,
Anythingconnected 0:7dcd871d726b 194 * _Init() modifies the ID of the RTT CB to allow identifying the
Anythingconnected 0:7dcd871d726b 195 * RTT Control Block Structure in the data segment.
Anythingconnected 0:7dcd871d726b 196 */
Anythingconnected 0:7dcd871d726b 197 static void _Init(void) {
Anythingconnected 0:7dcd871d726b 198 #if SEGGER_RTT_IN_RAM
Anythingconnected 0:7dcd871d726b 199 if (_SEGGER_RTT.acID[10] == 'I') {
Anythingconnected 0:7dcd871d726b 200 _SEGGER_RTT.acID[10] = '\0';
Anythingconnected 0:7dcd871d726b 201 }
Anythingconnected 0:7dcd871d726b 202 #endif
Anythingconnected 0:7dcd871d726b 203 }
Anythingconnected 0:7dcd871d726b 204
Anythingconnected 0:7dcd871d726b 205 /*********************************************************************
Anythingconnected 0:7dcd871d726b 206 *
Anythingconnected 0:7dcd871d726b 207 * Public code
Anythingconnected 0:7dcd871d726b 208 *
Anythingconnected 0:7dcd871d726b 209 **********************************************************************
Anythingconnected 0:7dcd871d726b 210 */
Anythingconnected 0:7dcd871d726b 211 /*********************************************************************
Anythingconnected 0:7dcd871d726b 212 *
Anythingconnected 0:7dcd871d726b 213 * SEGGER_RTT_Read
Anythingconnected 0:7dcd871d726b 214 *
Anythingconnected 0:7dcd871d726b 215 * Function description
Anythingconnected 0:7dcd871d726b 216 * Reads characters from SEGGER real-time-terminal control block
Anythingconnected 0:7dcd871d726b 217 * which have been previously stored by the host.
Anythingconnected 0:7dcd871d726b 218 *
Anythingconnected 0:7dcd871d726b 219 * Parameters
Anythingconnected 0:7dcd871d726b 220 * BufferIndex Index of Down-buffer to be used. (e.g. 0 for "Terminal")
Anythingconnected 0:7dcd871d726b 221 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
Anythingconnected 0:7dcd871d726b 222 * BufferSize Size of the target application buffer
Anythingconnected 0:7dcd871d726b 223 *
Anythingconnected 0:7dcd871d726b 224 * Return values
Anythingconnected 0:7dcd871d726b 225 * Number of bytes that have been read
Anythingconnected 0:7dcd871d726b 226 */
Anythingconnected 0:7dcd871d726b 227 int SEGGER_RTT_Read(unsigned BufferIndex, char* pBuffer, unsigned BufferSize) {
Anythingconnected 0:7dcd871d726b 228 int NumBytesRem;
Anythingconnected 0:7dcd871d726b 229 unsigned NumBytesRead;
Anythingconnected 0:7dcd871d726b 230 int RdOff;
Anythingconnected 0:7dcd871d726b 231 int WrOff;
Anythingconnected 0:7dcd871d726b 232
Anythingconnected 0:7dcd871d726b 233 SEGGER_RTT_LOCK();
Anythingconnected 0:7dcd871d726b 234 _Init();
Anythingconnected 0:7dcd871d726b 235 RdOff = _SEGGER_RTT.aDown[BufferIndex].RdOff;
Anythingconnected 0:7dcd871d726b 236 WrOff = _SEGGER_RTT.aDown[BufferIndex].WrOff;
Anythingconnected 0:7dcd871d726b 237 NumBytesRead = 0;
Anythingconnected 0:7dcd871d726b 238 //
Anythingconnected 0:7dcd871d726b 239 // Read from current read position to wrap-around of buffer, first
Anythingconnected 0:7dcd871d726b 240 //
Anythingconnected 0:7dcd871d726b 241 if (RdOff > WrOff) {
Anythingconnected 0:7dcd871d726b 242 NumBytesRem = _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer - RdOff;
Anythingconnected 0:7dcd871d726b 243 NumBytesRem = MIN(NumBytesRem, (int)BufferSize);
Anythingconnected 0:7dcd871d726b 244 MEMCPY(pBuffer, _SEGGER_RTT.aDown[BufferIndex].pBuffer + RdOff, NumBytesRem);
Anythingconnected 0:7dcd871d726b 245 NumBytesRead += NumBytesRem;
Anythingconnected 0:7dcd871d726b 246 pBuffer += NumBytesRem;
Anythingconnected 0:7dcd871d726b 247 BufferSize -= NumBytesRem;
Anythingconnected 0:7dcd871d726b 248 RdOff += NumBytesRem;
Anythingconnected 0:7dcd871d726b 249 //
Anythingconnected 0:7dcd871d726b 250 // Handle wrap-around of buffer
Anythingconnected 0:7dcd871d726b 251 //
Anythingconnected 0:7dcd871d726b 252 if (RdOff == _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer) {
Anythingconnected 0:7dcd871d726b 253 RdOff = 0;
Anythingconnected 0:7dcd871d726b 254 }
Anythingconnected 0:7dcd871d726b 255 }
Anythingconnected 0:7dcd871d726b 256 //
Anythingconnected 0:7dcd871d726b 257 // Read remaining items of buffer
Anythingconnected 0:7dcd871d726b 258 //
Anythingconnected 0:7dcd871d726b 259 NumBytesRem = WrOff - RdOff;
Anythingconnected 0:7dcd871d726b 260 NumBytesRem = MIN(NumBytesRem, (int)BufferSize);
Anythingconnected 0:7dcd871d726b 261 if (NumBytesRem > 0) {
Anythingconnected 0:7dcd871d726b 262 MEMCPY(pBuffer, _SEGGER_RTT.aDown[BufferIndex].pBuffer + RdOff, NumBytesRem);
Anythingconnected 0:7dcd871d726b 263 NumBytesRead += NumBytesRem;
Anythingconnected 0:7dcd871d726b 264 pBuffer += NumBytesRem;
Anythingconnected 0:7dcd871d726b 265 BufferSize -= NumBytesRem;
Anythingconnected 0:7dcd871d726b 266 RdOff += NumBytesRem;
Anythingconnected 0:7dcd871d726b 267 }
Anythingconnected 0:7dcd871d726b 268 if (NumBytesRead) {
Anythingconnected 0:7dcd871d726b 269 _SEGGER_RTT.aDown[BufferIndex].RdOff = RdOff;
Anythingconnected 0:7dcd871d726b 270 }
Anythingconnected 0:7dcd871d726b 271 SEGGER_RTT_UNLOCK();
Anythingconnected 0:7dcd871d726b 272 return NumBytesRead;
Anythingconnected 0:7dcd871d726b 273 }
Anythingconnected 0:7dcd871d726b 274
Anythingconnected 0:7dcd871d726b 275 /*********************************************************************
Anythingconnected 0:7dcd871d726b 276 *
Anythingconnected 0:7dcd871d726b 277 * SEGGER_RTT_Write
Anythingconnected 0:7dcd871d726b 278 *
Anythingconnected 0:7dcd871d726b 279 * Function description
Anythingconnected 0:7dcd871d726b 280 * Stores a specified number of characters in SEGGER RTT
Anythingconnected 0:7dcd871d726b 281 * control block which is then read by the host.
Anythingconnected 0:7dcd871d726b 282 *
Anythingconnected 0:7dcd871d726b 283 * Parameters
Anythingconnected 0:7dcd871d726b 284 * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
Anythingconnected 0:7dcd871d726b 285 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
Anythingconnected 0:7dcd871d726b 286 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
Anythingconnected 0:7dcd871d726b 287 *
Anythingconnected 0:7dcd871d726b 288 * Return values
Anythingconnected 0:7dcd871d726b 289 * Number of bytes which have been stored in the "Up"-buffer.
Anythingconnected 0:7dcd871d726b 290 *
Anythingconnected 0:7dcd871d726b 291 * Notes
Anythingconnected 0:7dcd871d726b 292 * (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
Anythingconnected 0:7dcd871d726b 293 */
Anythingconnected 0:7dcd871d726b 294 int SEGGER_RTT_Write(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes) {
Anythingconnected 0:7dcd871d726b 295 int NumBytesToWrite;
Anythingconnected 0:7dcd871d726b 296 unsigned NumBytesWritten;
Anythingconnected 0:7dcd871d726b 297 int RdOff;
Anythingconnected 0:7dcd871d726b 298 //
Anythingconnected 0:7dcd871d726b 299 // Target is not allowed to perform other RTT operations while string still has not been stored completely.
Anythingconnected 0:7dcd871d726b 300 // Otherwise we would probably end up with a mixed string in the buffer.
Anythingconnected 0:7dcd871d726b 301 //
Anythingconnected 0:7dcd871d726b 302 SEGGER_RTT_LOCK();
Anythingconnected 0:7dcd871d726b 303 _Init();
Anythingconnected 0:7dcd871d726b 304 //
Anythingconnected 0:7dcd871d726b 305 // In case we are not in blocking mode,
Anythingconnected 0:7dcd871d726b 306 // we need to calculate, how many bytes we can put into the buffer at all.
Anythingconnected 0:7dcd871d726b 307 //
Anythingconnected 0:7dcd871d726b 308 if ((_SEGGER_RTT.aUp[BufferIndex].Flags & SEGGER_RTT_MODE_MASK) != SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
Anythingconnected 0:7dcd871d726b 309 RdOff = _SEGGER_RTT.aUp[BufferIndex].RdOff;
Anythingconnected 0:7dcd871d726b 310 NumBytesToWrite = RdOff - _SEGGER_RTT.aUp[BufferIndex].WrOff - 1;
Anythingconnected 0:7dcd871d726b 311 if (NumBytesToWrite < 0) {
Anythingconnected 0:7dcd871d726b 312 NumBytesToWrite += _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer;
Anythingconnected 0:7dcd871d726b 313 }
Anythingconnected 0:7dcd871d726b 314 //
Anythingconnected 0:7dcd871d726b 315 // If the complete data does not fit in the buffer, check if we have to skip it completely or trim the data
Anythingconnected 0:7dcd871d726b 316 //
Anythingconnected 0:7dcd871d726b 317 if ((int)NumBytes > NumBytesToWrite) {
Anythingconnected 0:7dcd871d726b 318 if ((_SEGGER_RTT.aUp[BufferIndex].Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_NO_BLOCK_SKIP) {
Anythingconnected 0:7dcd871d726b 319 SEGGER_RTT_UNLOCK();
Anythingconnected 0:7dcd871d726b 320 return 0;
Anythingconnected 0:7dcd871d726b 321 } else {
Anythingconnected 0:7dcd871d726b 322 NumBytes = NumBytesToWrite;
Anythingconnected 0:7dcd871d726b 323 }
Anythingconnected 0:7dcd871d726b 324 }
Anythingconnected 0:7dcd871d726b 325 }
Anythingconnected 0:7dcd871d726b 326 //
Anythingconnected 0:7dcd871d726b 327 // Early out if nothing is to do
Anythingconnected 0:7dcd871d726b 328 //
Anythingconnected 0:7dcd871d726b 329 if (NumBytes == 0) {
Anythingconnected 0:7dcd871d726b 330 SEGGER_RTT_UNLOCK();
Anythingconnected 0:7dcd871d726b 331 return 0;
Anythingconnected 0:7dcd871d726b 332 }
Anythingconnected 0:7dcd871d726b 333 //
Anythingconnected 0:7dcd871d726b 334 // Write data to buffer and handle wrap-around if necessary
Anythingconnected 0:7dcd871d726b 335 //
Anythingconnected 0:7dcd871d726b 336 NumBytesWritten = 0;
Anythingconnected 0:7dcd871d726b 337 do {
Anythingconnected 0:7dcd871d726b 338 RdOff = _SEGGER_RTT.aUp[BufferIndex].RdOff; // May be changed by host (debug probe) in the meantime
Anythingconnected 0:7dcd871d726b 339 NumBytesToWrite = RdOff - _SEGGER_RTT.aUp[BufferIndex].WrOff - 1;
Anythingconnected 0:7dcd871d726b 340 if (NumBytesToWrite < 0) {
Anythingconnected 0:7dcd871d726b 341 NumBytesToWrite += _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer;
Anythingconnected 0:7dcd871d726b 342 }
Anythingconnected 0:7dcd871d726b 343 NumBytesToWrite = MIN(NumBytesToWrite, (_SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer - _SEGGER_RTT.aUp[BufferIndex].WrOff)); // Number of bytes that can be written until buffer wrap-around
Anythingconnected 0:7dcd871d726b 344 NumBytesToWrite = MIN(NumBytesToWrite, (int)NumBytes);
Anythingconnected 0:7dcd871d726b 345 MEMCPY(_SEGGER_RTT.aUp[BufferIndex].pBuffer + _SEGGER_RTT.aUp[BufferIndex].WrOff, pBuffer, NumBytesToWrite);
Anythingconnected 0:7dcd871d726b 346 NumBytesWritten += NumBytesToWrite;
Anythingconnected 0:7dcd871d726b 347 pBuffer += NumBytesToWrite;
Anythingconnected 0:7dcd871d726b 348 NumBytes -= NumBytesToWrite;
Anythingconnected 0:7dcd871d726b 349 _SEGGER_RTT.aUp[BufferIndex].WrOff += NumBytesToWrite;
Anythingconnected 0:7dcd871d726b 350 if (_SEGGER_RTT.aUp[BufferIndex].WrOff == _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer) {
Anythingconnected 0:7dcd871d726b 351 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0;
Anythingconnected 0:7dcd871d726b 352 }
Anythingconnected 0:7dcd871d726b 353 } while (NumBytes);
Anythingconnected 0:7dcd871d726b 354 SEGGER_RTT_UNLOCK();
Anythingconnected 0:7dcd871d726b 355 return NumBytesWritten;
Anythingconnected 0:7dcd871d726b 356 }
Anythingconnected 0:7dcd871d726b 357
Anythingconnected 0:7dcd871d726b 358 /*********************************************************************
Anythingconnected 0:7dcd871d726b 359 *
Anythingconnected 0:7dcd871d726b 360 * SEGGER_RTT_WriteString
Anythingconnected 0:7dcd871d726b 361 *
Anythingconnected 0:7dcd871d726b 362 * Function description
Anythingconnected 0:7dcd871d726b 363 * Stores string in SEGGER RTT control block.
Anythingconnected 0:7dcd871d726b 364 * This data is read by the host.
Anythingconnected 0:7dcd871d726b 365 *
Anythingconnected 0:7dcd871d726b 366 * Parameters
Anythingconnected 0:7dcd871d726b 367 * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
Anythingconnected 0:7dcd871d726b 368 * s Pointer to string.
Anythingconnected 0:7dcd871d726b 369 *
Anythingconnected 0:7dcd871d726b 370 * Return values
Anythingconnected 0:7dcd871d726b 371 * Number of bytes which have been stored in the "Up"-buffer.
Anythingconnected 0:7dcd871d726b 372 *
Anythingconnected 0:7dcd871d726b 373 * Notes
Anythingconnected 0:7dcd871d726b 374 * (1) If there is not enough space in the "Up"-buffer, depending on configuration,
Anythingconnected 0:7dcd871d726b 375 * remaining characters may be dropped or RTT module waits until there is more space in the buffer.
Anythingconnected 0:7dcd871d726b 376 * (2) String passed to this function has to be \0 terminated
Anythingconnected 0:7dcd871d726b 377 * (3) \0 termination character is *not* stored in RTT buffer
Anythingconnected 0:7dcd871d726b 378 */
Anythingconnected 0:7dcd871d726b 379 int SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
Anythingconnected 0:7dcd871d726b 380 int Len;
Anythingconnected 0:7dcd871d726b 381
Anythingconnected 0:7dcd871d726b 382 Len = _strlen(s);
Anythingconnected 0:7dcd871d726b 383 return SEGGER_RTT_Write(BufferIndex, s, Len);
Anythingconnected 0:7dcd871d726b 384 }
Anythingconnected 0:7dcd871d726b 385
Anythingconnected 0:7dcd871d726b 386 /*********************************************************************
Anythingconnected 0:7dcd871d726b 387 *
Anythingconnected 0:7dcd871d726b 388 * SEGGER_RTT_GetKey
Anythingconnected 0:7dcd871d726b 389 *
Anythingconnected 0:7dcd871d726b 390 * Function description
Anythingconnected 0:7dcd871d726b 391 * Reads one character from the SEGGER RTT buffer.
Anythingconnected 0:7dcd871d726b 392 * Host has previously stored data there.
Anythingconnected 0:7dcd871d726b 393 *
Anythingconnected 0:7dcd871d726b 394 * Return values
Anythingconnected 0:7dcd871d726b 395 * < 0 No character available (buffer empty).
Anythingconnected 0:7dcd871d726b 396 * >= 0 Character which has been read. (Possible values: 0 - 255)
Anythingconnected 0:7dcd871d726b 397 *
Anythingconnected 0:7dcd871d726b 398 * Notes
Anythingconnected 0:7dcd871d726b 399 * (1) This function is only specified for accesses to RTT buffer 0.
Anythingconnected 0:7dcd871d726b 400 */
Anythingconnected 0:7dcd871d726b 401 int SEGGER_RTT_GetKey(void) {
Anythingconnected 0:7dcd871d726b 402 char c;
Anythingconnected 0:7dcd871d726b 403 int r;
Anythingconnected 0:7dcd871d726b 404
Anythingconnected 0:7dcd871d726b 405 r = SEGGER_RTT_Read(0, &c, 1);
Anythingconnected 0:7dcd871d726b 406 if (r == 1) {
Anythingconnected 0:7dcd871d726b 407 return (int)(unsigned char)c;
Anythingconnected 0:7dcd871d726b 408 }
Anythingconnected 0:7dcd871d726b 409 return -1;
Anythingconnected 0:7dcd871d726b 410 }
Anythingconnected 0:7dcd871d726b 411
Anythingconnected 0:7dcd871d726b 412 /*********************************************************************
Anythingconnected 0:7dcd871d726b 413 *
Anythingconnected 0:7dcd871d726b 414 * SEGGER_RTT_WaitKey
Anythingconnected 0:7dcd871d726b 415 *
Anythingconnected 0:7dcd871d726b 416 * Function description
Anythingconnected 0:7dcd871d726b 417 * Waits until at least one character is avaible in the SEGGER RTT buffer.
Anythingconnected 0:7dcd871d726b 418 * Once a character is available, it is read and this function returns.
Anythingconnected 0:7dcd871d726b 419 *
Anythingconnected 0:7dcd871d726b 420 * Return values
Anythingconnected 0:7dcd871d726b 421 * >=0 Character which has been read.
Anythingconnected 0:7dcd871d726b 422 *
Anythingconnected 0:7dcd871d726b 423 * Notes
Anythingconnected 0:7dcd871d726b 424 * (1) This function is only specified for accesses to RTT buffer 0
Anythingconnected 0:7dcd871d726b 425 * (2) This function is blocking if no character is present in RTT buffer
Anythingconnected 0:7dcd871d726b 426 */
Anythingconnected 0:7dcd871d726b 427 int SEGGER_RTT_WaitKey(void) {
Anythingconnected 0:7dcd871d726b 428 int r;
Anythingconnected 0:7dcd871d726b 429
Anythingconnected 0:7dcd871d726b 430 do {
Anythingconnected 0:7dcd871d726b 431 r = SEGGER_RTT_GetKey();
Anythingconnected 0:7dcd871d726b 432 } while (r < 0);
Anythingconnected 0:7dcd871d726b 433 return r;
Anythingconnected 0:7dcd871d726b 434 }
Anythingconnected 0:7dcd871d726b 435
Anythingconnected 0:7dcd871d726b 436 /*********************************************************************
Anythingconnected 0:7dcd871d726b 437 *
Anythingconnected 0:7dcd871d726b 438 * SEGGER_RTT_HasKey
Anythingconnected 0:7dcd871d726b 439 *
Anythingconnected 0:7dcd871d726b 440 * Function description
Anythingconnected 0:7dcd871d726b 441 * Checks if at least one character for reading is available in the SEGGER RTT buffer.
Anythingconnected 0:7dcd871d726b 442 *
Anythingconnected 0:7dcd871d726b 443 * Return values
Anythingconnected 0:7dcd871d726b 444 * 0 No characters are available to read.
Anythingconnected 0:7dcd871d726b 445 * 1 At least one character is available.
Anythingconnected 0:7dcd871d726b 446 *
Anythingconnected 0:7dcd871d726b 447 * Notes
Anythingconnected 0:7dcd871d726b 448 * (1) This function is only specified for accesses to RTT buffer 0
Anythingconnected 0:7dcd871d726b 449 */
Anythingconnected 0:7dcd871d726b 450 int SEGGER_RTT_HasKey(void) {
Anythingconnected 0:7dcd871d726b 451 int RdOff;
Anythingconnected 0:7dcd871d726b 452
Anythingconnected 0:7dcd871d726b 453 _Init();
Anythingconnected 0:7dcd871d726b 454 RdOff = _SEGGER_RTT.aDown[0].RdOff;
Anythingconnected 0:7dcd871d726b 455 if (RdOff != _SEGGER_RTT.aDown[0].WrOff) {
Anythingconnected 0:7dcd871d726b 456 return 1;
Anythingconnected 0:7dcd871d726b 457 }
Anythingconnected 0:7dcd871d726b 458 return 0;
Anythingconnected 0:7dcd871d726b 459 }
Anythingconnected 0:7dcd871d726b 460
Anythingconnected 0:7dcd871d726b 461 /*********************************************************************
Anythingconnected 0:7dcd871d726b 462 *
Anythingconnected 0:7dcd871d726b 463 * SEGGER_RTT_ConfigUpBuffer
Anythingconnected 0:7dcd871d726b 464 *
Anythingconnected 0:7dcd871d726b 465 * Function description
Anythingconnected 0:7dcd871d726b 466 * Run-time configuration of a specific up-buffer (T->H).
Anythingconnected 0:7dcd871d726b 467 * Buffer to be configured is specified by index.
Anythingconnected 0:7dcd871d726b 468 * This includes: Buffer address, size, name, flags, ...
Anythingconnected 0:7dcd871d726b 469 *
Anythingconnected 0:7dcd871d726b 470 * Return value
Anythingconnected 0:7dcd871d726b 471 * >= 0 O.K.
Anythingconnected 0:7dcd871d726b 472 * < 0 Error
Anythingconnected 0:7dcd871d726b 473 */
Anythingconnected 0:7dcd871d726b 474 int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) {
Anythingconnected 0:7dcd871d726b 475 _Init();
Anythingconnected 0:7dcd871d726b 476 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
Anythingconnected 0:7dcd871d726b 477 SEGGER_RTT_LOCK();
Anythingconnected 0:7dcd871d726b 478 if (BufferIndex > 0) {
Anythingconnected 0:7dcd871d726b 479 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
Anythingconnected 0:7dcd871d726b 480 _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer;
Anythingconnected 0:7dcd871d726b 481 _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
Anythingconnected 0:7dcd871d726b 482 _SEGGER_RTT.aUp[BufferIndex].RdOff = 0;
Anythingconnected 0:7dcd871d726b 483 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0;
Anythingconnected 0:7dcd871d726b 484 }
Anythingconnected 0:7dcd871d726b 485 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
Anythingconnected 0:7dcd871d726b 486 SEGGER_RTT_UNLOCK();
Anythingconnected 0:7dcd871d726b 487 return 0;
Anythingconnected 0:7dcd871d726b 488 }
Anythingconnected 0:7dcd871d726b 489 return -1;
Anythingconnected 0:7dcd871d726b 490 }
Anythingconnected 0:7dcd871d726b 491
Anythingconnected 0:7dcd871d726b 492 /*********************************************************************
Anythingconnected 0:7dcd871d726b 493 *
Anythingconnected 0:7dcd871d726b 494 * SEGGER_RTT_ConfigDownBuffer
Anythingconnected 0:7dcd871d726b 495 *
Anythingconnected 0:7dcd871d726b 496 * Function description
Anythingconnected 0:7dcd871d726b 497 * Run-time configuration of a specific down-buffer (H->T).
Anythingconnected 0:7dcd871d726b 498 * Buffer to be configured is specified by index.
Anythingconnected 0:7dcd871d726b 499 * This includes: Buffer address, size, name, flags, ...
Anythingconnected 0:7dcd871d726b 500 *
Anythingconnected 0:7dcd871d726b 501 * Return value
Anythingconnected 0:7dcd871d726b 502 * >= 0 O.K.
Anythingconnected 0:7dcd871d726b 503 * < 0 Error
Anythingconnected 0:7dcd871d726b 504 */
Anythingconnected 0:7dcd871d726b 505 int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) {
Anythingconnected 0:7dcd871d726b 506 _Init();
Anythingconnected 0:7dcd871d726b 507 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
Anythingconnected 0:7dcd871d726b 508 SEGGER_RTT_LOCK();
Anythingconnected 0:7dcd871d726b 509 if (BufferIndex > 0) {
Anythingconnected 0:7dcd871d726b 510 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
Anythingconnected 0:7dcd871d726b 511 _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer;
Anythingconnected 0:7dcd871d726b 512 _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
Anythingconnected 0:7dcd871d726b 513 _SEGGER_RTT.aDown[BufferIndex].RdOff = 0;
Anythingconnected 0:7dcd871d726b 514 _SEGGER_RTT.aDown[BufferIndex].WrOff = 0;
Anythingconnected 0:7dcd871d726b 515 }
Anythingconnected 0:7dcd871d726b 516 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
Anythingconnected 0:7dcd871d726b 517 SEGGER_RTT_UNLOCK();
Anythingconnected 0:7dcd871d726b 518 return 0;
Anythingconnected 0:7dcd871d726b 519 }
Anythingconnected 0:7dcd871d726b 520 return -1;
Anythingconnected 0:7dcd871d726b 521 }
Anythingconnected 0:7dcd871d726b 522
Anythingconnected 0:7dcd871d726b 523 /*********************************************************************
Anythingconnected 0:7dcd871d726b 524 *
Anythingconnected 0:7dcd871d726b 525 * SEGGER_RTT_Init
Anythingconnected 0:7dcd871d726b 526 *
Anythingconnected 0:7dcd871d726b 527 * Function description
Anythingconnected 0:7dcd871d726b 528 * Initializes the RTT Control Block.
Anythingconnected 0:7dcd871d726b 529 * Should be used in RAM targets, at start of the application.
Anythingconnected 0:7dcd871d726b 530 *
Anythingconnected 0:7dcd871d726b 531 */
Anythingconnected 0:7dcd871d726b 532 void SEGGER_RTT_Init (void) {
Anythingconnected 0:7dcd871d726b 533 _Init();
Anythingconnected 0:7dcd871d726b 534 }
Anythingconnected 0:7dcd871d726b 535
Anythingconnected 0:7dcd871d726b 536 /*********************************************************************
Anythingconnected 0:7dcd871d726b 537 *
Anythingconnected 0:7dcd871d726b 538 * SEGGER_RTT_SetTerminal
Anythingconnected 0:7dcd871d726b 539 *
Anythingconnected 0:7dcd871d726b 540 * Function description
Anythingconnected 0:7dcd871d726b 541 * Sets the terminal to be used for output on channel 0.
Anythingconnected 0:7dcd871d726b 542 *
Anythingconnected 0:7dcd871d726b 543 */
Anythingconnected 0:7dcd871d726b 544 void SEGGER_RTT_SetTerminal (char TerminalId) {
Anythingconnected 0:7dcd871d726b 545 char ac[2];
Anythingconnected 0:7dcd871d726b 546
Anythingconnected 0:7dcd871d726b 547 ac[0] = 0xFF;
Anythingconnected 0:7dcd871d726b 548 if (TerminalId < 10) {
Anythingconnected 0:7dcd871d726b 549 ac[1] = '0' + TerminalId;
Anythingconnected 0:7dcd871d726b 550 } else if (TerminalId < 16) {
Anythingconnected 0:7dcd871d726b 551 ac[1] = 'A' + (TerminalId - 0x0A);
Anythingconnected 0:7dcd871d726b 552 } else {
Anythingconnected 0:7dcd871d726b 553 return; // RTT only supports up to 16 virtual terminals.
Anythingconnected 0:7dcd871d726b 554 }
Anythingconnected 0:7dcd871d726b 555 _ActiveTerminal = TerminalId;
Anythingconnected 0:7dcd871d726b 556 SEGGER_RTT_Write(0, ac, 2);
Anythingconnected 0:7dcd871d726b 557 }
Anythingconnected 0:7dcd871d726b 558
Anythingconnected 0:7dcd871d726b 559 /*********************************************************************
Anythingconnected 0:7dcd871d726b 560 *
Anythingconnected 0:7dcd871d726b 561 * SEGGER_RTT_TerminalOut
Anythingconnected 0:7dcd871d726b 562 *
Anythingconnected 0:7dcd871d726b 563 * Function description
Anythingconnected 0:7dcd871d726b 564 * Writes a string to the given terminal
Anythingconnected 0:7dcd871d726b 565 * without changing the terminal for channel 0.
Anythingconnected 0:7dcd871d726b 566 *
Anythingconnected 0:7dcd871d726b 567 */
Anythingconnected 0:7dcd871d726b 568 int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) {
Anythingconnected 0:7dcd871d726b 569 char ac[2];
Anythingconnected 0:7dcd871d726b 570 int r;
Anythingconnected 0:7dcd871d726b 571
Anythingconnected 0:7dcd871d726b 572 ac[0] = 0xFF;
Anythingconnected 0:7dcd871d726b 573 if (TerminalId < 10) {
Anythingconnected 0:7dcd871d726b 574 ac[1] = '0' + TerminalId;
Anythingconnected 0:7dcd871d726b 575 } else if (TerminalId < 16) {
Anythingconnected 0:7dcd871d726b 576 ac[1] = 'A' + (TerminalId - 0x0A);
Anythingconnected 0:7dcd871d726b 577 } else {
Anythingconnected 0:7dcd871d726b 578 return -1; // RTT only supports up to 16 virtual terminals.
Anythingconnected 0:7dcd871d726b 579 }
Anythingconnected 0:7dcd871d726b 580 SEGGER_RTT_Write(0, ac, 2);
Anythingconnected 0:7dcd871d726b 581 r = SEGGER_RTT_WriteString(0, s);
Anythingconnected 0:7dcd871d726b 582 if (TerminalId < 10) {
Anythingconnected 0:7dcd871d726b 583 ac[1] = '0' + _ActiveTerminal;
Anythingconnected 0:7dcd871d726b 584 } else if (TerminalId < 16) {
Anythingconnected 0:7dcd871d726b 585 ac[1] = 'A' + (_ActiveTerminal - 0x0A);
Anythingconnected 0:7dcd871d726b 586 }
Anythingconnected 0:7dcd871d726b 587 SEGGER_RTT_Write(0, ac, 2);
Anythingconnected 0:7dcd871d726b 588 return r;
Anythingconnected 0:7dcd871d726b 589 }
Anythingconnected 0:7dcd871d726b 590
Anythingconnected 0:7dcd871d726b 591 /*************************** End of file ****************************/