44 #include "segger-rtt.h" 45 #include "segger-rtt-conf.h" 54 #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE 55 #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) 62 #define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) 63 #define FORMAT_FLAG_PAD_ZERO (1u << 1) 64 #define FORMAT_FLAG_PRINT_SIGN (1u << 2) 65 #define FORMAT_FLAG_ALTERNATE (1u << 3) 81 unsigned RTTBufferIndex;
82 } SEGGER_RTT_PRINTF_DESC;
90 int SEGGER_RTT_vprintf(
unsigned BufferIndex,
const char * sFormat, va_list * pParamList);
102 static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p,
char c) {
106 if ((Cnt + 1u) <= p->BufferSize) {
107 *(p->pBuffer + Cnt) = c;
114 if (p->Cnt == p->BufferSize) {
115 if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
127 static inline void _PrintChars(SEGGER_RTT_PRINTF_DESC * pBufferDesc,
const char * s,
unsigned Base,
unsigned NumDigits,
unsigned FieldWidth,
unsigned FormatFlags) {
147 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
148 if (FieldWidth != 0u) {
149 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
154 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
156 _StoreChar(pBufferDesc, c);
157 if (pBufferDesc->ReturnValue < 0) {
171 if (NumDigits == 0) {
175 _StoreChar(pBufferDesc, c);
176 }
while (pBufferDesc->ReturnValue >= 0);
184 _StoreChar(pBufferDesc, c);
185 }
while (pBufferDesc->ReturnValue >= 0);
191 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
192 if (FieldWidth != 0u) {
193 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
195 _StoreChar(pBufferDesc,
' ');
196 if (pBufferDesc->ReturnValue < 0) {
210 static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc,
unsigned v,
unsigned Base,
unsigned NumDigits,
unsigned FieldWidth,
unsigned FormatFlags) {
211 static const char _aV2C[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
224 while (Number >= Base) {
225 Number = (Number / Base);
231 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
232 if (FieldWidth != 0u) {
233 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
238 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
240 _StoreChar(pBufferDesc, c);
241 if (pBufferDesc->ReturnValue < 0) {
247 if (pBufferDesc->ReturnValue >= 0) {
254 if (NumDigits > 1u) {
270 _StoreChar(pBufferDesc, _aV2C[Div]);
271 if (pBufferDesc->ReturnValue < 0) {
279 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
280 if (FieldWidth != 0u) {
281 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
283 _StoreChar(pBufferDesc,
' ');
284 if (pBufferDesc->ReturnValue < 0) {
297 static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc,
int v,
unsigned Base,
unsigned NumDigits,
unsigned FieldWidth,
unsigned FormatFlags) {
301 Number = (v < 0) ? -v : v;
307 while (Number >= (
int)Base) {
308 Number = (Number / (int)Base);
311 if (NumDigits > Width) {
314 if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
321 if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
322 if (FieldWidth != 0u) {
323 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
325 _StoreChar(pBufferDesc,
' ');
326 if (pBufferDesc->ReturnValue < 0) {
335 if (pBufferDesc->ReturnValue >= 0) {
338 _StoreChar(pBufferDesc,
'-');
339 }
else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
340 _StoreChar(pBufferDesc,
'+');
344 if (pBufferDesc->ReturnValue >= 0) {
348 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
349 if (FieldWidth != 0u) {
350 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
352 _StoreChar(pBufferDesc,
'0');
353 if (pBufferDesc->ReturnValue < 0) {
359 if (pBufferDesc->ReturnValue >= 0) {
363 _PrintUnsigned(pBufferDesc, (
unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
392 int SEGGER_RTT_vprintf(
unsigned BufferIndex,
const char * sFormat, va_list * pParamList) {
394 SEGGER_RTT_PRINTF_DESC BufferDesc;
398 unsigned FormatFlags;
400 char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
402 BufferDesc.pBuffer = acBuffer;
403 BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
405 BufferDesc.RTTBufferIndex = BufferIndex;
406 BufferDesc.ReturnValue = 0;
423 case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++;
break;
424 case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++;
break;
425 case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++;
break;
426 case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++;
break;
427 default: v = 0;
break;
436 if ((c <
'0') || (c >
'9')) {
440 FieldWidth = (FieldWidth * 10u) + ((
unsigned)c -
'0');
454 v = va_arg(*pParamList,
int);
455 NumDigits = (unsigned)v;
458 if ((c <
'0') || (c >
'9')) {
462 NumDigits = NumDigits * 10u + ((unsigned)c -
'0');
470 if ((c ==
'l') || (c ==
'h')) {
484 v = va_arg(*pParamList,
int);
486 _StoreChar(&BufferDesc, c0);
490 v = va_arg(*pParamList,
int);
491 _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
494 v = va_arg(*pParamList,
int);
495 _PrintUnsigned(&BufferDesc, (
unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
499 v = va_arg(*pParamList,
int);
500 _PrintUnsigned(&BufferDesc, (
unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
503 s = va_arg(*pParamList,
const char *);
504 _PrintChars(&BufferDesc, (
const char *)s, 10u, NumDigits, FieldWidth, FormatFlags);
507 v = va_arg(*pParamList,
int);
508 _PrintUnsigned(&BufferDesc, (
unsigned)v, 16u, 8u, 8u, 0u);
511 _StoreChar(&BufferDesc,
'%');
518 _StoreChar(&BufferDesc, c);
520 }
while (BufferDesc.ReturnValue >= 0);
522 if (BufferDesc.ReturnValue > 0) {
526 if (BufferDesc.Cnt != 0u) {
527 SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
529 BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
531 return BufferDesc.ReturnValue;
565 int SEGGER_RTT_printf(
unsigned BufferIndex,
const char * sFormat, ...) {
568 va_start(ParamList, sFormat);
569 return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);