2016-03-29 11 views
1

Ich passe eine einfache Linux-Serienbibliothek an, die ich für plattformübergreifende Kompatibilität geschrieben habe. Die meisten Dinge werden übertragen (obwohl Microsoft darauf besteht, alles umzubenennen), aber es gibt ein paar Funktionen, die ich nicht finden konnte.Verwenden von VMIN und VTIME mit Windows

Mein aktuelles Problem ist die Verwendung von VMIN und VTIME (in struct termios). Unter Linux benutze ich sie, um Lesevorgänge zu erzwingen, die für eine bestimmte Anzahl von Zeichen blockiert werden. Wenn sie jedoch nicht empfangen werden, tritt ein Timeout mit einem Fehler auf. Windows empfiehlt jedoch, die BuildCommDCB-Funktion zu verwenden, anstatt Parameter für seine Struktur DCB (Gerätesteuerungsblock) direkt festzulegen. Diese Funktion unterstützt nichts, was VMIN oder VTIME ähnelt, und die Struktur DCB ist nicht viel besser.

Gibt es eine Möglichkeit, diese Funktionalität in Windows zu erhalten, ohne es selbst zu implementieren? Ich würde mich lieber nicht damit beschäftigen, serielle Interrupts und Callbacks für nur eine Plattform in meiner Bibliothek zu verwalten, wenn es überhaupt vermeidbar ist.

EDIT: Die SetCommTimeouts Funktion scheint die Funktionen von VTIME zu emulieren, aber ich habe immer noch nichts für VMIN gefunden.

Antwort

0

Ich konnte den Fall nicht perfekt emulieren, wo VMIN = 0 und VTIME = 0, aber ich konnte alles andere genau neu erstellen.

Im Konstruktor der Klasse, nachdem die DCB initialisiert und angewandt wird (timeout ist ein COMMTIMEOUTS, readTimeout und readMinChars sind unsigned char e):

//Set read timeouts 
if(readTimeout > 0) { 
    if(readMinChars > 0) { //Intercharacter timeout 
     timeout.ReadIntervalTimeout = readTimeout * 100; //Deciseconds to milliseconds 
    } else {    //Total timeout 
     timeout.ReadTotalTimeoutConstant = readTimeout * 100; //Deciseconds to milliseconds 
    } 
} else { 
    if(readMinChars > 0) { //Counted read 
     //Handled by length parameter of serialRead(); timeouts remain 0 (unused) 
    } else {    //"Nonblocking" read 
     timeout.ReadTotalTimeoutConstant = 1; //Wait as little as possible for a blocking read (1 millisecond) 
    } 
} 
if(!SetCommTimeouts(handle, &timeout)) { 
    printf("Error setting serial port timeout: %lu\n", GetLastError()); 
    throw std::runtime_error("serial initialization failed"); 
} 

Die komplette Serienklasse ist auf Github verfügbar als Teil eines viel größeren Projekts: serial.hserial.cpp

+0

VMIN ist minimale Anzahl von Zeichen, der Parameter für die Leselänge ist maximal! Es gibt keine Entsprechung auf Windows afaik. Und für nonblocking lesen müssen Sie "einen Wert von MAXDWORD, kombiniert mit Nullwerten für die ReadTotalTimeoutConstant und ReadTotalTimeoutMultiplier Mitglieder". – Trass3r

0

Sie könnten versuchen, die source code for cygwin zu betrachten. Ich denke, sie machen einen guten Job, indem sie Windows Serial I/O basierend auf der Unix-API richtig verhalten.

+0

Ich konnte die Header-Dateien für serielle I/O in diesem Repository nicht finden, und die Quelldateien werden in Cygwin1.dll in meiner lokalen Installation kompiliert. – Techwolf