2010-06-05 7 views
6

Ich schrieb eine Anwendung, die serielle Schnittstellen unter Linux verwenden muss, insbesondere ttyUSB. Lese- und Schreiboperationen werden mit der standard select()/read() Schleife und write() ausgeführt, und es ist wahrscheinlich nichts Falsches daran, aber der Initialisierungscode (oder das Fehlen eines Teils davon) beschädigt etwas im tty Subsystem. Hier ist sie:Korrekte Initialisierungssequenz für Linux serielle Schnittstelle


    vuxboot(string filename, unsigned baud = B115200) : _debug(false) { 
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY); 
    if(_fd < 0) throw new io_error("cannot open port"); 

    // Serial initialization was written with FTDI USB-to-serial converters 
    // in mind. Anyway, who wants to use non-8n1 protocol? 

    tcgetattr(_fd, &_termios); 

    termios tio = {0}; 
    tio.c_iflag = IGNPAR; 
    tio.c_oflag = 0; 
    tio.c_cflag = baud | CLOCAL | CREAD | CS8; 
    tio.c_lflag = 0; 

    tcflush(_fd, TCIFLUSH); 
    tcsetattr(_fd, TCSANOW, &tio); 
    } 

Ein weiterer tcsetattr(_fd, TCSANOW, &_termios) im destructor sitzt, aber es spielt keine Rolle.

Mit oder ohne diese Terminologie-Initialisierung passieren seltsame Dinge im System nach der Anwendung beendet. Manchmal wird einfach cat (oder hd) beendet, sofort druckt nichts oder dasselbe Zeug jedes Mal, manchmal wartet es und zeigt keine der Daten an, die sicher an den Port gesendet werden; und close() (read() auch, aber nicht jedes Mal) gibt eine seltsame WARNING zu dmesg referring to usb-serial.c.

Ich habe die Hardware und Firmware Dutzende Male überprüft (sogar auf verschiedenen Maschinen) und ich bin sicher, dass es wie vorgesehen funktioniert; außerdem entfernte ich die Firmware, um die gleiche Nachricht immer wieder zu drucken.

Wie kann ich die serielle Schnittstelle verwenden, ohne etwas zu zerstören? Danke.

Antwort

0

Okay. Das ist vielleicht keine perfekte Lösung ... ist es definitiv nicht. Ich warf gerade FT232 Konverter (fritierte es tatsächlich) und benutzte CP2102-based one. Es funktioniert jetzt (und ist auch 6 mal billiger).

1

Ich bin nicht sicher, was mit Ihrem Code-Snippet falsch ist es aber dies könnte sich als nützlich erweisen, wenn Sie nicht bereits gesehen haben: Serial Programming Guide for POSIX Operating Systems

Ich hatte einige serielle Schnittstelle zu tun vor kurzem Schnittstelle und this library funktionierte gut, das könnte als ein weiteres Beispiel dienen.

+0

Ich habe gerade den Großteil des obigen Codes aus diesem Handbuch kopiert. Es ist nur _not that good_, oder fehle ich etwas? .. Ich werde diese Bibliothek überprüfen, aber es ist GPL, und meine App verwendet Expat (aka MIT); und auch die Schnittstelle ist überhaupt nicht gut. Z.B. Ich möchte ttyUSB als eine Zeichenkette spezifizieren: es könnte andere Namen mit unterschiedlicher udev Config oder manchmal bekommen. – whitequark

+0

Ja, ich muss zugeben, es gab ein paar verwirrende Teile in diesem Leitfaden, aber immer noch war das die umfassendste Ressource, die ich finden konnte. In Bezug auf die Bibliothek: Vielleicht können Sie es als "Gesundheitscheck" verwenden, nur um zu sehen, ob das auch Ihr System kaputt macht? – Hamza

+0

Ja, ich überprüfte und kann bestätigen, dass der Initialisierungscode in dieser Bibliothek und in meinem Code identisch ist, außer für 'O_NDELAY' (= 'O_NONBLOCK'). Ich hatte diese Option in der Vergangenheit, und die Ergebnisse waren noch seltsamer: vollständiger Unsinn wurde an das Gerät gesendet und von ihm empfangen, Fehler wurden von 'read()' zurückgegeben, und noch mehr 'WARNING's in syslog. – whitequark

2

Eine WARN_ON Zeile schlagen könnte bedeuten, dass Sie einen Kernel-Fehler getroffen haben. Ich weiß, dass in letzter Zeit viel an der Verbesserung des USB-Seriell-Treibers gearbeitet wurde; Ich schlage vor, einen neueren Kernel zu testen und/oder auf der Mailingliste [email protected] zu fragen.

+0

Dieses Problem wird häufig von Leuten mit Beagle-Boards getroffen, bei denen fast alles über USB angeschlossen ist. Ich bin mir auch ziemlich sicher, dass er einen von mehreren möglichen Fehlern in diesem Subsystem trifft. –

+1

Geschichte für den stabilen Kernel schlägt vor, dass nach ca. 2009-10. Auch wenn ich "Minicom" oder ähnliche Tools verwende, tritt der "Bug" nicht auf. – whitequark

0

Genau wie eine Randnotiz, ist Ihre Fehlerprüfung auf open nicht ganz richtig - Fehlerbedingungen werden durch einen Rückgabewert von -1 signalisiert. (0 ist eine absolut gültige fd, in der Regel auf stdin verbunden.)

+0

Danke, das behoben. – whitequark

0

Sie könnten versuchen wollen:

vuxboot(string filename, unsigned baud = B115200) : _debug(false) { 
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY); 
    if(_fd < 0) throw new io_error("cannot open port"); 

    // Serial initialization was written with FTDI USB-to-serial converters 
    // in mind. Anyway, who wants to use non-8n1 protocol? 

    tcgetattr(_fd, &_termios); 

- termios tio; 
+ termios tio; 
+ memcpy(&tio, &_termios, sizeof(struct termios)); 

    tio.c_iflag = IGNPAR; 
    tio.c_oflag = 0; 
    tio.c_cflag = baud | CLOCAL | CREAD | CS8; 
    tio.c_lflag = 0; 

    tcflush(_fd, TCIFLUSH); 
    tcsetattr(_fd, TCSANOW, &tio); 
} 

Dies macht es so, dass alle unerwarteten Bereichen termios auf Ihrem System etwas vernünftige Werte bekommen.

Verwandte Themen