Risposta breve: Sì, è possibile eseguire entrambe le soluzioni.
La funzione printf è piuttosto complessa se si desidera supportare tutti i tipi di dati e formati. Ma non è così difficile scrivere qualcosa che possa produrre una stringa o un intero in poche basi diverse (la maggior parte delle persone ha bisogno solo di decimali ed esadecimali, ma l'ottale probabilmente aggiunge solo altre 3-4 linee di codice una volta che hai decimale e hex).
Tipicamente, printf è scritto così:
int printf(const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt)
ret = do_xprintf(outputfunc, NULL, fmt, args);
va_end(args);
return ret;
}
E poi il do_xprintf()
fa tutto il lavoro duro per tutte le varianti (printf, sprintf, fprintf, ecc)
int do_xprintf(void (*outputfunc)(void *extra, char c), void *extra, const char *fmt, va_list args)
{
char *ptr = fmt;
while(1)
{
char c = *ptr++;
if (c == '%')
{
c = *ptr++; // Get next character from format string.
switch(c)
{
case 's':
char *str = va_arg(args, const char *);
while(*str)
{
count++;
outputfunc(extra, *str);
str++;
}
break;
case 'x':
base = 16;
goto output_number;
case 'd':
base = 10;
output_number:
int i = va_arg(args, int);
// magical code to output 'i' in 'base'.
break;
default:
count++;
outputfunc(extra, c);
break;
}
else
count++;
outputfunc(extra, c);
}
return count;
}
Ora, tutto è necessario inserire alcuni bit del codice precedente e scrivere un outputfunc() che viene inviato alla porta seriale.
Si noti che questo è uno schizzo approssimativo, e sono sicuro che ci sono alcuni bug nel codice - e se si desidera supportare il punto mobile o "width", si dovrà lavorare un po 'di più su di esso ...
(Nota sul parametro in più - per l'uscita su un FILE *
che sarebbe la filepointer, per sprintf
, è possibile passare una struttura per il buffer e la posizione nel buffer, o qualcosa del genere)
Si è possibile - è possibile scrivere i propri routine di output, trovare un'implementazione piccola autonomo printf parziale(), o scrivere il supporto back-end necessario per attivare queste funzioni da un minimimal incorporato libc (probabilmente incluso nella tua toolchain) per funzionare sulla tua piattaforma. –
Grazie. Ho sentito dire che newlib come una libc incorporata funziona bene. Comunque cercherò un partial printf(). – Sam
@ChrisStratton: dipende in modo efficace dal sistema operativo. È possibile che le routine OS native _ siano_ la libreria standard. –