Hallo,
ich versuche gerade eine Lüftersteuerung zu schreiben, die per Telnet
den aktuellen Zustand(Temperatur/Lüfterdrehzahl) ausgibt und
Einstellungen für die Regelung entgegennimmt.
Zur Ausgabe der Daten möchte ich per UART einfach Zeilenweise den Text
senden. Da ich auch Zahlenwerte aus Variablen mitsenden möchte, habe ich
mich für sprintf() entschieden.
Die Ausgabe läuft so ab:
char text[80];
//uart_putc(12);//FormFeed. Clearen des Terminals
sprintf(text,"\n\rWakue-Steuerung Version 0.91\n\r\n\r");
uart_putstring(text);
sprintf(text,"Temperaturen:\n\r");
uart_putstring(text);
Das Uart ist Interruptbasierend und ich hab die Funktionen von
Roboternetz
(http://www.roboternetz.de/wissen/index.php/UART_mit_avr-gcc#Mit_Interrupts).
Dahinter steht ein FIFO Buffer, in den die zu sendene Zeichenkette
geschoben wird und dann nach und nach gesendet wird.
Ich habe nur kommischerweise sehr Merkwürdiges Verhalten. Einige Teile
werden problemlos ausgegeben, aber manchmal kommt nur Müll. Es ist auch
teilweise so, dass der erste Teil wunderbar am Terminal ankommt und 2
Zeilen später ist die Formatierung hin(teilweise mit Zeichen, die nicht
da sein sollten)
Ich kann dabei aber kein Muster erkennen.
Z.B. erzeugt
sprintf(text,"Drehzahlregelung\n\r");
uart_putstring(text);
sprintf(text,"Bottom: 30C = 50p \n\rUpper: 60C = 100p\n\r");
im moment gerade
"Botto00p00Wakue-Steuerung Version 0.91) pDrae"
und andere Zeilen produzieren keinen output.
Bin ich vielleicht auf dem flaschen Weg? Gibts eine andere, einfachere
Lösung? Oder sollte ich das Uart nicht Interruptgesteuert machen?
Danke schonmal für jeden Tipp, denn mir gehen langsam die Ideen aus.
Christian
Ich habe die UART-Routinen nur überflogen, aber kann es sein, dass der
FIFO zu klein ist? Soll heissen, kann es sein, dass du schneller Texte
in den Buffer schreibst als gesendet werden können?
Ich würde zum Testen mal vor jedem 'uart_putstring(text)' eine
Warteschleife einbauen.
sehr guter Tipp ...
ich hab mal die Bufferlänge hochgesetzt und sieheda: die Fehler
verschwinden. Nur muss ich jetzt meine uart routine umändern, denn ich
kann ja nicht die Bufferlänge auf 300 bis 400 byte setzen.
Damit blockiere ich doch dann den ganzen Ram,oder sehe ich das falsch?
vielen Dank
Christian
Ich schätze mal, dein 'uart_putstring()' ist die 'uart_puts()' aus den
UART-Routinen. In dieser wird 'uart_putc' verwendet, um die einzelnen
Zeichen des Strings in den FIFO zu schreiben. 'uart_putc' gibt einen
wert zurück, der angibt, ob das Zeichen in den FIFO geschrieben wurde
oder ob der Puffer voll ist (steht so im Text). Dieser Wert wird aber
nicht ausgewertet. Das funktioniert so nur mit kurzen Texten.
Wenn du genügend RAM hast, würde ich den Puffer schrittweise
vergrössern, bis es passt. 300 Byte weden wohl nicht gebraucht, denke
ich. Ich tippe mal so auf 60 Byte.
Alternativ kannst du natürlich den Return-Wert von 'uart_putc' auswerten
und immer warten, bis der FIFO wieder frei ist.
CB
Ja, meine uart_putstrin() ist die uart_puts() ich fand, dass muss man
zur besseren Kennzeichnung umbennenen.
Ich hab mich durch die Funktionen gekwühlt und hab das ganze anders
gelöst.
ich hab die uart_putc() um folgendes erweitert
fifo_t *fn = &outfifo;
while(fn->count >= fn->size){;};
also die Abbruchbedingung aus dem Fifo verwendet.
so wartet er nun, wenn der Buffer voll ist. Ich denke, so ist es am
einfachsten, da ich mir keine Gedanken über die Auswertung machen muss.
Ich würd es ja auch im RN angeben, doch irgendwie hab ich keine Lust
mich da jetzt erst groß anzumelden.
Aber dir erstmal vielen Dank
hast mein Wochenende gerettet :)
Christian
> hast mein Wochenende gerettet :)
bitte bitte...
Ich hätte dass vielleicht so gemacht:
Die Zeile
int ret = fifo_put (&outfifo, c);
in 'uart_putc' ersetzt durch
int ret;
do
{
ret = fifo_put (&outfifo, c);
}
while (ret=0);
Sollte doch auch gehen, oder? Aber wenn deine Lösung funktioniert...
BC
also zu aller erst, ich will nicht besserwisserisch sein, nur zum
Verständniss, aber ich glaube nicht,
denn es wird immer zuerst einmal versucht das Zeichen in den Buffer zu
schieben. Schlägt das fehl, ist das Zeichen verlohren.
Es geht gut, bis einmal -1 zurückgeliefert wird.
dann bricht die Schleife ab, und das Zeichen wird verworfen, oder?
Also verhindert die Schleife zwar effektiv den Überlauf des Puffers,
doch die Ausgabe wird dennoch verfälscht.
Oder liege ich da gerade daneben?
Christian
Es wird versucht, ein Zeichen in den FIFO zu schreiben
ret = fifo_put (&outfifo, c);
Wenn ret 0 ist, war der FIFO voll und es wird weiter versucht, bis ret
nicht mehr 0 ist
while (ret=0);
ret wird 1, wenn das Zeichen im FIFO ist. Warum sollte das Zeichen
verloren gehen? Ich denke nicht, das die Routine fifo_put das Zeichen
('c') ändert (weiss ich allerdings nicht, da ich fifo.h nicht kenne)
CB
Ein Returnwert beim Senden ist Blödsinn, wer soll den denn auswerten ?
Eine Sende-FIFO muß einfach immer solange warten, bis wieder Platz im
Puffer ist. Nur so geht nichts verloren.
Eine andere Möglichkeit wäre noch eine Funktion, die die aktuelle freie
Pufferlänge zurückgibt.
Dann kann man mit der Ausgabe solange warten, bis auch genügend Platz
ist und die Zwischenzeit anderweitig nutzen.
Trotzdem sollte die Sendefunktion warten, falls man sich mal mit der
benötigten Paketlänge verschätzt hat.
Lieber die Daten etwas später senden, als total falsch.
Peter
> Eine Sende-FIFO muß einfach immer solange warten, bis wieder Platz im> Puffer ist. Nur so geht nichts verloren.
Ja, aber genau dieses warten ist anscheinend nicht implementiert, was
ich mit meinem Vorschlag nachholen wollte. Oder übersehe ich da
irgendetwas?
Nabend
ich glaub ich lag falsch.
Ich bin davon ausgegangen, dass -1 zurückgeleifert wird, wenn die
Funktion nicht erfolgreich war, deshalb hats keinen Sinn für mich
gemacht.
Hast also Recht.
Habs aber so implementiert, wie oben und es läuft soweit.
Wünsch euch noch ne gute Nacht und danke :)
Christian