Comm-Port und Windows
Informationen zur Win32-API
Links
- "Serial Communications in Win32" by Allen Denver
http://msdn.microsoft.com/library/en-us/dnfiles/html/msdn_serial.asp (schwirrt auch als PDF herum). - Platform SDK:
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm 340MB! Es gibt dafür sogar eine Newsgroup (microsoft.public.platformsdk.sdk_install). - oder "kompakt" (17MB) im Hilfeformat bei
ftp://ftp.borland.com/pub/bcppbuilder/techpubs/bcb5/b5ms.zip
http://www.tldp.org/HOWTO/Serial-HOWTO-18.html Informationen über UARTs und deren FIFO.
http://www.lvr.com/serport.htm
http://www.thaiio.com/serialport.html
Win32-Funktionen:
- SetupComm - stellt Größe des Empfangs- und des Sendepuffers ein. Der Sendepuffer muß so groß sein wie der größte "am Stück" gesendete String.
- SetCommState schickt den DCB zum Port und somit auch die DTR und RTS-Zustände (siehe auch EscapeCommFunction).
- ReadFile, WriteFile
- SetCommBreak/ClearCommBreak: Pegel der TxD-Leitung ("Break") - hält normale Kommunikation an!
- GetCommModemStatus liefert Pegel aller Eingänge (außer RxD): DSR CTS DCD (=RLSD) RI
- PurgeComm bricht Lese- und Schreiboperationen ab und löscht Puffer (alles wahlweise).
- SetCommTimeouts, GetCommTimeouts: Lese- und Schreibtimeouts.
- WaitCommEvent wartet auf Events (Break, CTS, DSR, ERR, RING, RLSD (=DCD), RXCHAR, RXFLAG, TXEMPTY). Problematisch bei "non-overlapped"-Betrieb, weil man es nicht abbrechen kann.
- SetCommMask setzt die zu überwachenden Events für WaitCommEvent. GetCommMask fragt ab.
- ClearCommError: Handshake-Wartegrund, Empfangs-Break und -fehler, Lese- und Schreibpufferzustand. Achtung: Schreibpufferzeiger nur nutzbar bei overlapped I/O!
- EscapeCommFunction setzt DTR, RTS, TxD (Break). Ersteres kann auch SetCommState, letzteres kann auch SetCommBreak und ClearCommBreak. Vorsicht: DTR und RTS in "aufbewahrtem" DCB stimmen bei Verwendung von EscapeCommFunction nicht mehr mit der Realität überein! Müßte man dann selbst passend einstellen oder vorher GetCommState verwenden oder nur SetCommState verwenden.
- GetDefaultCommConfig kann man verwenden, um das Vorhandensein eines Ports zu testen. Einzige Methode, die keine Dialogbox öffnet, wenn der Port gerade in einer DOS-Box verwendet wird! Achtung - funktioniert wohl auch bei Parallelports, also sollte man noch "dwProvSubType" testen.
- EnumPorts kann man zur Auflistung aller Ports (auch Parallelports) im System verwenden, und danach mit GetDefaultCommConfig auf "Seriellport" testen.
Win32-Datenstrukturen:
- DCB (GetCommState, SetCommState): Datenformat, Geschwindigkeit, Handshake, Pegel der Handshake-Ausgänge
- COMMTIMEOUTS (SetCommTimeouts, GetCommTimeouts): Lese- und Schreibtimeouts. Alle Einträge '0' bedeutet "ewig warten". timeouts.ReadIntervalTimeout = MAXDWORD; und Rest = 0 bedeutet "gar nicht warten", dabei ist mir nicht klar, ob der Pufferinhalt gelesen wird oder gar nichts.
- Errors, COMSTAT (ClearCommError, siehe oben).
- Pegel der Schnittstelleneingänge außer RxD (GetCommModemStatus)
- COMMCONFIG enthält dwProviderSubType, mit dem man den Typ des Ports (seriell, parallell...) feststellen kann (GetDefaultCommConfig).
Overlappend vs. Non-Overlapped:
- Non-Overlapped blockiert fast alles, sogar der Sendevorgang wartet, bis alle Zeichen gesendet sind, wahrscheinlich sogar die 16 Bytes aus dem Hardware-Fifo (falls der bei non-overlapped überhaupt aktiv ist)! Der Sendepuffer muß aber trotzdem wenigstens so groß sein, wie der gesendete String (ausprobiert). Die COMSTAT Struktur meldet im non-overlapped-Modus immer einen leeren Sendepuffer.
- Overlapped-Operationen müssen abgeschlossen sein, bevor die OVERLAPPED Struktur wieder verwendet wird. Um "sorglos" mehrere Strings hintereinander schreiben zu können, muß man also einen eigenen (zusätzlichen) Sendepuffer verwalten!
- Overlapped-Funktionen können auch sofort mit "fertig"-Status zurückkehren, das erfordert viel Code zur Behandlung der unterschiedlichen Fälle.
- Bei Timeouts muß man möglicherweise die overlapped-Operation explizit abbrechen (da bin ich mir nicht ganz sicher).
- Overlapped bietet dafür Events, und gleichzeitiges Senden und Empfangen.
Bugs, Fallstricke, weitere Informationen
- EV_RING wird in Win95 nicht unterstützt.
- ReadIntervalTimeout funktioniert in W2K nicht, wenn ein Hardware-FIFO aktiv ist: ReadFile kehrt mit Timeout zurück, wenn ReadIntervalTimeout kürzer ist als die Zeit, die der FIFO puffert.
- Möglicherweise wird in manchen Windows-Versionen ein Break nicht richtig erkannt, sondern nur 0x00 empfangen.
- Howto: "If a thread is blocked on any communications function and another thread calls a communications function, the second thread is blocked until the communications function returns in the first thread." Das betrifft ausdrücklich SetCommMask, während jemand mit WaitCommEvent wartet, wahrscheinlich aber auch Schreiboperationen, während jemand liest oder mit WaitCommEvent wartet! Das heißt, es gibt wahrscheinlich keine einfache Möglichkeit, WaitCommEvent mit einem Timeout zu versehen.
- Möglicherweise führen Kommunikationsfehler (Frame Error usw.) zum Blockieren der Kommunikation (Howto: "In either case, errors associated with the communications port cause all I/O operations to be suspended until removal of the error condition."). Testen und ggf. in der Empfangsroutine ClearCommError verwenden. Möglicherweise im DCB einstellbar (fAbortOnError).
- DTR flow control thresholds sind 1/2 und 1/4.
Alternativen zur Win32-API
- sio.c und siolight.c von Tim Hudson/Matthias Bruestle sollte unter
http://cvs.gnumonks.org/scez/sio/siolight.c?rev=1.6 oder
http://cvs.gnumonks.org/scez/sio/siolight.c verfügbar sein (ist aber gerade down). - Die RSAPI-DLL von Kainka und Berndt, erhältlich bei
http://www.b-kainka.de/download.htm, damit kann man sogar unter Excel und Word einfach auf die serielle Schnittstelle zugreifen.
http://www.codeproject.com/system/serial.asp (C++)- CPort:
http://sourceforge.net/projects/comport/ (Delphi-component, ursprünglich von Dejan Crnila) - TurboPower Async Professional
http://sourceforge.net/projects/tpapro/ (Delphi, ActiveX
Kommerziell:
http://www.wcscnet.com/ COMM-DRV/LIB Standard Edition ca. 80EUR, setzt auf Win32-API auf. Auch echte Treiber mit Timestamp, 9-Bit-Protokolle etc: COMM-DRV/VxD (154EUR), COMM-DRV/NT (243EUR), Runtime-Lizenzen stark gestaffelt von 125/50..500/100...
http://www.kithara.de/
Zum Vergleich: Behandlung der seriellen Schnittstelle unter Linux
Links:
Serial-Programming-HOWTO von Vern Hoxie, darauf kann ich (ob) auch als "anonymous" mit E-Mail-Adresse als Paßwort nicht zugreifen,- wohl aber auf das
Serial-Programming-HOWTO.
Serial Programming Guide for POSIX Operating Systems gibt viel mehr her.
ftp://ftp.digi.com/pub/shareware/unix/dinc/ ein kleines Terminalprogramm
http://sources.redhat.com/ml/cygwin/1997-06/msg00033.html Cygwin Linux<->Win32, hier nur Patches.- Buch: Advanced Programming in the UNIX Environment by W. Richard Stevens (Reading, Massachusetts: Addison-Wesley Publishing Company, 1992)
Informationen:
- Linux verwendet POSIX' termios.h
- Daten: termios Struktur
- Funktionen: open, read, write, close, select, fcntl, tcgetattr, tcsetattr, tcgetospeed, tcgetispeed, tcsetospeed, tcsetispeed, tcdrain, tcflow, tcflush, tcsendbreak and, on some systems, termios, termio, termiox.
- Hardware-Handshake ist nicht im POSIX.1-Standard enthalten (wohl aber ein Bit in der termios-Struktur der meisten Implementierungen)
- Timeout auch "gesamt" und "zwischen zwei Zeichen", aber in 0,1s-Schritten!!
- tcdrain wartet, bis der Sendepuffer leer ist (aber wohl auch nicht bei Hardware-Puffern?).
- tcflush bekommt einen Parameter, was "geflusht" werden soll.
struct termios {
tcflag_t c_iflag; /* input modes */
tcflag_t c_oflag; /* output modes */
tcflag_t c_cflag; /* control modes */
tcflag_t c_lflag; /* line discipline modes */
speed_t c_ospeed; /* output speed */
speed_t c_ispeed; /* input speed - not supported */
cc_t c_cc[NCCS]; /* control chars */
};
