PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : stdin stdout & Co über UART laufen lassen.



tobimc
20.07.2006, 13:06
Hi!

Wie ich so mit WinAVR spiele kommt mir die Idee, die UART-Ansteuerung etwas zu vereinfachen, und stdin und stdout dafür zu verwenden, sodass man den UART z.B. über printf(); ansprechen kann.

stdin, stdout und stderr werden bei WinAVR nicht genutzt.

Man müsste die Streams quasi auf eine eigene Funktion umleiten, die den UART ansteuert.

Problem: Die Funktion müsste sich Quasi wie eine Datei verhalten. Ich habe jetzt keine Idee, wie man das programmieren könnte.

Hat jemand ne Idee, weis jemand wie man das machen kann?

VLG Tobi

PicNick
20.07.2006, 14:01
Ich glaub', so geht's.


static int uart_putchar(char c, FILE *stream);

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

static int uart_putchar(char c, FILE *stream)
{
//while (!(UCSRA & (1<<UDRE))); //warten bis Senden moeglich
if (c == '\n')
{
uart_putchar('\r',&mystdout);
}
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
return 0;
}
.....................

printf ("Trilulliöö\n");

tobimc
21.07.2006, 09:13
Hi PicNick!

Das hört sich ja echt gut an!

Das Geheimnis mus irgendwo hier leigen:

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);


Wie läuft das denn?
{Oder hast du jetzt einen extra stream geschaffen, den man mit z.B. fprintf(); ansprechen müsste?}

Und wie geht das mit dem stdin?

VLG Tobi

PicNick
21.07.2006, 09:57
Au weia, das sind Fragen, da ist eher der SprinterSB zuständig.
Für ein I/O Gerät braucht C eine Kontrollstruktur (FILE), die sonst mit "open" oÄ angelegt wird. da steht im Grunde nur drinnen, wohin er springen muß, wenn er irgendwas lesen oder schreiben will.
Diese Strukturen sind einfach durchnummeriert. Die ersten paar haben eine sonderstellung, die sind immer da und heissen stdin, stdout, usw.
Beim PC ist das normalerweise automatisch Tastatur und Bildschirm, auf dem µC gibt's das ja nicht, also muß man die Vektoren für stdxxx definieren.

Ich rat' mal, "Stdin" geht im Prinzip genauso

Pascal
22.07.2006, 10:25
Meines Wissens nach ist dazu ein Beispiel in den Quellen zur MMC-Ansteuerung bei AVRs von Ulrich Radig. Das müsste gleich in der main-Routine sein.

SprinterSB
22.07.2006, 19:09
5.14.3.3

FILE* fdevopen (int(*put)(char), int(*get)(void), int opts __attribute__ ((unused)));
This function is a replacement for fopen().

It opens a stream for a device where the actual device implementation needs to be provided by the application. If successful, a pointer to the structure for the opened stream is returned. Reasons for a possible failure currently include that neither the put nor the get argument have been provided, thus attempting to open a stream with no IO intent at all, or that insufficient dynamic memory is available to establish a new stream.

If the put function pointer is provided, the stream is opened with write intent. The function passed as put shall take one character to write to the device as argument, and shall return 0 if the output was successful, and a nonzero value if the character could not be sent to the device.

If the get function pointer is provided, the stream is opened with read intent. The function passed as get shall take no arguments, and return one character from the device, passed as an int type. If an error occurs when trying to read from the device, it shall return -1.

If both functions are provided, the stream is opened with read and write intent. The first stream opened with read intent is assigned to stdin, and the first one opened with write intent is assigned to both, stdout and stderr.

Das ist so zu verstehen:
Argument von fdevopen ist eine Funktion, die nen char erhält und nen int liefert, also vom Prototyp int myput (char) ist:

int myput (char c) { ... }

FILE * pmyfile = fdevopen (myput, ...);
Argument analog
Argument ist ungenutzt

du bekommst dann nen Filepointer und kannst damit via fprintf (myfile, ...) Ausgaben machen. Mich dünkt aber, das ganze brauch malloc wies aussieht. Woher sollte sinst der Filepointer kommen... :-k
Oder wie PicNick geschrieben hat, dann hast du nen FILE und mit stdin = &myfile; geht's weiter oder pmyfile = &myfile; Wenn gas geht spart den malloc (irgendwo im Gedärm von libc, kann aber sein daß du dir den eh einfängst mit printf ("%lf"...

Ausserdem geht auch sowas: stin = stdout = myfile;
Vorausgesetzt, myfile implementiert Ein- und Ausgabe. (stdin ist einfach nur __iob[0])

SprinterSB
22.07.2006, 19:25
...natürlich stin = stdout = pmyfile; bzw stin = stdou = &myfile;