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 void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc,
unsigned v,
unsigned Base,
unsigned NumDigits,
unsigned FieldWidth,
unsigned FormatFlags) {
128 static const char _aV2C[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
141 while (Number >= Base) {
142 Number = (Number / Base);
145 if (NumDigits > Width) {
151 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
152 if (FieldWidth != 0u) {
153 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
158 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
160 _StoreChar(pBufferDesc, c);
161 if (pBufferDesc->ReturnValue < 0) {
167 if (pBufferDesc->ReturnValue >= 0) {
174 if (NumDigits > 1u) {
190 _StoreChar(pBufferDesc, _aV2C[Div]);
191 if (pBufferDesc->ReturnValue < 0) {
199 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
200 if (FieldWidth != 0u) {
201 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
203 _StoreChar(pBufferDesc,
' ');
204 if (pBufferDesc->ReturnValue < 0) {
217 static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc,
int v,
unsigned Base,
unsigned NumDigits,
unsigned FieldWidth,
unsigned FormatFlags) {
221 Number = (v < 0) ? -v : v;
227 while (Number >= (
int)Base) {
228 Number = (Number / (int)Base);
231 if (NumDigits > Width) {
234 if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
241 if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
242 if (FieldWidth != 0u) {
243 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
245 _StoreChar(pBufferDesc,
' ');
246 if (pBufferDesc->ReturnValue < 0) {
255 if (pBufferDesc->ReturnValue >= 0) {
258 _StoreChar(pBufferDesc,
'-');
259 }
else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
260 _StoreChar(pBufferDesc,
'+');
264 if (pBufferDesc->ReturnValue >= 0) {
268 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
269 if (FieldWidth != 0u) {
270 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
272 _StoreChar(pBufferDesc,
'0');
273 if (pBufferDesc->ReturnValue < 0) {
279 if (pBufferDesc->ReturnValue >= 0) {
283 _PrintUnsigned(pBufferDesc, (
unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
312 int SEGGER_RTT_vprintf(
unsigned BufferIndex,
const char * sFormat, va_list * pParamList) {
314 SEGGER_RTT_PRINTF_DESC BufferDesc;
317 unsigned FormatFlags;
319 char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
321 BufferDesc.pBuffer = acBuffer;
322 BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
324 BufferDesc.RTTBufferIndex = BufferIndex;
325 BufferDesc.ReturnValue = 0;
342 case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++;
break;
343 case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++;
break;
344 case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++;
break;
345 case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++;
break;
346 default: v = 0;
break;
355 if ((c <
'0') || (c >
'9')) {
359 FieldWidth = (FieldWidth * 10u) + ((
unsigned)c -
'0');
373 v = va_arg(*pParamList,
int);
374 NumDigits = (unsigned)v;
377 if ((c <
'0') || (c >
'9')) {
381 NumDigits = NumDigits * 10u + ((unsigned)c -
'0');
389 if ((c ==
'l') || (c ==
'h')) {
402 v = va_arg(*pParamList,
int);
404 _StoreChar(&BufferDesc, c0);
408 v = va_arg(*pParamList,
int);
409 _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
412 v = va_arg(*pParamList,
int);
413 _PrintUnsigned(&BufferDesc, (
unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
417 v = va_arg(*pParamList,
int);
418 _PrintUnsigned(&BufferDesc, (
unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
422 const char * s = va_arg(*pParamList,
const char *);
427 if (NumDigits == 0) {
431 _StoreChar(&BufferDesc, c);
432 }
while (BufferDesc.ReturnValue >= 0);
437 if (c ==
'\0' || NumDigits == 0) {
440 _StoreChar(&BufferDesc, c);
441 }
while (BufferDesc.ReturnValue >= 0);
446 v = va_arg(*pParamList,
int);
447 _PrintUnsigned(&BufferDesc, (
unsigned)v, 16u, 8u, 8u, 0u);
450 _StoreChar(&BufferDesc,
'%');
457 _StoreChar(&BufferDesc, c);
459 }
while (BufferDesc.ReturnValue >= 0);
461 if (BufferDesc.ReturnValue > 0) {
465 if (BufferDesc.Cnt != 0u) {
466 SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
468 BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
470 return BufferDesc.ReturnValue;
504 int SEGGER_RTT_printf(
unsigned BufferIndex,
const char * sFormat, ...) {
507 va_start(ParamList, sFormat);
508 return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);