Modyfikowanie wskaźników, gdzie popełniam błędy?

0

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

0

a po cholere Ci specjalna wersja sprintf na uC skoro bedzie identyczna jak ta z biblioteki standardowej?

0
krwq napisał(a):

a po cholere Ci specjalna wersja sprintf na uC skoro bedzie identyczna jak ta z biblioteki standardowej?

Otóż nie będzie. 512B to naprawdę mało pamięci RAM ;-) Wersja z biblioteki standardowej, standardowo nadpisuje stos....

1 użytkowników online, w tym zalogowanych: 0, gości: 1