Forum: Mikrocontroller und Digitale Elektronik UART Software Flow Control Befehle werden ignoriert


von Torsten W. (torsten_w)


Angehängte Dateien:

Lesenswert?

Hi,

ich arbeite momentan an einem CAN-Bootloader, bei dem ich momentan an 
einem Problem mit der seriellen Verbindung hänge.
Ich verwende einen atmega168 in Kombination mit einem MCP2515 um die 
Daten auf den CAN-Bus zu schreiben. Der atmega nimmt dabei die Daten 
über UART vom PC entgegen und legt sie momentan noch byte-weise auf den 
Bus, wo sie ein anderer atmega32 empfängt und dann später als Bootloader 
in seinen Flash schreiben soll.
Das übertragen funktioniert momentan auch problemlos. Ich hab den 
atmega32 testweise seine empfangenen Daten über UART ausgeben lassen und 
es treten keine Fehler auf. Als Testdaten benutze ich ein .hex file, da 
dieses ja auch später übertragen werden soll.
Für das spätere Übertragen möchte ich immer 8 byte über UART vom PC 
einlesen und diese über den CAN-Bus weiter reichen und eine Bestätigung 
des Empfängers auf dem CAN-Bus abwarten. Um einen Buffer Overlow beim 
Empfänger der Daten über UART zu vermeiden möchte ich diesen mittels 
Software Flow Control über das Zeichen 0x13 stoppen und nach der 
Bestätigung mit 0x11 fortsetzen.
Um das ganze erstmal so zu testen möchte ich die über UART empfangenen 
Daten direkt wieder über UART an den PC zurücksenden. Ich benutze in 
beide Richtungen einen Buffer.
Mein eigentliches Problem ist jetzt jedoch, dass trotz des XOFF Bytes 
immer noch weiter gesendet wird. Zum senden verwende ich am PC (linux) 
das Programm Minicom mit eingeschaltetem Software Flow Control.
Ich kann mir leider nicht erklären warum das geschieht. Es werden keine 
Binärdaten übertragen, wo XON enthalten sein könnte, da ich minicom 
extra auf ASCII eingestellt hab.
Ich hab das ganze auch mittels
1
stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb ixon ixoff
und
1
cat output.hex > /dev/ttyUSB0
Probiert. Leider bei beiden das selbe Ergebniss, der Empfangspuffer 
läuft nach kürzester Zeit über, da der Sendepuffer wohl nicht mit dem 
schreiben nach kommt.

Da ich mich nicht als Profi der Materie bezeichnen würde, kann ich 
leider auch nicht ausschließen, dass es vielleicht auch ein 
grundlegender Fehler ist. Ich hab meinen Code mal in den Anhang gepackt. 
Dabei handelt es sich um das eigentliche Programm zum Empfangen (Main.c) 
und die Implementierung der UART Kommunikation (UART.*).

Ich bin Softwaretechnisch auch für andere Vorschläge offen, wie ich die 
Daten vom Computer per UART an den atmega geschickt bekomme. Die 
Software sollte nur unter Linux verfügbar sein.

Als letztes vielleicht noch kurz zur Hardware. Da mein PC keine 
seriellen Anschlüsse hat verwende ich ein mySmartUSB bei einer Baudrate 
von 9600. Da die Kommunikation bei nicht zeitkritischen Sachen 
fehlerfrei funktioniert, sollte das glaub ich als Fehlerquelle 
auszuschließen sein.

Gruß,
toti

von Jobst M. (jobstens-de)


Lesenswert?

Hört der Sender (PC) gar nicht auf zu senden oder hört er erst auf, wenn 
der Buffer schon übergelaufen ist?

Ansonsten lege ich bei solchen Geräten die Baudrate immer so, daß ich 
die Daten mit Sicherheit verarbeiten kann.


Gruß

Jobst

von Torsten W. (torsten_w)


Lesenswert?

Hi,

das senden endet gar nicht. Der buffer läuft über und sobald wieder 
etwas frei ist im buffer läd er wieder rein und läuft danach wieder 
über. Das XOFF wird also nicht zu spät erkannt sondern scheinbar gar 
nicht.
Das mit der Baudrate wäre natürlich eine Möglichkeit aber ich würde dem 
Problem gerne auf den grund gehen. Das ganze muss ja am ende auf den 
can-bus geschrieben werden und dann in den Flash geschrieben werden und 
wenn ich dabei den datenfluss kontrollieren kann wäre das wohl schon 
besser.

Gruß,
Toti

von Rolle (Gast)


Lesenswert?

Torsten W. schrieb:
> stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb ixon ixoff

Hallo Torsten,

nach obiger Zeile vermute ich, dass du über USB -> seriell Adapter die 
Daten am PC ausgibst.
Bei einem USB -> seriell Adapter ist der XON/XOFF Handshake (wie auch 
RTS/CTS) Sache genau dieses Adapters.
Mal einen von einer anderen Firma verwenden, vielleicht kann deiner das 
nicht !!???

von Torsten W. (torsten_w)


Lesenswert?

Hi,

