Witam,
Piszę kod na mikrokontroler o bardzo małej ilości pamięci RAM (512B), znalazłem w sieci funkcję printf, która wypisuje wynik na UART.
Chciałbym ją przerobić tak, aby pisała do wcześniej zdefiniowanej tablicy, tak jak sprintf.
Funkcję (na razie najprostszy możliwy scenariusz) wołam tak:
char string[60];
usprintf(string, "%c",'x');
A sam kod funkcji jest taki:
void usprintf(char* str, char* format, ...)
{
char c;
int i;
long n;
va_list a;
va_start(a, format);
while (c = *format++)
{
if (c == '%')
{
switch (c = *format++)
{
case 's': // String
//usputs(str, va_arg(a, char*));
break;
case 'c': // Char
usputc(&str, va_arg(a, char));
break;
case 'i': // 16 bit Integer
case 'u': // 16 bit Unsigned
i = va_arg(a, int);
if (c == 'i' && i < 0)
i = -i, usputc(&str, '-');
usxtoa((unsigned) i, dv + 5);
break;
case 'l': // 32 bit Long
case 'n': // 32 bit uNsigned loNg
n = va_arg(a, long);
if (c == 'l' && n < 0)
n = -n, usputc(&str, '-');
xtoa((unsigned long) n, dv);
break;
case 'x': // 16 bit heXadecimal
i = va_arg(a, int);
puth(i >> 12);
puth(i >> 8);
puth(i >> 4);
puth(i);
break;
case 0:
return;
default:
goto bad_fmt;
}
}
else
bad_fmt: usputc(&str, c);
}
*str++ = '\0';
va_end(a);
}
void usputc(char** target_str, unsigned char c)
{
printf("usputc, adress str: %u\n\r",**target_str);
**target_str++;
}
static void usxtoa(char* str, unsigned long x, const unsigned long *dp)
{
char c;
unsigned long d;
if (x)
{
while (x < *dp)
++dp;
do
{
d = *dp++;
c = '0';
while (x >= d)
++c, x -= d;
usputc(&str, c);
} while (!(d & 1));
}
else
usputc(&str, '0');
}
Przekazuję do funkcji usprintf wskaźnik do początku tablicy. Funkcja usprintf wywołuje funkcję usputc (mógłbym zrezygnować z wołania funkcji tylko przenieść ciało usputc w miejsca wywołania, jednak i tak dla integerów funkcja woła xtoa, więc problem z przekazywaniem wskaźniików jest aktualny) i wydaje mi się, że od momentu wywołania usprintf, wszelkie wywołane przez nią funkcję muszą modyfikować wskaźnik
do str, aby móc go fizycznie przesuwać.
Brakuje mi doświadczenia w pracy ze wskaźnikami, muszę poćwiczyć, jednak byłbym wdzięczny za pomoc w znalezieniu przyczyny, dla której powyższy kod nie działa. W praktyce zatrzymuje się w "case 'c'", a debugger nie potrafi wejść do funkcji usputc - tu wciąż kombinuję.
Pozdrawiam,
Tomek