123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- #include "SEGGER_RTT.h"
- #include "SEGGER_RTT_Conf.h"
- #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
- #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
- #endif
- #include <stdlib.h>
- #include <stdarg.h>
- #define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0)
- #define FORMAT_FLAG_PAD_ZERO (1u << 1)
- #define FORMAT_FLAG_PRINT_SIGN (1u << 2)
- #define FORMAT_FLAG_ALTERNATE (1u << 3)
- typedef struct {
- char* pBuffer;
- unsigned BufferSize;
- unsigned Cnt;
- int ReturnValue;
- unsigned RTTBufferIndex;
- } SEGGER_RTT_PRINTF_DESC;
- static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
- unsigned Cnt;
- Cnt = p->Cnt;
- if ((Cnt + 1u) <= p->BufferSize) {
- *(p->pBuffer + Cnt) = c;
- p->Cnt = Cnt + 1u;
- p->ReturnValue++;
- }
-
-
-
- if (p->Cnt == p->BufferSize) {
- if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
- p->ReturnValue = -1;
- } else {
- p->Cnt = 0u;
- }
- }
- }
- static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
- static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- unsigned Div;
- unsigned Digit;
- unsigned Number;
- unsigned Width;
- char c;
- Number = v;
- Digit = 1u;
-
-
-
- Width = 1u;
- while (Number >= Base) {
- Number = (Number / Base);
- Width++;
- }
- if (NumDigits > Width) {
- Width = NumDigits;
- }
-
-
-
- if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
- if (FieldWidth != 0u) {
- if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
- c = '0';
- } else {
- c = ' ';
- }
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, c);
- if (pBufferDesc->ReturnValue < 0) {
- break;
- }
- }
- }
- }
- if (pBufferDesc->ReturnValue >= 0) {
-
-
-
-
-
- while (1) {
- if (NumDigits > 1u) {
- NumDigits--;
- } else {
- Div = v / Digit;
- if (Div < Base) {
- break;
- }
- }
- Digit *= Base;
- }
-
-
-
- do {
- Div = v / Digit;
- v -= Div * Digit;
- _StoreChar(pBufferDesc, _aV2C[Div]);
- if (pBufferDesc->ReturnValue < 0) {
- break;
- }
- Digit /= Base;
- } while (Digit);
-
-
-
- if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
- if (FieldWidth != 0u) {
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, ' ');
- if (pBufferDesc->ReturnValue < 0) {
- break;
- }
- }
- }
- }
- }
- }
- static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
- unsigned Width;
- int Number;
- Number = (v < 0) ? -v : v;
-
-
-
- Width = 1u;
- while (Number >= (int)Base) {
- Number = (Number / (int)Base);
- Width++;
- }
- if (NumDigits > Width) {
- Width = NumDigits;
- }
- if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
- FieldWidth--;
- }
-
-
-
- if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
- if (FieldWidth != 0u) {
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, ' ');
- if (pBufferDesc->ReturnValue < 0) {
- break;
- }
- }
- }
- }
-
-
-
- if (pBufferDesc->ReturnValue >= 0) {
- if (v < 0) {
- v = -v;
- _StoreChar(pBufferDesc, '-');
- } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
- _StoreChar(pBufferDesc, '+');
- } else {
- }
- if (pBufferDesc->ReturnValue >= 0) {
-
-
-
- if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
- if (FieldWidth != 0u) {
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, '0');
- if (pBufferDesc->ReturnValue < 0) {
- break;
- }
- }
- }
- }
- if (pBufferDesc->ReturnValue >= 0) {
-
-
-
- _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
- }
- }
- }
- }
- int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
- char c;
- SEGGER_RTT_PRINTF_DESC BufferDesc;
- int v;
- unsigned NumDigits;
- unsigned FormatFlags;
- unsigned FieldWidth;
- char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
- BufferDesc.pBuffer = acBuffer;
- BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
- BufferDesc.Cnt = 0u;
- BufferDesc.RTTBufferIndex = BufferIndex;
- BufferDesc.ReturnValue = 0;
- do {
- c = *sFormat;
- sFormat++;
- if (c == 0u) {
- break;
- }
- if (c == '%') {
-
-
-
- FormatFlags = 0u;
- v = 1;
- do {
- c = *sFormat;
- switch (c) {
- case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
- case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
- case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
- case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
- default: v = 0; break;
- }
- } while (v);
-
-
-
- FieldWidth = 0u;
- do {
- c = *sFormat;
- if ((c < '0') || (c > '9')) {
- break;
- }
- sFormat++;
- FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
- } while (1);
-
-
-
- NumDigits = 0u;
- c = *sFormat;
- if (c == '.') {
- sFormat++;
- do {
- c = *sFormat;
- if ((c < '0') || (c > '9')) {
- break;
- }
- sFormat++;
- NumDigits = NumDigits * 10u + ((unsigned)c - '0');
- } while (1);
- }
-
-
-
- c = *sFormat;
- do {
- if ((c == 'l') || (c == 'h')) {
- sFormat++;
- c = *sFormat;
- } else {
- break;
- }
- } while (1);
-
-
-
- switch (c) {
- case 'c': {
- char c0;
- v = va_arg(*pParamList, int);
- c0 = (char)v;
- _StoreChar(&BufferDesc, c0);
- break;
- }
- case 'd':
- v = va_arg(*pParamList, int);
- _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
- break;
- case 'u':
- v = va_arg(*pParamList, int);
- _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
- break;
- case 'x':
- case 'X':
- v = va_arg(*pParamList, int);
- _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
- break;
- case 's':
- {
- const char * s = va_arg(*pParamList, const char *);
- do {
- c = *s;
- s++;
- if (c == '\0') {
- break;
- }
- _StoreChar(&BufferDesc, c);
- } while (BufferDesc.ReturnValue >= 0);
- }
- break;
- case 'p':
- v = va_arg(*pParamList, int);
- _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u);
- break;
- case '%':
- _StoreChar(&BufferDesc, '%');
- break;
- default:
- break;
- }
- sFormat++;
- } else {
- _StoreChar(&BufferDesc, c);
- }
- } while (BufferDesc.ReturnValue >= 0);
- if (BufferDesc.ReturnValue > 0) {
-
-
-
- if (BufferDesc.Cnt != 0u) {
- SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
- }
- BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
- }
- return BufferDesc.ReturnValue;
- }
- int SEGGER_RTT_printf(const char * sFormat, ...) {
- int r;
- va_list ParamList;
- va_start(ParamList, sFormat);
- r = SEGGER_RTT_vprintf(0, sFormat, &ParamList);
- va_end(ParamList);
- return r;
- }
|