also als USB<->UART Schnittstelle wird beim MySmartUSB mk2.11 ein CP2102 
von Silicon Labs verwendet. Der sollte laut Datenblatt eigentlich 
Software Handshaking unterstützen.
Leider bietet das MySmartUSB nicht viele Informationen zum Thema 
Pinbelegung. Im Datenblatt wird zwar an einer Stelle geschrieben, dass 
es UART mittels Hardware Handshake unterstützt, aber an keiner Stelle 
wird beschrieben wo die Anschlüsse für CTS und RTS sind, weswegen ich 
die Möglichkeit des Hardware Handshakes erst mal ganz außen vor gelassen 
hab.
Noch bedauerlicher ist aber, dass es noch nicht mal einen Schaltplan im 
Internet zu finden gibt (könnte natürlich auch an meiner Unfähigkeit 
beim Suchen liegen).
Glücklicherweise lassen sich die Leiterbahnen vom CP2102 aber gut 
verfolgen und daher die PINS für CTS und RTS ausfindig machen.
Per Hardware Handshaking funktioniert der Flow Control ohne Probleme, 
wodurch mein Problem nun im Grunde gelöst ist und ich wohl noch besser 
bedient bin als mit Software Flow Control.

Ich würde mich aber trotzdem freuen wenn jemand noch eine Idee hätte, 
warum es per XON/XOFF nicht funktioniert. Da der Controller es ja 
eigentlich unterstützt würde mich das sehr interessieren.

Vielen dank auf jeden Fall für die Antworten bis jetzt.

Gruß,
toti

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Torsten W. schrieb:

>
1
stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb ixon ixoff

Ohne mir den Rest jetzt näher angeschaut zu haben:

Du darfst nur ixon setzen, nicht auch noch ixoff. Letzteres hat unter 
Unix/Linux eine ganz andere Bedeutung, siehe auch "man stty".

Auszug:

       [-]ixoff
        enable sending of start/stop characters

       [-]ixon
        enable XON/XOFF flow control

Gruß,

Frank

von Torsten W. (torsten_w)


Lesenswert?

Hi,

ich hab es sowohl mit als auch ohne -ixoff probiert. Ohne Erfolg. Mit 
Minicom hat es ja auch nicht funktioniert, da wird es separat 
eingestellt.

Gruß,
toti

von · · · − − − · · · (Gast)


Lesenswert?

Rolle schrieb:
> Bei einem USB -> seriell Adapter ist der XON/XOFF Handshake (...)
> Sache genau dieses Adapters.

Eigentlich nicht, der sollte die Handshake-Bytes einfach nur weiter 
senden.

Einem
1
cat output.hex > /dev/ttyUSB0
ist es allerdings sowieso völlig egal ob da was über die Leitung 
reinkommt oder nicht, XON/XOFF kann man damit vergessen. Minicom sollte 
das allerdings können.
Wenn ich mir aber die obige Software ansehe, dann wird zwar nach jedem 
empfangenen Byte ein XOFF zurück gesendet (allerdings auch erst nach dem 
Übertragen via CAN), anschließend dann das empfangene Byte und dann 
direkt danach aber auch wieder ein XON. Minicom dürfte also die meiste 
Zeit den XON-Zustand sehen und frisch und fröhlich weiter senden. Das 
Senden eines XOFF heißt dazu noch lange nicht, das dann keine Daten mehr 
ankommen! Wenn das XOFF irgendwann mal beim Terminalprogramm ankommt, 
sollte dieses zwar keine weiteren Daten mehr senden, alles was sich aber 
z.B. noch im FIFO des auf dem MB des PC implementierten UART befindet 
geht erstmal trotzdem über die Leitung. Und da wie schon gesagt die 
obige Software mehr oder wenige direkt nach dem XOFF wieder ein XON 
sendet haut dann auch das Teminalprogramm diesen FIFO erstmal wieder 
komplett voll. Kein Wunder, daß da die Buffer überlaufen. Zumal während 
der Verarbeitung eines einzigen Bytes (über CAN senden, XOFF+Byte+XON 
über UART senden) mindestens schon die nächsten 3 Bytes empfangen und im 
Receivebuffer abgelegt wurden.
Mittels XON/XOFF einem PC+beliebigem Terminalprogramm beibringen zu 
wollen nur 8 Bytes zu senden und dann zu warten ist nahezu unmöglich. So 
etwas geht maximal via Hardware-Handshake oder spezieller Software, die 
von sich aus nach 8 Bytes wartet.

Via XON/XOFF könnte höchstens sowas in der Art gehen:
1
// ...
2
  uart_putc_buffert(XOFF);
3
  while(1==1) {
4
    // ...
5
    if(rec & UART_NO_DATA){
6
      uart_putc_buffert(XON);
7
      uart_putc_buffert(XOFF);
8
    } else if(rec & UART_BUFFER_OVERFLOW) {
9
      sendUSART("Buffer Overflow!\n\r");
10
    } else {
11
      unsigned char tmp = ((unsigned char)rec);
12
      write_message_to_can(0b1, 1, &tmp);
13
      uart_putc_buffert((unsigned char)rec);
14
    }
15
  }
und dann hoffen/beten, daß die 64 Byte Receivebuffer auf dem AVR 
ausreichen.

von Torsten W. (torsten_w)


Lesenswert?

Hi,

bezüglich der Unterstützung des Adapters bin ich eigentlich auch immer 
davon ausgegangen, dass das wie der Name schon sagt, eine Software Sache 
ist und das Terminalprogramm für das erkennen der XOFF/XON Zeichen 
zuständig ist.

Um die Funktionalität des Software Handshakes generell zu testen hab ich 
Testweise mal einen delay_ms(2000); hinter den Befehl zum Senden von 
XOFF gepackt. Das sollte zwar das überlaufen des Buffers wie du 
beschrieben hast nicht verhindern, aber zumindest sollte Minicom dann ja 
knapp zwei Sekunden das Senden pausieren, bis nach dem delay wieder das 
XON gesendet wird. Leider hat auch das nicht funktioniert. Minicom hat 
einfach weiter gesendet.

Gruß,
toti

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.