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

Dependents:   3_Test_AFE 1_Test_Flash_ADC_RTT

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
0x6d61726b 0:7fca1bf48117 1 /*********************************************************************
0x6d61726b 0:7fca1bf48117 2 * SEGGER Microcontroller GmbH *
0x6d61726b 0:7fca1bf48117 3 * The Embedded Experts *
0x6d61726b 0:7fca1bf48117 4 **********************************************************************
0x6d61726b 0:7fca1bf48117 5 * *
0x6d61726b 0:7fca1bf48117 6 * (c) 1995 - 2019 SEGGER Microcontroller GmbH *
0x6d61726b 0:7fca1bf48117 7 * *
0x6d61726b 0:7fca1bf48117 8 * www.segger.com Support: support@segger.com *
0x6d61726b 0:7fca1bf48117 9 * *
0x6d61726b 0:7fca1bf48117 10 **********************************************************************
0x6d61726b 0:7fca1bf48117 11 * *
0x6d61726b 0:7fca1bf48117 12 * SEGGER RTT * Real Time Transfer for embedded targets *
0x6d61726b 0:7fca1bf48117 13 * *
0x6d61726b 0:7fca1bf48117 14 **********************************************************************
0x6d61726b 0:7fca1bf48117 15 * *
0x6d61726b 0:7fca1bf48117 16 * All rights reserved. *
0x6d61726b 0:7fca1bf48117 17 * *
0x6d61726b 0:7fca1bf48117 18 * SEGGER strongly recommends to not make any changes *
0x6d61726b 0:7fca1bf48117 19 * to or modify the source code of this software in order to stay *
0x6d61726b 0:7fca1bf48117 20 * compatible with the RTT protocol and J-Link. *
0x6d61726b 0:7fca1bf48117 21 * *
0x6d61726b 0:7fca1bf48117 22 * Redistribution and use in source and binary forms, with or *
0x6d61726b 0:7fca1bf48117 23 * without modification, are permitted provided that the following *
0x6d61726b 0:7fca1bf48117 24 * conditions are met: *
0x6d61726b 0:7fca1bf48117 25 * *
0x6d61726b 0:7fca1bf48117 26 * o Redistributions of source code must retain the above copyright *
0x6d61726b 0:7fca1bf48117 27 * notice, this list of conditions and the following disclaimer. *
0x6d61726b 0:7fca1bf48117 28 * *
0x6d61726b 0:7fca1bf48117 29 * o Redistributions in binary form must reproduce the above *
0x6d61726b 0:7fca1bf48117 30 * copyright notice, this list of conditions and the following *
0x6d61726b 0:7fca1bf48117 31 * disclaimer in the documentation and/or other materials provided *
0x6d61726b 0:7fca1bf48117 32 * with the distribution. *
0x6d61726b 0:7fca1bf48117 33 * *
0x6d61726b 0:7fca1bf48117 34 * o Neither the name of SEGGER Microcontroller GmbH *
0x6d61726b 0:7fca1bf48117 35 * nor the names of its contributors may be used to endorse or *
0x6d61726b 0:7fca1bf48117 36 * promote products derived from this software without specific *
0x6d61726b 0:7fca1bf48117 37 * prior written permission. *
0x6d61726b 0:7fca1bf48117 38 * *
0x6d61726b 0:7fca1bf48117 39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
0x6d61726b 0:7fca1bf48117 40 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
0x6d61726b 0:7fca1bf48117 41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
0x6d61726b 0:7fca1bf48117 42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
0x6d61726b 0:7fca1bf48117 43 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
0x6d61726b 0:7fca1bf48117 44 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
0x6d61726b 0:7fca1bf48117 45 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
0x6d61726b 0:7fca1bf48117 46 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
0x6d61726b 0:7fca1bf48117 47 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
0x6d61726b 0:7fca1bf48117 48 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
0x6d61726b 0:7fca1bf48117 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
0x6d61726b 0:7fca1bf48117 50 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
0x6d61726b 0:7fca1bf48117 51 * DAMAGE. *
0x6d61726b 0:7fca1bf48117 52 * *
0x6d61726b 0:7fca1bf48117 53 **********************************************************************
0x6d61726b 0:7fca1bf48117 54 * *
0x6d61726b 0:7fca1bf48117 55 * RTT version: 6.44i *
0x6d61726b 0:7fca1bf48117 56 * *
0x6d61726b 0:7fca1bf48117 57 **********************************************************************
0x6d61726b 0:7fca1bf48117 58 ---------------------------END-OF-HEADER------------------------------
0x6d61726b 0:7fca1bf48117 59 File : SEGGER_RTT_printf.c
0x6d61726b 0:7fca1bf48117 60 Purpose : Replacement for printf to write formatted data via RTT
0x6d61726b 0:7fca1bf48117 61 Revision: Rev: 12360
0x6d61726b 0:7fca1bf48117 62 ----------------------------------------------------------------------
0x6d61726b 0:7fca1bf48117 63 */
0x6d61726b 0:7fca1bf48117 64 #include "SEGGER_RTT.h"
0x6d61726b 0:7fca1bf48117 65 #include "SEGGER_RTT_Conf.h"
0x6d61726b 0:7fca1bf48117 66
0x6d61726b 0:7fca1bf48117 67 /*********************************************************************
0x6d61726b 0:7fca1bf48117 68 *
0x6d61726b 0:7fca1bf48117 69 * Defines, configurable
0x6d61726b 0:7fca1bf48117 70 *
0x6d61726b 0:7fca1bf48117 71 **********************************************************************
0x6d61726b 0:7fca1bf48117 72 */
0x6d61726b 0:7fca1bf48117 73
0x6d61726b 0:7fca1bf48117 74 #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
0x6d61726b 0:7fca1bf48117 75 #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
0x6d61726b 0:7fca1bf48117 76 #endif
0x6d61726b 0:7fca1bf48117 77
0x6d61726b 0:7fca1bf48117 78 #include <stdlib.h>
0x6d61726b 0:7fca1bf48117 79 #include <stdarg.h>
0x6d61726b 0:7fca1bf48117 80
0x6d61726b 0:7fca1bf48117 81
0x6d61726b 0:7fca1bf48117 82 #define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0)
0x6d61726b 0:7fca1bf48117 83 #define FORMAT_FLAG_PAD_ZERO (1u << 1)
0x6d61726b 0:7fca1bf48117 84 #define FORMAT_FLAG_PRINT_SIGN (1u << 2)
0x6d61726b 0:7fca1bf48117 85 #define FORMAT_FLAG_ALTERNATE (1u << 3)
0x6d61726b 0:7fca1bf48117 86
0x6d61726b 0:7fca1bf48117 87 /*********************************************************************
0x6d61726b 0:7fca1bf48117 88 *
0x6d61726b 0:7fca1bf48117 89 * Types
0x6d61726b 0:7fca1bf48117 90 *
0x6d61726b 0:7fca1bf48117 91 **********************************************************************
0x6d61726b 0:7fca1bf48117 92 */
0x6d61726b 0:7fca1bf48117 93
0x6d61726b 0:7fca1bf48117 94 typedef struct {
0x6d61726b 0:7fca1bf48117 95 char* pBuffer;
0x6d61726b 0:7fca1bf48117 96 unsigned BufferSize;
0x6d61726b 0:7fca1bf48117 97 unsigned Cnt;
0x6d61726b 0:7fca1bf48117 98
0x6d61726b 0:7fca1bf48117 99 int ReturnValue;
0x6d61726b 0:7fca1bf48117 100
0x6d61726b 0:7fca1bf48117 101 unsigned RTTBufferIndex;
0x6d61726b 0:7fca1bf48117 102 } SEGGER_RTT_PRINTF_DESC;
0x6d61726b 0:7fca1bf48117 103
0x6d61726b 0:7fca1bf48117 104 /*********************************************************************
0x6d61726b 0:7fca1bf48117 105 *
0x6d61726b 0:7fca1bf48117 106 * Function prototypes
0x6d61726b 0:7fca1bf48117 107 *
0x6d61726b 0:7fca1bf48117 108 **********************************************************************
0x6d61726b 0:7fca1bf48117 109 */
0x6d61726b 0:7fca1bf48117 110
0x6d61726b 0:7fca1bf48117 111 /*********************************************************************
0x6d61726b 0:7fca1bf48117 112 *
0x6d61726b 0:7fca1bf48117 113 * Static code
0x6d61726b 0:7fca1bf48117 114 *
0x6d61726b 0:7fca1bf48117 115 **********************************************************************
0x6d61726b 0:7fca1bf48117 116 */
0x6d61726b 0:7fca1bf48117 117 /*********************************************************************
0x6d61726b 0:7fca1bf48117 118 *
0x6d61726b 0:7fca1bf48117 119 * _StoreChar
0x6d61726b 0:7fca1bf48117 120 */
0x6d61726b 0:7fca1bf48117 121 static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
0x6d61726b 0:7fca1bf48117 122 unsigned Cnt;
0x6d61726b 0:7fca1bf48117 123
0x6d61726b 0:7fca1bf48117 124 Cnt = p->Cnt;
0x6d61726b 0:7fca1bf48117 125 if ((Cnt + 1u) <= p->BufferSize) {
0x6d61726b 0:7fca1bf48117 126 *(p->pBuffer + Cnt) = c;
0x6d61726b 0:7fca1bf48117 127 p->Cnt = Cnt + 1u;
0x6d61726b 0:7fca1bf48117 128 p->ReturnValue++;
0x6d61726b 0:7fca1bf48117 129 }
0x6d61726b 0:7fca1bf48117 130 //
0x6d61726b 0:7fca1bf48117 131 // Write part of string, when the buffer is full
0x6d61726b 0:7fca1bf48117 132 //
0x6d61726b 0:7fca1bf48117 133 if (p->Cnt == p->BufferSize) {
0x6d61726b 0:7fca1bf48117 134 if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
0x6d61726b 0:7fca1bf48117 135 p->ReturnValue = -1;
0x6d61726b 0:7fca1bf48117 136 } else {
0x6d61726b 0:7fca1bf48117 137 p->Cnt = 0u;
0x6d61726b 0:7fca1bf48117 138 }
0x6d61726b 0:7fca1bf48117 139 }
0x6d61726b 0:7fca1bf48117 140 }
0x6d61726b 0:7fca1bf48117 141
0x6d61726b 0:7fca1bf48117 142 /*********************************************************************
0x6d61726b 0:7fca1bf48117 143 *
0x6d61726b 0:7fca1bf48117 144 * _PrintUnsigned
0x6d61726b 0:7fca1bf48117 145 */
0x6d61726b 0:7fca1bf48117 146 static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
0x6d61726b 0:7fca1bf48117 147 static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
0x6d61726b 0:7fca1bf48117 148 unsigned Div;
0x6d61726b 0:7fca1bf48117 149 unsigned Digit;
0x6d61726b 0:7fca1bf48117 150 unsigned Number;
0x6d61726b 0:7fca1bf48117 151 unsigned Width;
0x6d61726b 0:7fca1bf48117 152 char c;
0x6d61726b 0:7fca1bf48117 153
0x6d61726b 0:7fca1bf48117 154 Number = v;
0x6d61726b 0:7fca1bf48117 155 Digit = 1u;
0x6d61726b 0:7fca1bf48117 156 //
0x6d61726b 0:7fca1bf48117 157 // Get actual field width
0x6d61726b 0:7fca1bf48117 158 //
0x6d61726b 0:7fca1bf48117 159 Width = 1u;
0x6d61726b 0:7fca1bf48117 160 while (Number >= Base) {
0x6d61726b 0:7fca1bf48117 161 Number = (Number / Base);
0x6d61726b 0:7fca1bf48117 162 Width++;
0x6d61726b 0:7fca1bf48117 163 }
0x6d61726b 0:7fca1bf48117 164 if (NumDigits > Width) {
0x6d61726b 0:7fca1bf48117 165 Width = NumDigits;
0x6d61726b 0:7fca1bf48117 166 }
0x6d61726b 0:7fca1bf48117 167 //
0x6d61726b 0:7fca1bf48117 168 // Print leading chars if necessary
0x6d61726b 0:7fca1bf48117 169 //
0x6d61726b 0:7fca1bf48117 170 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
0x6d61726b 0:7fca1bf48117 171 if (FieldWidth != 0u) {
0x6d61726b 0:7fca1bf48117 172 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
0x6d61726b 0:7fca1bf48117 173 c = '0';
0x6d61726b 0:7fca1bf48117 174 } else {
0x6d61726b 0:7fca1bf48117 175 c = ' ';
0x6d61726b 0:7fca1bf48117 176 }
0x6d61726b 0:7fca1bf48117 177 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
0x6d61726b 0:7fca1bf48117 178 FieldWidth--;
0x6d61726b 0:7fca1bf48117 179 _StoreChar(pBufferDesc, c);
0x6d61726b 0:7fca1bf48117 180 if (pBufferDesc->ReturnValue < 0) {
0x6d61726b 0:7fca1bf48117 181 break;
0x6d61726b 0:7fca1bf48117 182 }
0x6d61726b 0:7fca1bf48117 183 }
0x6d61726b 0:7fca1bf48117 184 }
0x6d61726b 0:7fca1bf48117 185 }
0x6d61726b 0:7fca1bf48117 186 if (pBufferDesc->ReturnValue >= 0) {
0x6d61726b 0:7fca1bf48117 187 //
0x6d61726b 0:7fca1bf48117 188 // Compute Digit.
0x6d61726b 0:7fca1bf48117 189 // Loop until Digit has the value of the highest digit required.
0x6d61726b 0:7fca1bf48117 190 // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
0x6d61726b 0:7fca1bf48117 191 //
0x6d61726b 0:7fca1bf48117 192 while (1) {
0x6d61726b 0:7fca1bf48117 193 if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
0x6d61726b 0:7fca1bf48117 194 NumDigits--;
0x6d61726b 0:7fca1bf48117 195 } else {
0x6d61726b 0:7fca1bf48117 196 Div = v / Digit;
0x6d61726b 0:7fca1bf48117 197 if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done
0x6d61726b 0:7fca1bf48117 198 break;
0x6d61726b 0:7fca1bf48117 199 }
0x6d61726b 0:7fca1bf48117 200 }
0x6d61726b 0:7fca1bf48117 201 Digit *= Base;
0x6d61726b 0:7fca1bf48117 202 }
0x6d61726b 0:7fca1bf48117 203 //
0x6d61726b 0:7fca1bf48117 204 // Output digits
0x6d61726b 0:7fca1bf48117 205 //
0x6d61726b 0:7fca1bf48117 206 do {
0x6d61726b 0:7fca1bf48117 207 Div = v / Digit;
0x6d61726b 0:7fca1bf48117 208 v -= Div * Digit;
0x6d61726b 0:7fca1bf48117 209 _StoreChar(pBufferDesc, _aV2C[Div]);
0x6d61726b 0:7fca1bf48117 210 if (pBufferDesc->ReturnValue < 0) {
0x6d61726b 0:7fca1bf48117 211 break;
0x6d61726b 0:7fca1bf48117 212 }
0x6d61726b 0:7fca1bf48117 213 Digit /= Base;
0x6d61726b 0:7fca1bf48117 214 } while (Digit);
0x6d61726b 0:7fca1bf48117 215 //
0x6d61726b 0:7fca1bf48117 216 // Print trailing spaces if necessary
0x6d61726b 0:7fca1bf48117 217 //
0x6d61726b 0:7fca1bf48117 218 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
0x6d61726b 0:7fca1bf48117 219 if (FieldWidth != 0u) {
0x6d61726b 0:7fca1bf48117 220 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
0x6d61726b 0:7fca1bf48117 221 FieldWidth--;
0x6d61726b 0:7fca1bf48117 222 _StoreChar(pBufferDesc, ' ');
0x6d61726b 0:7fca1bf48117 223 if (pBufferDesc->ReturnValue < 0) {
0x6d61726b 0:7fca1bf48117 224 break;
0x6d61726b 0:7fca1bf48117 225 }
0x6d61726b 0:7fca1bf48117 226 }
0x6d61726b 0:7fca1bf48117 227 }
0x6d61726b 0:7fca1bf48117 228 }
0x6d61726b 0:7fca1bf48117 229 }
0x6d61726b 0:7fca1bf48117 230 }
0x6d61726b 0:7fca1bf48117 231
0x6d61726b 0:7fca1bf48117 232 /*********************************************************************
0x6d61726b 0:7fca1bf48117 233 *
0x6d61726b 0:7fca1bf48117 234 * _PrintInt
0x6d61726b 0:7fca1bf48117 235 */
0x6d61726b 0:7fca1bf48117 236 static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
0x6d61726b 0:7fca1bf48117 237 unsigned Width;
0x6d61726b 0:7fca1bf48117 238 int Number;
0x6d61726b 0:7fca1bf48117 239
0x6d61726b 0:7fca1bf48117 240 Number = (v < 0) ? -v : v;
0x6d61726b 0:7fca1bf48117 241
0x6d61726b 0:7fca1bf48117 242 //
0x6d61726b 0:7fca1bf48117 243 // Get actual field width
0x6d61726b 0:7fca1bf48117 244 //
0x6d61726b 0:7fca1bf48117 245 Width = 1u;
0x6d61726b 0:7fca1bf48117 246 while (Number >= (int)Base) {
0x6d61726b 0:7fca1bf48117 247 Number = (Number / (int)Base);
0x6d61726b 0:7fca1bf48117 248 Width++;
0x6d61726b 0:7fca1bf48117 249 }
0x6d61726b 0:7fca1bf48117 250 if (NumDigits > Width) {
0x6d61726b 0:7fca1bf48117 251 Width = NumDigits;
0x6d61726b 0:7fca1bf48117 252 }
0x6d61726b 0:7fca1bf48117 253 if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
0x6d61726b 0:7fca1bf48117 254 FieldWidth--;
0x6d61726b 0:7fca1bf48117 255 }
0x6d61726b 0:7fca1bf48117 256
0x6d61726b 0:7fca1bf48117 257 //
0x6d61726b 0:7fca1bf48117 258 // Print leading spaces if necessary
0x6d61726b 0:7fca1bf48117 259 //
0x6d61726b 0:7fca1bf48117 260 if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
0x6d61726b 0:7fca1bf48117 261 if (FieldWidth != 0u) {
0x6d61726b 0:7fca1bf48117 262 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
0x6d61726b 0:7fca1bf48117 263 FieldWidth--;
0x6d61726b 0:7fca1bf48117 264 _StoreChar(pBufferDesc, ' ');
0x6d61726b 0:7fca1bf48117 265 if (pBufferDesc->ReturnValue < 0) {
0x6d61726b 0:7fca1bf48117 266 break;
0x6d61726b 0:7fca1bf48117 267 }
0x6d61726b 0:7fca1bf48117 268 }
0x6d61726b 0:7fca1bf48117 269 }
0x6d61726b 0:7fca1bf48117 270 }
0x6d61726b 0:7fca1bf48117 271 //
0x6d61726b 0:7fca1bf48117 272 // Print sign if necessary
0x6d61726b 0:7fca1bf48117 273 //
0x6d61726b 0:7fca1bf48117 274 if (pBufferDesc->ReturnValue >= 0) {
0x6d61726b 0:7fca1bf48117 275 if (v < 0) {
0x6d61726b 0:7fca1bf48117 276 v = -v;
0x6d61726b 0:7fca1bf48117 277 _StoreChar(pBufferDesc, '-');
0x6d61726b 0:7fca1bf48117 278 } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
0x6d61726b 0:7fca1bf48117 279 _StoreChar(pBufferDesc, '+');
0x6d61726b 0:7fca1bf48117 280 } else {
0x6d61726b 0:7fca1bf48117 281
0x6d61726b 0:7fca1bf48117 282 }
0x6d61726b 0:7fca1bf48117 283 if (pBufferDesc->ReturnValue >= 0) {
0x6d61726b 0:7fca1bf48117 284 //
0x6d61726b 0:7fca1bf48117 285 // Print leading zeros if necessary
0x6d61726b 0:7fca1bf48117 286 //
0x6d61726b 0:7fca1bf48117 287 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
0x6d61726b 0:7fca1bf48117 288 if (FieldWidth != 0u) {
0x6d61726b 0:7fca1bf48117 289 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
0x6d61726b 0:7fca1bf48117 290 FieldWidth--;
0x6d61726b 0:7fca1bf48117 291 _StoreChar(pBufferDesc, '0');
0x6d61726b 0:7fca1bf48117 292 if (pBufferDesc->ReturnValue < 0) {
0x6d61726b 0:7fca1bf48117 293 break;
0x6d61726b 0:7fca1bf48117 294 }
0x6d61726b 0:7fca1bf48117 295 }
0x6d61726b 0:7fca1bf48117 296 }
0x6d61726b 0:7fca1bf48117 297 }
0x6d61726b 0:7fca1bf48117 298 if (pBufferDesc->ReturnValue >= 0) {
0x6d61726b 0:7fca1bf48117 299 //
0x6d61726b 0:7fca1bf48117 300 // Print number without sign
0x6d61726b 0:7fca1bf48117 301 //
0x6d61726b 0:7fca1bf48117 302 _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
0x6d61726b 0:7fca1bf48117 303 }
0x6d61726b 0:7fca1bf48117 304 }
0x6d61726b 0:7fca1bf48117 305 }
0x6d61726b 0:7fca1bf48117 306 }
0x6d61726b 0:7fca1bf48117 307
0x6d61726b 0:7fca1bf48117 308 /*********************************************************************
0x6d61726b 0:7fca1bf48117 309 *
0x6d61726b 0:7fca1bf48117 310 * Public code
0x6d61726b 0:7fca1bf48117 311 *
0x6d61726b 0:7fca1bf48117 312 **********************************************************************
0x6d61726b 0:7fca1bf48117 313 */
0x6d61726b 0:7fca1bf48117 314 /*********************************************************************
0x6d61726b 0:7fca1bf48117 315 *
0x6d61726b 0:7fca1bf48117 316 * SEGGER_RTT_vprintf
0x6d61726b 0:7fca1bf48117 317 *
0x6d61726b 0:7fca1bf48117 318 * Function description
0x6d61726b 0:7fca1bf48117 319 * Stores a formatted string in SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 320 * This data is read by the host.
0x6d61726b 0:7fca1bf48117 321 *
0x6d61726b 0:7fca1bf48117 322 * Parameters
0x6d61726b 0:7fca1bf48117 323 * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
0x6d61726b 0:7fca1bf48117 324 * sFormat Pointer to format string
0x6d61726b 0:7fca1bf48117 325 * pParamList Pointer to the list of arguments for the format string
0x6d61726b 0:7fca1bf48117 326 *
0x6d61726b 0:7fca1bf48117 327 * Return values
0x6d61726b 0:7fca1bf48117 328 * >= 0: Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 329 * < 0: Error
0x6d61726b 0:7fca1bf48117 330 */
0x6d61726b 0:7fca1bf48117 331 int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
0x6d61726b 0:7fca1bf48117 332 char c;
0x6d61726b 0:7fca1bf48117 333 SEGGER_RTT_PRINTF_DESC BufferDesc;
0x6d61726b 0:7fca1bf48117 334 int v;
0x6d61726b 0:7fca1bf48117 335 unsigned NumDigits;
0x6d61726b 0:7fca1bf48117 336 unsigned FormatFlags;
0x6d61726b 0:7fca1bf48117 337 unsigned FieldWidth;
0x6d61726b 0:7fca1bf48117 338 char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
0x6d61726b 0:7fca1bf48117 339
0x6d61726b 0:7fca1bf48117 340 BufferDesc.pBuffer = acBuffer;
0x6d61726b 0:7fca1bf48117 341 BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
0x6d61726b 0:7fca1bf48117 342 BufferDesc.Cnt = 0u;
0x6d61726b 0:7fca1bf48117 343 BufferDesc.RTTBufferIndex = BufferIndex;
0x6d61726b 0:7fca1bf48117 344 BufferDesc.ReturnValue = 0;
0x6d61726b 0:7fca1bf48117 345
0x6d61726b 0:7fca1bf48117 346 do {
0x6d61726b 0:7fca1bf48117 347 c = *sFormat;
0x6d61726b 0:7fca1bf48117 348 sFormat++;
0x6d61726b 0:7fca1bf48117 349 if (c == 0u) {
0x6d61726b 0:7fca1bf48117 350 break;
0x6d61726b 0:7fca1bf48117 351 }
0x6d61726b 0:7fca1bf48117 352 if (c == '%') {
0x6d61726b 0:7fca1bf48117 353 //
0x6d61726b 0:7fca1bf48117 354 // Filter out flags
0x6d61726b 0:7fca1bf48117 355 //
0x6d61726b 0:7fca1bf48117 356 FormatFlags = 0u;
0x6d61726b 0:7fca1bf48117 357 v = 1;
0x6d61726b 0:7fca1bf48117 358 do {
0x6d61726b 0:7fca1bf48117 359 c = *sFormat;
0x6d61726b 0:7fca1bf48117 360 switch (c) {
0x6d61726b 0:7fca1bf48117 361 case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
0x6d61726b 0:7fca1bf48117 362 case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
0x6d61726b 0:7fca1bf48117 363 case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
0x6d61726b 0:7fca1bf48117 364 case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
0x6d61726b 0:7fca1bf48117 365 default: v = 0; break;
0x6d61726b 0:7fca1bf48117 366 }
0x6d61726b 0:7fca1bf48117 367 } while (v);
0x6d61726b 0:7fca1bf48117 368 //
0x6d61726b 0:7fca1bf48117 369 // filter out field with
0x6d61726b 0:7fca1bf48117 370 //
0x6d61726b 0:7fca1bf48117 371 FieldWidth = 0u;
0x6d61726b 0:7fca1bf48117 372 do {
0x6d61726b 0:7fca1bf48117 373 c = *sFormat;
0x6d61726b 0:7fca1bf48117 374 if ((c < '0') || (c > '9')) {
0x6d61726b 0:7fca1bf48117 375 break;
0x6d61726b 0:7fca1bf48117 376 }
0x6d61726b 0:7fca1bf48117 377 sFormat++;
0x6d61726b 0:7fca1bf48117 378 FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
0x6d61726b 0:7fca1bf48117 379 } while (1);
0x6d61726b 0:7fca1bf48117 380
0x6d61726b 0:7fca1bf48117 381 //
0x6d61726b 0:7fca1bf48117 382 // Filter out precision (number of digits to display)
0x6d61726b 0:7fca1bf48117 383 //
0x6d61726b 0:7fca1bf48117 384 NumDigits = 0u;
0x6d61726b 0:7fca1bf48117 385 c = *sFormat;
0x6d61726b 0:7fca1bf48117 386 if (c == '.') {
0x6d61726b 0:7fca1bf48117 387 sFormat++;
0x6d61726b 0:7fca1bf48117 388 do {
0x6d61726b 0:7fca1bf48117 389 c = *sFormat;
0x6d61726b 0:7fca1bf48117 390 if ((c < '0') || (c > '9')) {
0x6d61726b 0:7fca1bf48117 391 break;
0x6d61726b 0:7fca1bf48117 392 }
0x6d61726b 0:7fca1bf48117 393 sFormat++;
0x6d61726b 0:7fca1bf48117 394 NumDigits = NumDigits * 10u + ((unsigned)c - '0');
0x6d61726b 0:7fca1bf48117 395 } while (1);
0x6d61726b 0:7fca1bf48117 396 }
0x6d61726b 0:7fca1bf48117 397 //
0x6d61726b 0:7fca1bf48117 398 // Filter out length modifier
0x6d61726b 0:7fca1bf48117 399 //
0x6d61726b 0:7fca1bf48117 400 c = *sFormat;
0x6d61726b 0:7fca1bf48117 401 do {
0x6d61726b 0:7fca1bf48117 402 if ((c == 'l') || (c == 'h')) {
0x6d61726b 0:7fca1bf48117 403 sFormat++;
0x6d61726b 0:7fca1bf48117 404 c = *sFormat;
0x6d61726b 0:7fca1bf48117 405 } else {
0x6d61726b 0:7fca1bf48117 406 break;
0x6d61726b 0:7fca1bf48117 407 }
0x6d61726b 0:7fca1bf48117 408 } while (1);
0x6d61726b 0:7fca1bf48117 409 //
0x6d61726b 0:7fca1bf48117 410 // Handle specifiers
0x6d61726b 0:7fca1bf48117 411 //
0x6d61726b 0:7fca1bf48117 412 switch (c) {
0x6d61726b 0:7fca1bf48117 413 case 'c': {
0x6d61726b 0:7fca1bf48117 414 char c0;
0x6d61726b 0:7fca1bf48117 415 v = va_arg(*pParamList, int);
0x6d61726b 0:7fca1bf48117 416 c0 = (char)v;
0x6d61726b 0:7fca1bf48117 417 _StoreChar(&BufferDesc, c0);
0x6d61726b 0:7fca1bf48117 418 break;
0x6d61726b 0:7fca1bf48117 419 }
0x6d61726b 0:7fca1bf48117 420 case 'd':
0x6d61726b 0:7fca1bf48117 421 v = va_arg(*pParamList, int);
0x6d61726b 0:7fca1bf48117 422 _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
0x6d61726b 0:7fca1bf48117 423 break;
0x6d61726b 0:7fca1bf48117 424 case 'u':
0x6d61726b 0:7fca1bf48117 425 v = va_arg(*pParamList, int);
0x6d61726b 0:7fca1bf48117 426 _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
0x6d61726b 0:7fca1bf48117 427 break;
0x6d61726b 0:7fca1bf48117 428 case 'x':
0x6d61726b 0:7fca1bf48117 429 case 'X':
0x6d61726b 0:7fca1bf48117 430 v = va_arg(*pParamList, int);
0x6d61726b 0:7fca1bf48117 431 _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
0x6d61726b 0:7fca1bf48117 432 break;
0x6d61726b 0:7fca1bf48117 433 case 's':
0x6d61726b 0:7fca1bf48117 434 {
0x6d61726b 0:7fca1bf48117 435 const char * s = va_arg(*pParamList, const char *);
0x6d61726b 0:7fca1bf48117 436 do {
0x6d61726b 0:7fca1bf48117 437 c = *s;
0x6d61726b 0:7fca1bf48117 438 s++;
0x6d61726b 0:7fca1bf48117 439 if (c == '\0') {
0x6d61726b 0:7fca1bf48117 440 break;
0x6d61726b 0:7fca1bf48117 441 }
0x6d61726b 0:7fca1bf48117 442 _StoreChar(&BufferDesc, c);
0x6d61726b 0:7fca1bf48117 443 } while (BufferDesc.ReturnValue >= 0);
0x6d61726b 0:7fca1bf48117 444 }
0x6d61726b 0:7fca1bf48117 445 break;
0x6d61726b 0:7fca1bf48117 446 case 'p':
0x6d61726b 0:7fca1bf48117 447 v = va_arg(*pParamList, int);
0x6d61726b 0:7fca1bf48117 448 _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u);
0x6d61726b 0:7fca1bf48117 449 break;
0x6d61726b 0:7fca1bf48117 450 case '%':
0x6d61726b 0:7fca1bf48117 451 _StoreChar(&BufferDesc, '%');
0x6d61726b 0:7fca1bf48117 452 break;
0x6d61726b 0:7fca1bf48117 453 default:
0x6d61726b 0:7fca1bf48117 454 break;
0x6d61726b 0:7fca1bf48117 455 }
0x6d61726b 0:7fca1bf48117 456 sFormat++;
0x6d61726b 0:7fca1bf48117 457 } else {
0x6d61726b 0:7fca1bf48117 458 _StoreChar(&BufferDesc, c);
0x6d61726b 0:7fca1bf48117 459 }
0x6d61726b 0:7fca1bf48117 460 } while (BufferDesc.ReturnValue >= 0);
0x6d61726b 0:7fca1bf48117 461
0x6d61726b 0:7fca1bf48117 462 if (BufferDesc.ReturnValue > 0) {
0x6d61726b 0:7fca1bf48117 463 //
0x6d61726b 0:7fca1bf48117 464 // Write remaining data, if any
0x6d61726b 0:7fca1bf48117 465 //
0x6d61726b 0:7fca1bf48117 466 if (BufferDesc.Cnt != 0u) {
0x6d61726b 0:7fca1bf48117 467 SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
0x6d61726b 0:7fca1bf48117 468 }
0x6d61726b 0:7fca1bf48117 469 BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
0x6d61726b 0:7fca1bf48117 470 }
0x6d61726b 0:7fca1bf48117 471 return BufferDesc.ReturnValue;
0x6d61726b 0:7fca1bf48117 472 }
0x6d61726b 0:7fca1bf48117 473
0x6d61726b 0:7fca1bf48117 474 /*********************************************************************
0x6d61726b 0:7fca1bf48117 475 *
0x6d61726b 0:7fca1bf48117 476 * SEGGER_RTT_printf
0x6d61726b 0:7fca1bf48117 477 *
0x6d61726b 0:7fca1bf48117 478 * Function description
0x6d61726b 0:7fca1bf48117 479 * Stores a formatted string in SEGGER RTT control block.
0x6d61726b 0:7fca1bf48117 480 * This data is read by the host.
0x6d61726b 0:7fca1bf48117 481 *
0x6d61726b 0:7fca1bf48117 482 * Parameters
0x6d61726b 0:7fca1bf48117 483 * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
0x6d61726b 0:7fca1bf48117 484 * sFormat Pointer to format string, followed by the arguments for conversion
0x6d61726b 0:7fca1bf48117 485 *
0x6d61726b 0:7fca1bf48117 486 * Return values
0x6d61726b 0:7fca1bf48117 487 * >= 0: Number of bytes which have been stored in the "Up"-buffer.
0x6d61726b 0:7fca1bf48117 488 * < 0: Error
0x6d61726b 0:7fca1bf48117 489 *
0x6d61726b 0:7fca1bf48117 490 * Notes
0x6d61726b 0:7fca1bf48117 491 * (1) Conversion specifications have following syntax:
0x6d61726b 0:7fca1bf48117 492 * %[flags][FieldWidth][.Precision]ConversionSpecifier
0x6d61726b 0:7fca1bf48117 493 * (2) Supported flags:
0x6d61726b 0:7fca1bf48117 494 * -: Left justify within the field width
0x6d61726b 0:7fca1bf48117 495 * +: Always print sign extension for signed conversions
0x6d61726b 0:7fca1bf48117 496 * 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision
0x6d61726b 0:7fca1bf48117 497 * Supported conversion specifiers:
0x6d61726b 0:7fca1bf48117 498 * c: Print the argument as one char
0x6d61726b 0:7fca1bf48117 499 * d: Print the argument as a signed integer
0x6d61726b 0:7fca1bf48117 500 * u: Print the argument as an unsigned integer
0x6d61726b 0:7fca1bf48117 501 * x: Print the argument as an hexadecimal integer
0x6d61726b 0:7fca1bf48117 502 * s: Print the string pointed to by the argument
0x6d61726b 0:7fca1bf48117 503 * p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)
0x6d61726b 0:7fca1bf48117 504 */
0x6d61726b 0:7fca1bf48117 505 int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {
0x6d61726b 0:7fca1bf48117 506 int r;
0x6d61726b 0:7fca1bf48117 507 va_list ParamList;
0x6d61726b 0:7fca1bf48117 508
0x6d61726b 0:7fca1bf48117 509 va_start(ParamList, sFormat);
0x6d61726b 0:7fca1bf48117 510 r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);
0x6d61726b 0:7fca1bf48117 511 va_end(ParamList);
0x6d61726b 0:7fca1bf48117 512 return r;
0x6d61726b 0:7fca1bf48117 513 }
0x6d61726b 0:7fca1bf48117 514 /*************************** End of file ****************************/