2016-09-21 2 views
1

In Embedded-Programmierung, ich oft am Ende mit Code, der etwa wie folgt aussieht:Gibt es eine Möglichkeit, Formatspezifizierer-Zeichenfolgen in C inkrementell zu verarbeiten?

void debug_terminal_printf(const char* format, va_list ap){ 
    char tmp[ARBITRARY_LIMITATION]; 
    vsprintf(tmp, format, ap); 
    for(int pos=0; pos<strlen(tmp); pos++){ 
     if(tmp[pos] == 0) break; 
     uart_putc(tmp[pos]); 
    } 
} 

Ich mag meine Schnittstelle die Bequemlichkeit der String-Formate zur Verfügung zu stellen, aber in der Regel die Verbraucher von den formatierten String sind Dinge, die die verbrauchen Formatierte Strings einige Bytes gleichzeitig, wie in diesem Fall ein UART. Also habe ich diese kleinen temporären Puffer in jeder meiner Hilfsfunktionen. Die Verwendung von dynamischem Speicher ist nicht wirklich geeignet, da Entscheidungen über die Verwendung von dynamischem Speicher auf der Systemebene getroffen werden, und es wäre unangemessen, sie in eingebettetem Plattformcode zu verwenden.

Was ich möchte, ist in der Lage zu tun Prozess der String inkrementell, so etwas wie folgt aus:

void debug_terminal_printf(const char* format, va_list ap){ 
    char tmp[MAX_TOKEN_SIZE]; 
    while(*format){ 
     int len = single_token_sprintf(tmp, format, ap); 
     uart_puts(tmp); 
     format += len; 
    } 
} 

So kann ich nie genug Speicher für die gesamte formatierten String benötigen, kann ich bis zu diesem Hardware warten hat das letzte Token verbraucht, bevor es mit der Decodierung des nächsten Tokens fortfährt.

Hat jemals jemand ein (hoffentlich tragbares) Idiom wie dieses gesehen, das die Notwendigkeit eines großen temporären Puffers beseitigt?

+0

ich diesen Kommentar nach zu bemerken Ihrer Bemerkung über die Laufzeit gelöscht. Aber sind Sie so im Stapelspeicher, dass Sie keinen lokalen Puffer verwenden können? –

+2

Oft kann serieller Zugriff durch 'fopen()' auch in eingebetteten, 'fprintf()' eine Option behandelt werden? – chux

+1

Ich glaube nicht, dass es eine Möglichkeit gibt, dies portabel zu machen. Sie brauchen eine Möglichkeit, sich in die Ausgabepufferung von 'stdio' Streams einzuklinken. – Barmar

Antwort

0

Vielen Dank an @chux für die Führung in die richtige Richtung.

Die Antwort ist, dass die Implementierung von putc() in der Laufzeitumgebung gehakt werden kann, so dass ich beim Aufruf von fprintf die resultierenden Strings Byte für Byte konsumieren kann. Das ist ziemlich nicht tragbar. Für jede Umgebung wird der genaue Weg dies zu erreichen anders sein.

In meinem Fall (Cortex M auf Keil), werden die Anweisungen von Keil hier zur Verfügung gestellt: http://www.keil.com/support/man/docs/gsac/gsac_retargetcortex.htm

Verwandte Themen