60 #include "SEGGER_RTT.h" 61 #include "SEGGER_RTT_Conf.h" 70 #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE 71 #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) 78 #define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) 79 #define FORMAT_FLAG_PAD_ZERO (1u << 1) 80 #define FORMAT_FLAG_PRINT_SIGN (1u << 2) 81 #define FORMAT_FLAG_ALTERNATE (1u << 3) 97 unsigned RTTBufferIndex;
98 } SEGGER_RTT_PRINTF_DESC;
106 int SEGGER_RTT_vprintf(
unsigned BufferIndex,
const char * sFormat, va_list * pParamList);
118 static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p,
char c) {
122 if ((Cnt + 1u) <= p->BufferSize) {
123 *(p->pBuffer + Cnt) = c;
130 if (p->Cnt == p->BufferSize) {
131 if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
143 static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc,
unsigned v,
unsigned Base,
unsigned NumDigits,
unsigned FieldWidth,
unsigned FormatFlags) {
144 static const char _aV2C[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
157 while (Number >= Base) {
158 Number = (Number / Base);
161 if (NumDigits > Width) {
167 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
168 if (FieldWidth != 0u) {
169 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
174 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
176 _StoreChar(pBufferDesc, c);
177 if (pBufferDesc->ReturnValue < 0) {
183 if (pBufferDesc->ReturnValue >= 0) {
190 if (NumDigits > 1u) {
206 _StoreChar(pBufferDesc, _aV2C[Div]);
207 if (pBufferDesc->ReturnValue < 0) {
215 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
216 if (FieldWidth != 0u) {
217 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
219 _StoreChar(pBufferDesc,
' ');
220 if (pBufferDesc->ReturnValue < 0) {
233 static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc,
int v,
unsigned Base,
unsigned NumDigits,
unsigned FieldWidth,
unsigned FormatFlags) {
237 Number = (v < 0) ? -v : v;
243 while (Number >= (
int)Base) {
244 Number = (Number / (int)Base);
247 if (NumDigits > Width) {
250 if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
257 if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
258 if (FieldWidth != 0u) {
259 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
261 _StoreChar(pBufferDesc,
' ');
262 if (pBufferDesc->ReturnValue < 0) {
271 if (pBufferDesc->ReturnValue >= 0) {
274 _StoreChar(pBufferDesc,
'-');
275 }
else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
276 _StoreChar(pBufferDesc,
'+');
280 if (pBufferDesc->ReturnValue >= 0) {
284 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
285 if (FieldWidth != 0u) {
286 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
288 _StoreChar(pBufferDesc,
'0');
289 if (pBufferDesc->ReturnValue < 0) {
295 if (pBufferDesc->ReturnValue >= 0) {
299 _PrintUnsigned(pBufferDesc, (
unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
328 int SEGGER_RTT_vprintf(
unsigned BufferIndex,
const char * sFormat, va_list * pParamList) {
330 SEGGER_RTT_PRINTF_DESC BufferDesc;
333 unsigned FormatFlags;
335 char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
337 BufferDesc.pBuffer = acBuffer;
338 BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
340 BufferDesc.RTTBufferIndex = BufferIndex;
341 BufferDesc.ReturnValue = 0;
358 case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++;
break;
359 case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++;
break;
360 case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++;
break;
361 case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++;
break;
362 default: v = 0;
break;
371 if ((c <
'0') || (c >
'9')) {
375 FieldWidth = (FieldWidth * 10u) + ((
unsigned)c -
'0');
387 if ((c <
'0') || (c >
'9')) {
391 NumDigits = NumDigits * 10u + ((unsigned)c -
'0');
399 if ((c ==
'l') || (c ==
'h')) {
412 v = va_arg(*pParamList,
int);
414 _StoreChar(&BufferDesc, c0);
418 v = va_arg(*pParamList,
int);
419 _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
422 v = va_arg(*pParamList,
int);
423 _PrintUnsigned(&BufferDesc, (
unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
427 v = va_arg(*pParamList,
int);
428 _PrintUnsigned(&BufferDesc, (
unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
432 const char * s = va_arg(*pParamList,
const char *);
439 _StoreChar(&BufferDesc, c);
440 }
while (BufferDesc.ReturnValue >= 0);
444 v = va_arg(*pParamList,
int);
445 _PrintUnsigned(&BufferDesc, (
unsigned)v, 16u, 8u, 8u, 0u);
448 _StoreChar(&BufferDesc,
'%');
455 _StoreChar(&BufferDesc, c);
457 }
while (BufferDesc.ReturnValue >= 0);
459 if (BufferDesc.ReturnValue > 0) {
463 if (BufferDesc.Cnt != 0u) {
464 SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
466 BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
468 return BufferDesc.ReturnValue;
502 int SEGGER_RTT_printf(
unsigned BufferIndex,
const char * sFormat, ...) {
506 va_start(ParamList, sFormat);
507 r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);