Forum: Mikrocontroller und Digitale Elektronik fprintf auf STM32


von Jan B. (diphthong)


Lesenswert?

Hallo an alle,
ich würde gerne die standard C Ausgabefunktionen (printf etc.) auf einem 
STM32F4 Discovery Board nutzen. Soweit funktioniert das auch schon, in 
der _write Funktion kommen die Daten an, die über stdout und stderr 
gesendet werden. Nun möchte ich die printf Funktion aber auch z.B. für 
ein LCD nutzen - also verschiedene Streams. Dafür bietet sich dann ja 
die fprintf Funktion an - der ich eben eigene Streams übergeben kann. 
Wenn ich nun einen Stream deklariere über

__FILE lcdStream;

und über

fprintf(&lcdStream, "TEST\n");

etwas sende, läuft das Programm normal weiter, allerdings wird nicht in 
die _write Funktion gesprungen. Wie kann ich also die Funktion 
festlegen, die aufgerufen wird, wenn ich an einen bestimmten Stream per 
fprintf sende?

Grüße
Jan

von Jim M. (turboj)


Lesenswert?

Wieso arbeitest Du nicht einfach mit snprintf() und entsprechenden (z.B. 
statischen) char[] Arrays?

von LCD (Gast)


Lesenswert?

Jan, wie garantierst du, dass sich das LCD wie eine Stream verhält? Kann 
das die Library zu dem LCD?

von Jan B. (diphthong)


Lesenswert?

Jim Meba schrieb:
> Wieso arbeitest Du nicht einfach mit snprintf() und entsprechenden
> (z.B.
> statischen) char[] Arrays?

Das wäre eine Möglichkeit, anders fände ich das aber schöner.

LCD schrieb:
> Jan, wie garantierst du, dass sich das LCD wie eine Stream
> verhält? Kann
> das die Library zu dem LCD?

Das würde ich dann noch in den Funktionen implementieren, die aufgerufen 
werden, wenn fprintf die Eingabe verarbeitet hat.

Eigentlich muss ich wirklich nur wissen, ob es überhaupt möglich ist, 
eine Funktion zu deklarieren und die einem bestimmten Stream zuzuteilen, 
damit dann, wenn fprintf mit dem entsprechenden Stream aufgerufen wurde, 
die zugehörige, deklarierte Funktion von fprintf aufgerufen wird, der 
dann der verarbeitete String übergeben wird. Dass das möglich ist, habe 
ich jetzt daraus geschlossen, dass es ja eine _write Funktion gibt, in 
der ich den Ausgabestring z.B. ans USART weitergeben kann - die wird 
aber nur für stdout und stderr aufgerufen.
Außerdem gibt es in der __FILE bzw. in der _IO_FILE Datenstruktur in 
libio.h ja dieses Element:

char* _IO_write_ptr;  /* Current put pointer. */

Aber da kann ich ja keine Funktion übergeben, oder?

Ich hoffe, die Problematik wurde etwas klar.
Grüße
Jan

von Ch. K. (Gast)


Lesenswert?

bin mir nicht ganz sicher, ob ich dich richtig verstehe. aber kommt es 
darauf an, wie die standard lib realisiert wurde, die du nutzt. ich 
kenne das jetzt nur von KEIL konkret.  die haben die standard lib so 
verwirklicht, dass man ein extra retarget file mitgeben kann. darin sind 
dann die zuordnungen fuer die ausgaben implementiert, welche dann die 
standard streams ersetzen. google also mal nach "retarget.c+keil". 
fazit: es hängt stark von deinem lib hersteller ab, wie das zu 
bewerkstelligen ist. daher gibts keinen besseren rat als den verweis auf 
deren doku. vielleicht ist es ja ähnlich zu der art und weise wie es 
keil macht.

lg

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Jan B. schrieb:
> Eigentlich muss ich wirklich nur wissen, ob es überhaupt möglich ist,
> eine Funktion zu deklarieren und die einem bestimmten Stream zuzuteilen,
> damit dann, wenn fprintf mit dem entsprechenden Stream aufgerufen wurde,
> die zugehörige, deklarierte Funktion von fprintf aufgerufen wird, der
> dann der verarbeitete String übergeben wird. Dass das möglich ist, habe
> ich jetzt daraus geschlossen, dass es ja eine _write Funktion gibt, in
> der ich den Ausgabestring z.B. ans USART weitergeben kann - die wird
> aber nur für stdout und stderr aufgerufen.

Dann gib stdout an den USART, stderr ans Display weiter, z.B. so:
1
int _write(int file, char *ptr, int len)
2
{
3
    int n;
4
    switch (file)
5
    {
6
        case STDOUT_FILENO: /*stdout*/
7
            for (n = 0; n < len; n++)
8
            {
9
                Deine_ZeichenausgabeFunktion_an_USART(*ptr++);
10
            }
11
            break;
12
        case STDERR_FILENO: /* stderr */
13
            for (n = 0; n < len; n++)
14
            {
15
                Deine_ZeichenausgabeFunktion_an_DISPLAY(*ptr++);
16
            }
17
            break;
18
        default:
19
            errno = EBADF;
20
            return -1;
21
        }
22
    return len;
23
}

Leider weiß ich auch nicht, wie ich mehr als nur die beiden 
stdout/stderr-Kanäle verwenden kann. Ich spiele mit STM32 erst seit dem 
Wochenende.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.