RTT Debugger Library
Dependents: BREAK_SENSOR_LED MPU9250_simple MPU9250_tap_better Sensor_tap_BLE ... more
SEGGER_RTT_printf.c@0:7dcd871d726b, 2017-12-18 (annotated)
- Committer:
- Anythingconnected
- Date:
- Mon Dec 18 10:17:08 2017 +0000
- Revision:
- 0:7dcd871d726b
1
Who changed what in which revision?
User | Revision | Line number | New 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_printf.c |
Anythingconnected | 0:7dcd871d726b | 13 | Date : 17 Dec 2014 |
Anythingconnected | 0:7dcd871d726b | 14 | Purpose : Replacement for printf to write formatted data via RTT |
Anythingconnected | 0:7dcd871d726b | 15 | ---------------------------END-OF-HEADER------------------------------ |
Anythingconnected | 0:7dcd871d726b | 16 | */ |
Anythingconnected | 0:7dcd871d726b | 17 | #include "SEGGER_RTT.h" |
Anythingconnected | 0:7dcd871d726b | 18 | #include "SEGGER_RTT_Conf.h" |
Anythingconnected | 0:7dcd871d726b | 19 | |
Anythingconnected | 0:7dcd871d726b | 20 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 21 | * |
Anythingconnected | 0:7dcd871d726b | 22 | * Defines, configurable |
Anythingconnected | 0:7dcd871d726b | 23 | * |
Anythingconnected | 0:7dcd871d726b | 24 | ********************************************************************** |
Anythingconnected | 0:7dcd871d726b | 25 | */ |
Anythingconnected | 0:7dcd871d726b | 26 | |
Anythingconnected | 0:7dcd871d726b | 27 | #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE |
Anythingconnected | 0:7dcd871d726b | 28 | #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) |
Anythingconnected | 0:7dcd871d726b | 29 | #endif |
Anythingconnected | 0:7dcd871d726b | 30 | |
Anythingconnected | 0:7dcd871d726b | 31 | #include <stdlib.h> |
Anythingconnected | 0:7dcd871d726b | 32 | #include <stdarg.h> |
Anythingconnected | 0:7dcd871d726b | 33 | |
Anythingconnected | 0:7dcd871d726b | 34 | |
Anythingconnected | 0:7dcd871d726b | 35 | #define FORMAT_FLAG_LEFT_JUSTIFY (1 << 0) |
Anythingconnected | 0:7dcd871d726b | 36 | #define FORMAT_FLAG_PAD_ZERO (1 << 1) |
Anythingconnected | 0:7dcd871d726b | 37 | #define FORMAT_FLAG_PRINT_SIGN (1 << 2) |
Anythingconnected | 0:7dcd871d726b | 38 | #define FORMAT_FLAG_ALTERNATE (1 << 3) |
Anythingconnected | 0:7dcd871d726b | 39 | |
Anythingconnected | 0:7dcd871d726b | 40 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 41 | * |
Anythingconnected | 0:7dcd871d726b | 42 | * Types |
Anythingconnected | 0:7dcd871d726b | 43 | * |
Anythingconnected | 0:7dcd871d726b | 44 | ********************************************************************** |
Anythingconnected | 0:7dcd871d726b | 45 | */ |
Anythingconnected | 0:7dcd871d726b | 46 | |
Anythingconnected | 0:7dcd871d726b | 47 | typedef struct { |
Anythingconnected | 0:7dcd871d726b | 48 | char* pBuffer; |
Anythingconnected | 0:7dcd871d726b | 49 | int BufferSize; |
Anythingconnected | 0:7dcd871d726b | 50 | int Cnt; |
Anythingconnected | 0:7dcd871d726b | 51 | |
Anythingconnected | 0:7dcd871d726b | 52 | int ReturnValue; |
Anythingconnected | 0:7dcd871d726b | 53 | |
Anythingconnected | 0:7dcd871d726b | 54 | unsigned RTTBufferIndex; |
Anythingconnected | 0:7dcd871d726b | 55 | } SEGGER_RTT_PRINTF_DESC; |
Anythingconnected | 0:7dcd871d726b | 56 | |
Anythingconnected | 0:7dcd871d726b | 57 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 58 | * |
Anythingconnected | 0:7dcd871d726b | 59 | * Function prototypes |
Anythingconnected | 0:7dcd871d726b | 60 | * |
Anythingconnected | 0:7dcd871d726b | 61 | ********************************************************************** |
Anythingconnected | 0:7dcd871d726b | 62 | */ |
Anythingconnected | 0:7dcd871d726b | 63 | int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); |
Anythingconnected | 0:7dcd871d726b | 64 | |
Anythingconnected | 0:7dcd871d726b | 65 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 66 | * |
Anythingconnected | 0:7dcd871d726b | 67 | * Static code |
Anythingconnected | 0:7dcd871d726b | 68 | * |
Anythingconnected | 0:7dcd871d726b | 69 | ********************************************************************** |
Anythingconnected | 0:7dcd871d726b | 70 | */ |
Anythingconnected | 0:7dcd871d726b | 71 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 72 | * |
Anythingconnected | 0:7dcd871d726b | 73 | * _StoreChar |
Anythingconnected | 0:7dcd871d726b | 74 | */ |
Anythingconnected | 0:7dcd871d726b | 75 | static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { |
Anythingconnected | 0:7dcd871d726b | 76 | int Cnt; |
Anythingconnected | 0:7dcd871d726b | 77 | |
Anythingconnected | 0:7dcd871d726b | 78 | Cnt = p->Cnt; |
Anythingconnected | 0:7dcd871d726b | 79 | if ((Cnt + 1) <= p->BufferSize) { |
Anythingconnected | 0:7dcd871d726b | 80 | *(p->pBuffer + Cnt) = c; |
Anythingconnected | 0:7dcd871d726b | 81 | p->Cnt = Cnt + 1; |
Anythingconnected | 0:7dcd871d726b | 82 | p->ReturnValue++; |
Anythingconnected | 0:7dcd871d726b | 83 | } |
Anythingconnected | 0:7dcd871d726b | 84 | // |
Anythingconnected | 0:7dcd871d726b | 85 | // Write part of string, when the buffer is full |
Anythingconnected | 0:7dcd871d726b | 86 | // |
Anythingconnected | 0:7dcd871d726b | 87 | if (p->Cnt == p->BufferSize) { |
Anythingconnected | 0:7dcd871d726b | 88 | if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { |
Anythingconnected | 0:7dcd871d726b | 89 | p->ReturnValue = -1; |
Anythingconnected | 0:7dcd871d726b | 90 | } else { |
Anythingconnected | 0:7dcd871d726b | 91 | p->Cnt = 0; |
Anythingconnected | 0:7dcd871d726b | 92 | } |
Anythingconnected | 0:7dcd871d726b | 93 | } |
Anythingconnected | 0:7dcd871d726b | 94 | } |
Anythingconnected | 0:7dcd871d726b | 95 | |
Anythingconnected | 0:7dcd871d726b | 96 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 97 | * |
Anythingconnected | 0:7dcd871d726b | 98 | * _PrintUnsigned |
Anythingconnected | 0:7dcd871d726b | 99 | */ |
Anythingconnected | 0:7dcd871d726b | 100 | static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, int NumDigits, unsigned FieldWidth, unsigned FormatFlags) { |
Anythingconnected | 0:7dcd871d726b | 101 | static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; |
Anythingconnected | 0:7dcd871d726b | 102 | unsigned Div; |
Anythingconnected | 0:7dcd871d726b | 103 | unsigned Digit = 1; |
Anythingconnected | 0:7dcd871d726b | 104 | unsigned Number; |
Anythingconnected | 0:7dcd871d726b | 105 | unsigned Width; |
Anythingconnected | 0:7dcd871d726b | 106 | char c; |
Anythingconnected | 0:7dcd871d726b | 107 | |
Anythingconnected | 0:7dcd871d726b | 108 | Number = v; |
Anythingconnected | 0:7dcd871d726b | 109 | |
Anythingconnected | 0:7dcd871d726b | 110 | // |
Anythingconnected | 0:7dcd871d726b | 111 | // Get actual field width |
Anythingconnected | 0:7dcd871d726b | 112 | // |
Anythingconnected | 0:7dcd871d726b | 113 | Width = 1; |
Anythingconnected | 0:7dcd871d726b | 114 | while (Number >= Base) { |
Anythingconnected | 0:7dcd871d726b | 115 | Number = (Number / Base); |
Anythingconnected | 0:7dcd871d726b | 116 | Width++; |
Anythingconnected | 0:7dcd871d726b | 117 | } |
Anythingconnected | 0:7dcd871d726b | 118 | if ((unsigned)NumDigits > Width) { |
Anythingconnected | 0:7dcd871d726b | 119 | Width = NumDigits; |
Anythingconnected | 0:7dcd871d726b | 120 | } |
Anythingconnected | 0:7dcd871d726b | 121 | // |
Anythingconnected | 0:7dcd871d726b | 122 | // Print leading chars if necessary |
Anythingconnected | 0:7dcd871d726b | 123 | // |
Anythingconnected | 0:7dcd871d726b | 124 | if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0) { |
Anythingconnected | 0:7dcd871d726b | 125 | if (FieldWidth != 0) { |
Anythingconnected | 0:7dcd871d726b | 126 | if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0)) { |
Anythingconnected | 0:7dcd871d726b | 127 | c = '0'; |
Anythingconnected | 0:7dcd871d726b | 128 | } else { |
Anythingconnected | 0:7dcd871d726b | 129 | c = ' '; |
Anythingconnected | 0:7dcd871d726b | 130 | } |
Anythingconnected | 0:7dcd871d726b | 131 | while ((FieldWidth != 0) && (Width < FieldWidth--)) { |
Anythingconnected | 0:7dcd871d726b | 132 | _StoreChar(pBufferDesc, c); |
Anythingconnected | 0:7dcd871d726b | 133 | if (pBufferDesc->ReturnValue < 0) { |
Anythingconnected | 0:7dcd871d726b | 134 | return; |
Anythingconnected | 0:7dcd871d726b | 135 | } |
Anythingconnected | 0:7dcd871d726b | 136 | } |
Anythingconnected | 0:7dcd871d726b | 137 | } |
Anythingconnected | 0:7dcd871d726b | 138 | } |
Anythingconnected | 0:7dcd871d726b | 139 | // |
Anythingconnected | 0:7dcd871d726b | 140 | // Count how many digits are required by precision |
Anythingconnected | 0:7dcd871d726b | 141 | // |
Anythingconnected | 0:7dcd871d726b | 142 | while (((v / Digit) >= Base) | (NumDigits-- > 1)) { |
Anythingconnected | 0:7dcd871d726b | 143 | Digit *= Base; |
Anythingconnected | 0:7dcd871d726b | 144 | } |
Anythingconnected | 0:7dcd871d726b | 145 | // |
Anythingconnected | 0:7dcd871d726b | 146 | // Output digits |
Anythingconnected | 0:7dcd871d726b | 147 | // |
Anythingconnected | 0:7dcd871d726b | 148 | do { |
Anythingconnected | 0:7dcd871d726b | 149 | Div = v / Digit; |
Anythingconnected | 0:7dcd871d726b | 150 | v -= Div * Digit; |
Anythingconnected | 0:7dcd871d726b | 151 | _StoreChar(pBufferDesc, _aV2C[Div]); |
Anythingconnected | 0:7dcd871d726b | 152 | if (pBufferDesc->ReturnValue < 0) { |
Anythingconnected | 0:7dcd871d726b | 153 | break; |
Anythingconnected | 0:7dcd871d726b | 154 | } |
Anythingconnected | 0:7dcd871d726b | 155 | Digit /= Base; |
Anythingconnected | 0:7dcd871d726b | 156 | } while (Digit); |
Anythingconnected | 0:7dcd871d726b | 157 | // |
Anythingconnected | 0:7dcd871d726b | 158 | // Print trailing spaces if necessary |
Anythingconnected | 0:7dcd871d726b | 159 | // |
Anythingconnected | 0:7dcd871d726b | 160 | if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { |
Anythingconnected | 0:7dcd871d726b | 161 | if (FieldWidth != 0) { |
Anythingconnected | 0:7dcd871d726b | 162 | while ((FieldWidth != 0) && (Width < FieldWidth--)) { |
Anythingconnected | 0:7dcd871d726b | 163 | _StoreChar(pBufferDesc, ' '); |
Anythingconnected | 0:7dcd871d726b | 164 | if (pBufferDesc->ReturnValue < 0) { |
Anythingconnected | 0:7dcd871d726b | 165 | return; |
Anythingconnected | 0:7dcd871d726b | 166 | } |
Anythingconnected | 0:7dcd871d726b | 167 | } |
Anythingconnected | 0:7dcd871d726b | 168 | } |
Anythingconnected | 0:7dcd871d726b | 169 | } |
Anythingconnected | 0:7dcd871d726b | 170 | } |
Anythingconnected | 0:7dcd871d726b | 171 | |
Anythingconnected | 0:7dcd871d726b | 172 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 173 | * |
Anythingconnected | 0:7dcd871d726b | 174 | * _PrintInt |
Anythingconnected | 0:7dcd871d726b | 175 | */ |
Anythingconnected | 0:7dcd871d726b | 176 | static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { |
Anythingconnected | 0:7dcd871d726b | 177 | unsigned Width; |
Anythingconnected | 0:7dcd871d726b | 178 | unsigned Number; |
Anythingconnected | 0:7dcd871d726b | 179 | |
Anythingconnected | 0:7dcd871d726b | 180 | Number = (v < 0) ? -v : v; |
Anythingconnected | 0:7dcd871d726b | 181 | |
Anythingconnected | 0:7dcd871d726b | 182 | // |
Anythingconnected | 0:7dcd871d726b | 183 | // Get actual field width |
Anythingconnected | 0:7dcd871d726b | 184 | // |
Anythingconnected | 0:7dcd871d726b | 185 | Width = 1; |
Anythingconnected | 0:7dcd871d726b | 186 | while (Number >= Base) { |
Anythingconnected | 0:7dcd871d726b | 187 | Number = (Number / Base); |
Anythingconnected | 0:7dcd871d726b | 188 | Width++; |
Anythingconnected | 0:7dcd871d726b | 189 | } |
Anythingconnected | 0:7dcd871d726b | 190 | if (NumDigits > Width) { |
Anythingconnected | 0:7dcd871d726b | 191 | Width = NumDigits; |
Anythingconnected | 0:7dcd871d726b | 192 | } |
Anythingconnected | 0:7dcd871d726b | 193 | if ((FieldWidth > 0) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { |
Anythingconnected | 0:7dcd871d726b | 194 | FieldWidth--; |
Anythingconnected | 0:7dcd871d726b | 195 | } |
Anythingconnected | 0:7dcd871d726b | 196 | |
Anythingconnected | 0:7dcd871d726b | 197 | // |
Anythingconnected | 0:7dcd871d726b | 198 | // Print leading spaces if necessary |
Anythingconnected | 0:7dcd871d726b | 199 | // |
Anythingconnected | 0:7dcd871d726b | 200 | if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0) || (NumDigits != 0)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0)) { |
Anythingconnected | 0:7dcd871d726b | 201 | if (FieldWidth != 0) { |
Anythingconnected | 0:7dcd871d726b | 202 | while ((FieldWidth != 0) && (Width < FieldWidth--)) { |
Anythingconnected | 0:7dcd871d726b | 203 | _StoreChar(pBufferDesc, ' '); |
Anythingconnected | 0:7dcd871d726b | 204 | if (pBufferDesc->ReturnValue < 0) { |
Anythingconnected | 0:7dcd871d726b | 205 | return; |
Anythingconnected | 0:7dcd871d726b | 206 | } |
Anythingconnected | 0:7dcd871d726b | 207 | } |
Anythingconnected | 0:7dcd871d726b | 208 | } |
Anythingconnected | 0:7dcd871d726b | 209 | } |
Anythingconnected | 0:7dcd871d726b | 210 | // |
Anythingconnected | 0:7dcd871d726b | 211 | // Print sign if necessary |
Anythingconnected | 0:7dcd871d726b | 212 | // |
Anythingconnected | 0:7dcd871d726b | 213 | if (v < 0) { |
Anythingconnected | 0:7dcd871d726b | 214 | v = -v; |
Anythingconnected | 0:7dcd871d726b | 215 | _StoreChar(pBufferDesc, '-'); |
Anythingconnected | 0:7dcd871d726b | 216 | if (pBufferDesc->ReturnValue < 0) { |
Anythingconnected | 0:7dcd871d726b | 217 | return; |
Anythingconnected | 0:7dcd871d726b | 218 | } |
Anythingconnected | 0:7dcd871d726b | 219 | } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { |
Anythingconnected | 0:7dcd871d726b | 220 | _StoreChar(pBufferDesc, '+'); |
Anythingconnected | 0:7dcd871d726b | 221 | if (pBufferDesc->ReturnValue < 0) { |
Anythingconnected | 0:7dcd871d726b | 222 | return; |
Anythingconnected | 0:7dcd871d726b | 223 | } |
Anythingconnected | 0:7dcd871d726b | 224 | } |
Anythingconnected | 0:7dcd871d726b | 225 | // |
Anythingconnected | 0:7dcd871d726b | 226 | // Print leading zeros if necessary |
Anythingconnected | 0:7dcd871d726b | 227 | // |
Anythingconnected | 0:7dcd871d726b | 228 | if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0) && (NumDigits == 0)) { |
Anythingconnected | 0:7dcd871d726b | 229 | if (FieldWidth != 0) { |
Anythingconnected | 0:7dcd871d726b | 230 | while ((FieldWidth != 0) && (Width < FieldWidth--)) { |
Anythingconnected | 0:7dcd871d726b | 231 | _StoreChar(pBufferDesc, '0'); |
Anythingconnected | 0:7dcd871d726b | 232 | if (pBufferDesc->ReturnValue < 0) { |
Anythingconnected | 0:7dcd871d726b | 233 | return; |
Anythingconnected | 0:7dcd871d726b | 234 | } |
Anythingconnected | 0:7dcd871d726b | 235 | } |
Anythingconnected | 0:7dcd871d726b | 236 | } |
Anythingconnected | 0:7dcd871d726b | 237 | } |
Anythingconnected | 0:7dcd871d726b | 238 | |
Anythingconnected | 0:7dcd871d726b | 239 | // |
Anythingconnected | 0:7dcd871d726b | 240 | // Print number without sign |
Anythingconnected | 0:7dcd871d726b | 241 | // |
Anythingconnected | 0:7dcd871d726b | 242 | _PrintUnsigned(pBufferDesc, v, Base, NumDigits, FieldWidth, FormatFlags); |
Anythingconnected | 0:7dcd871d726b | 243 | } |
Anythingconnected | 0:7dcd871d726b | 244 | |
Anythingconnected | 0:7dcd871d726b | 245 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 246 | * |
Anythingconnected | 0:7dcd871d726b | 247 | * Public code |
Anythingconnected | 0:7dcd871d726b | 248 | * |
Anythingconnected | 0:7dcd871d726b | 249 | ********************************************************************** |
Anythingconnected | 0:7dcd871d726b | 250 | */ |
Anythingconnected | 0:7dcd871d726b | 251 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 252 | * |
Anythingconnected | 0:7dcd871d726b | 253 | * SEGGER_RTT_vprintf |
Anythingconnected | 0:7dcd871d726b | 254 | * |
Anythingconnected | 0:7dcd871d726b | 255 | * Function description |
Anythingconnected | 0:7dcd871d726b | 256 | * Stores a formatted string in SEGGER RTT control block. |
Anythingconnected | 0:7dcd871d726b | 257 | * This data is read by the host. |
Anythingconnected | 0:7dcd871d726b | 258 | * |
Anythingconnected | 0:7dcd871d726b | 259 | * Parameters |
Anythingconnected | 0:7dcd871d726b | 260 | * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") |
Anythingconnected | 0:7dcd871d726b | 261 | * sFormat Pointer to format string |
Anythingconnected | 0:7dcd871d726b | 262 | * pParamList Pointer to the list of arguments for the format string |
Anythingconnected | 0:7dcd871d726b | 263 | * |
Anythingconnected | 0:7dcd871d726b | 264 | * Return values |
Anythingconnected | 0:7dcd871d726b | 265 | * >= 0: Number of bytes which have been stored in the "Up"-buffer. |
Anythingconnected | 0:7dcd871d726b | 266 | * < 0: Error |
Anythingconnected | 0:7dcd871d726b | 267 | */ |
Anythingconnected | 0:7dcd871d726b | 268 | int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { |
Anythingconnected | 0:7dcd871d726b | 269 | char c; |
Anythingconnected | 0:7dcd871d726b | 270 | SEGGER_RTT_PRINTF_DESC BufferDesc; |
Anythingconnected | 0:7dcd871d726b | 271 | int v; |
Anythingconnected | 0:7dcd871d726b | 272 | unsigned NumDigits; |
Anythingconnected | 0:7dcd871d726b | 273 | unsigned FormatFlags; |
Anythingconnected | 0:7dcd871d726b | 274 | unsigned FieldWidth; |
Anythingconnected | 0:7dcd871d726b | 275 | char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; |
Anythingconnected | 0:7dcd871d726b | 276 | |
Anythingconnected | 0:7dcd871d726b | 277 | BufferDesc.pBuffer = acBuffer; |
Anythingconnected | 0:7dcd871d726b | 278 | BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; |
Anythingconnected | 0:7dcd871d726b | 279 | BufferDesc.Cnt = 0; |
Anythingconnected | 0:7dcd871d726b | 280 | BufferDesc.RTTBufferIndex = BufferIndex; |
Anythingconnected | 0:7dcd871d726b | 281 | BufferDesc.ReturnValue = 0; |
Anythingconnected | 0:7dcd871d726b | 282 | |
Anythingconnected | 0:7dcd871d726b | 283 | do { |
Anythingconnected | 0:7dcd871d726b | 284 | c = *sFormat++; |
Anythingconnected | 0:7dcd871d726b | 285 | if (c == 0) { |
Anythingconnected | 0:7dcd871d726b | 286 | break; |
Anythingconnected | 0:7dcd871d726b | 287 | } |
Anythingconnected | 0:7dcd871d726b | 288 | if (c == '%') { |
Anythingconnected | 0:7dcd871d726b | 289 | // |
Anythingconnected | 0:7dcd871d726b | 290 | // Filter out flags |
Anythingconnected | 0:7dcd871d726b | 291 | // |
Anythingconnected | 0:7dcd871d726b | 292 | FormatFlags = 0; |
Anythingconnected | 0:7dcd871d726b | 293 | do { |
Anythingconnected | 0:7dcd871d726b | 294 | c = *sFormat; |
Anythingconnected | 0:7dcd871d726b | 295 | switch (c) { |
Anythingconnected | 0:7dcd871d726b | 296 | case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; |
Anythingconnected | 0:7dcd871d726b | 297 | case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; |
Anythingconnected | 0:7dcd871d726b | 298 | case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; |
Anythingconnected | 0:7dcd871d726b | 299 | case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; |
Anythingconnected | 0:7dcd871d726b | 300 | default: goto FilterFieldWidth; break; |
Anythingconnected | 0:7dcd871d726b | 301 | } |
Anythingconnected | 0:7dcd871d726b | 302 | } while (1); |
Anythingconnected | 0:7dcd871d726b | 303 | // |
Anythingconnected | 0:7dcd871d726b | 304 | // filter out field with |
Anythingconnected | 0:7dcd871d726b | 305 | // |
Anythingconnected | 0:7dcd871d726b | 306 | FilterFieldWidth: |
Anythingconnected | 0:7dcd871d726b | 307 | FieldWidth = 0; |
Anythingconnected | 0:7dcd871d726b | 308 | do { |
Anythingconnected | 0:7dcd871d726b | 309 | c = *sFormat; |
Anythingconnected | 0:7dcd871d726b | 310 | if (c < '0' || c > '9') { |
Anythingconnected | 0:7dcd871d726b | 311 | break; |
Anythingconnected | 0:7dcd871d726b | 312 | } |
Anythingconnected | 0:7dcd871d726b | 313 | sFormat++; |
Anythingconnected | 0:7dcd871d726b | 314 | FieldWidth = FieldWidth * 10 + (c - '0'); |
Anythingconnected | 0:7dcd871d726b | 315 | } while (1); |
Anythingconnected | 0:7dcd871d726b | 316 | |
Anythingconnected | 0:7dcd871d726b | 317 | // |
Anythingconnected | 0:7dcd871d726b | 318 | // Filter out precision (number of digits to display) |
Anythingconnected | 0:7dcd871d726b | 319 | // |
Anythingconnected | 0:7dcd871d726b | 320 | NumDigits = 0; |
Anythingconnected | 0:7dcd871d726b | 321 | c = *sFormat; |
Anythingconnected | 0:7dcd871d726b | 322 | if (c == '.') { |
Anythingconnected | 0:7dcd871d726b | 323 | sFormat++; |
Anythingconnected | 0:7dcd871d726b | 324 | do { |
Anythingconnected | 0:7dcd871d726b | 325 | c = *sFormat; |
Anythingconnected | 0:7dcd871d726b | 326 | if (c < '0' || c > '9') { |
Anythingconnected | 0:7dcd871d726b | 327 | break; |
Anythingconnected | 0:7dcd871d726b | 328 | } |
Anythingconnected | 0:7dcd871d726b | 329 | sFormat++; |
Anythingconnected | 0:7dcd871d726b | 330 | NumDigits = NumDigits * 10 + (c - '0'); |
Anythingconnected | 0:7dcd871d726b | 331 | } while (1); |
Anythingconnected | 0:7dcd871d726b | 332 | } |
Anythingconnected | 0:7dcd871d726b | 333 | // |
Anythingconnected | 0:7dcd871d726b | 334 | // Filter out length modifier |
Anythingconnected | 0:7dcd871d726b | 335 | // |
Anythingconnected | 0:7dcd871d726b | 336 | c = *sFormat; |
Anythingconnected | 0:7dcd871d726b | 337 | do { |
Anythingconnected | 0:7dcd871d726b | 338 | if (c == 'l' || c == 'h') { |
Anythingconnected | 0:7dcd871d726b | 339 | c = *sFormat++; |
Anythingconnected | 0:7dcd871d726b | 340 | continue; |
Anythingconnected | 0:7dcd871d726b | 341 | } |
Anythingconnected | 0:7dcd871d726b | 342 | break; |
Anythingconnected | 0:7dcd871d726b | 343 | } while (1); |
Anythingconnected | 0:7dcd871d726b | 344 | // |
Anythingconnected | 0:7dcd871d726b | 345 | // Handle specifiers |
Anythingconnected | 0:7dcd871d726b | 346 | // |
Anythingconnected | 0:7dcd871d726b | 347 | switch (c) { |
Anythingconnected | 0:7dcd871d726b | 348 | case 'c': { |
Anythingconnected | 0:7dcd871d726b | 349 | char c0; |
Anythingconnected | 0:7dcd871d726b | 350 | v = va_arg(*pParamList, int); |
Anythingconnected | 0:7dcd871d726b | 351 | c0 = (char)v; |
Anythingconnected | 0:7dcd871d726b | 352 | _StoreChar(&BufferDesc, c0); |
Anythingconnected | 0:7dcd871d726b | 353 | break; |
Anythingconnected | 0:7dcd871d726b | 354 | } |
Anythingconnected | 0:7dcd871d726b | 355 | case 'd': |
Anythingconnected | 0:7dcd871d726b | 356 | v = va_arg(*pParamList, int); |
Anythingconnected | 0:7dcd871d726b | 357 | _PrintInt(&BufferDesc, v, 10, NumDigits, FieldWidth, FormatFlags); |
Anythingconnected | 0:7dcd871d726b | 358 | break; |
Anythingconnected | 0:7dcd871d726b | 359 | case 'u': |
Anythingconnected | 0:7dcd871d726b | 360 | v = va_arg(*pParamList, int); |
Anythingconnected | 0:7dcd871d726b | 361 | _PrintUnsigned(&BufferDesc, v, 10, NumDigits, FieldWidth, FormatFlags); |
Anythingconnected | 0:7dcd871d726b | 362 | break; |
Anythingconnected | 0:7dcd871d726b | 363 | case 'x': |
Anythingconnected | 0:7dcd871d726b | 364 | case 'X': |
Anythingconnected | 0:7dcd871d726b | 365 | v = va_arg(*pParamList, int); |
Anythingconnected | 0:7dcd871d726b | 366 | _PrintUnsigned(&BufferDesc, v, 16, NumDigits, FieldWidth, FormatFlags); |
Anythingconnected | 0:7dcd871d726b | 367 | break; |
Anythingconnected | 0:7dcd871d726b | 368 | case 's': |
Anythingconnected | 0:7dcd871d726b | 369 | { |
Anythingconnected | 0:7dcd871d726b | 370 | const char * s = va_arg(*pParamList, const char *); |
Anythingconnected | 0:7dcd871d726b | 371 | do { |
Anythingconnected | 0:7dcd871d726b | 372 | c = *s++; |
Anythingconnected | 0:7dcd871d726b | 373 | if (c == 0) { |
Anythingconnected | 0:7dcd871d726b | 374 | break; |
Anythingconnected | 0:7dcd871d726b | 375 | } |
Anythingconnected | 0:7dcd871d726b | 376 | _StoreChar(&BufferDesc, c); |
Anythingconnected | 0:7dcd871d726b | 377 | } while (BufferDesc.ReturnValue >= 0); |
Anythingconnected | 0:7dcd871d726b | 378 | } |
Anythingconnected | 0:7dcd871d726b | 379 | break; |
Anythingconnected | 0:7dcd871d726b | 380 | case 'p': |
Anythingconnected | 0:7dcd871d726b | 381 | v = va_arg(*pParamList, int); |
Anythingconnected | 0:7dcd871d726b | 382 | _PrintUnsigned(&BufferDesc, v, 16, 8, 8, 0); |
Anythingconnected | 0:7dcd871d726b | 383 | break; |
Anythingconnected | 0:7dcd871d726b | 384 | case '%': |
Anythingconnected | 0:7dcd871d726b | 385 | _StoreChar(&BufferDesc, '%'); |
Anythingconnected | 0:7dcd871d726b | 386 | break; |
Anythingconnected | 0:7dcd871d726b | 387 | } |
Anythingconnected | 0:7dcd871d726b | 388 | sFormat++; |
Anythingconnected | 0:7dcd871d726b | 389 | } else { |
Anythingconnected | 0:7dcd871d726b | 390 | _StoreChar(&BufferDesc, c); |
Anythingconnected | 0:7dcd871d726b | 391 | } |
Anythingconnected | 0:7dcd871d726b | 392 | } while (BufferDesc.ReturnValue >= 0); |
Anythingconnected | 0:7dcd871d726b | 393 | |
Anythingconnected | 0:7dcd871d726b | 394 | if (BufferDesc.ReturnValue > 0) { |
Anythingconnected | 0:7dcd871d726b | 395 | // |
Anythingconnected | 0:7dcd871d726b | 396 | // Write remaining data, if any |
Anythingconnected | 0:7dcd871d726b | 397 | // |
Anythingconnected | 0:7dcd871d726b | 398 | if (BufferDesc.Cnt != 0) { |
Anythingconnected | 0:7dcd871d726b | 399 | SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); |
Anythingconnected | 0:7dcd871d726b | 400 | } |
Anythingconnected | 0:7dcd871d726b | 401 | BufferDesc.ReturnValue += BufferDesc.Cnt; |
Anythingconnected | 0:7dcd871d726b | 402 | } |
Anythingconnected | 0:7dcd871d726b | 403 | return BufferDesc.ReturnValue; |
Anythingconnected | 0:7dcd871d726b | 404 | } |
Anythingconnected | 0:7dcd871d726b | 405 | |
Anythingconnected | 0:7dcd871d726b | 406 | /********************************************************************* |
Anythingconnected | 0:7dcd871d726b | 407 | * |
Anythingconnected | 0:7dcd871d726b | 408 | * SEGGER_RTT_printf |
Anythingconnected | 0:7dcd871d726b | 409 | * |
Anythingconnected | 0:7dcd871d726b | 410 | * Function description |
Anythingconnected | 0:7dcd871d726b | 411 | * Stores a formatted string in SEGGER RTT control block. |
Anythingconnected | 0:7dcd871d726b | 412 | * This data is read by the host. |
Anythingconnected | 0:7dcd871d726b | 413 | * |
Anythingconnected | 0:7dcd871d726b | 414 | * Parameters |
Anythingconnected | 0:7dcd871d726b | 415 | * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") |
Anythingconnected | 0:7dcd871d726b | 416 | * sFormat Pointer to format string, followed by the arguments for conversion |
Anythingconnected | 0:7dcd871d726b | 417 | * |
Anythingconnected | 0:7dcd871d726b | 418 | * Return values |
Anythingconnected | 0:7dcd871d726b | 419 | * >= 0: Number of bytes which have been stored in the "Up"-buffer. |
Anythingconnected | 0:7dcd871d726b | 420 | * < 0: Error |
Anythingconnected | 0:7dcd871d726b | 421 | * |
Anythingconnected | 0:7dcd871d726b | 422 | * Notes |
Anythingconnected | 0:7dcd871d726b | 423 | * (1) Conversion specifications have following syntax: |
Anythingconnected | 0:7dcd871d726b | 424 | * %[flags][FieldWidth][.Precision]ConversionSpecifier |
Anythingconnected | 0:7dcd871d726b | 425 | * (2) Supported flags: |
Anythingconnected | 0:7dcd871d726b | 426 | * -: Left justify within the field width |
Anythingconnected | 0:7dcd871d726b | 427 | * +: Always print sign extension for signed conversions |
Anythingconnected | 0:7dcd871d726b | 428 | * 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision |
Anythingconnected | 0:7dcd871d726b | 429 | * Supported conversion specifiers: |
Anythingconnected | 0:7dcd871d726b | 430 | * c: Print the argument as one char |
Anythingconnected | 0:7dcd871d726b | 431 | * d: Print the argument as a signed integer |
Anythingconnected | 0:7dcd871d726b | 432 | * u: Print the argument as an unsigned integer |
Anythingconnected | 0:7dcd871d726b | 433 | * x: Print the argument as an hexadecimal integer |
Anythingconnected | 0:7dcd871d726b | 434 | * s: Print the string pointed to by the argument |
Anythingconnected | 0:7dcd871d726b | 435 | * p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) |
Anythingconnected | 0:7dcd871d726b | 436 | */ |
Anythingconnected | 0:7dcd871d726b | 437 | int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { |
Anythingconnected | 0:7dcd871d726b | 438 | va_list ParamList; |
Anythingconnected | 0:7dcd871d726b | 439 | |
Anythingconnected | 0:7dcd871d726b | 440 | va_start(ParamList, sFormat); |
Anythingconnected | 0:7dcd871d726b | 441 | return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); |
Anythingconnected | 0:7dcd871d726b | 442 | } |
Anythingconnected | 0:7dcd871d726b | 443 | /*************************** End of file ****************************/ |