home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
telecomm
/
fser096b
/
xsdd.txt
< prev
Wrap
Text File
|
1992-09-11
|
19KB
|
441 lines
Extended Serial Device Driver (XSDD)
Entwurf eines Protokolls mit erweiterten Funktionen zur seriellen I/O
Author: Stephan Baucke
Erste Niederschrift: 7-Sept-1992
Letzte Änderung: 11-Sept-1992
Einleitung
----------
Bekanntlich sind die Möglichkeiten des TOS zur Bedienung der seriellen Schnitt-
stellen recht beschränkt:
- die Bedienung diverser Kontrolleitungen (wie DCD, DTR, RI usw.) ist nur durch
Direktzugriff auf die Hardware möglich
- Es sind nur die von Rsconf angebotenen Baudraten einstellbar, auch wenn die
Hardware mehr erlaubt
- Der Zugriff auf eine Schnittstelle von mehreren Programmen kann nicht koordiniert
werden
- Da mit BIOS jedes Zeichen einzeln übertragen werden muß, ist die I/O-Performance
nicht sehr hoch
Im Rahmen der Entwicklung eines seriellen Treibers für MiNT, der diese Schwächen
beheben sollte, kam die Idee auf, die erweiterte Funktionalität auch unter reinem
TOS zugänglich zu machen. Dies ist ein erster Vorschlag, wie das aussehen könnte.
Im wesentlichen werden dabei die Low-Level-Routinen des MiNT-Treibers über einen
Cookie von außen zugänglich gemacht. Denkbar wäre jedoch auch, die beiden Ebenen
völlig zu trennen und den MiNT-Treiber auf einen separaten TOS-Treiber aufzu-
setzen.
Das XSDD-Protokoll
------------------
Das XSDD-Protokoll unterstützt die über Bconmap verwalteten Devices 6 bis ein-
schließlich <maptabsize+5> (soweit das zugrundeliegende TOS sie zur Verfügung
stellt), sowie das Device 1 (AUX). Operationen auf AUX beziehen sich immer auf
das zum Zeitpunkt des Aufrufs von XSDD gerade aktuelle Bconmap-Device. In Zu-
kunft wird AUX möglicherweise aus technischen Gründen nur noch dann unterstützt,
wenn das zugrundeliegende TOS kein Bconmap hat.
Der Treiber installiert einen Cookie "XSDD". Der Cookie zeigt auf den Einsprung-
punkt des XSDD-Treibers. Unmittelbar vor der Routine (also an Offset -4 vor der
Adresse aus dem Cookie) steht zur Absicherung nochmals die Long-Konstante "XSDD".
Aufruf: Welche Funktion ausgeführt werden soll, wird durch einen Opcode (WORD)
angegeben. Dieser Opcode ist bei jedem Aufruf das erste Argument. Wenn ein un-
gültiger Opcode angegeben wird, wird EINVFN zurückgeliefert.
Die Übergabe aller Parameter erfolgt nach GEMDOS-Konvention, d.h. auf dem Stack.
Der Rückgabewert wird in D0 geliefert. Außer D0 werden keine Register verändert.
Der Aufruf von XSDD darf AUSSCHLIESSLICH im Supervisor-Modus erfolgen.
Z.Zt. sind die im folgenden aufgelisteten Funktionen vorgesehen (Opcodes müssen
noch vergeben werden). Für die Parametertypen gilt folgende Vereinbarung:
BYTE: 8-Bit-Zeichen
WORD: 16-Bit signed Integer
UWORD: 16-Bit unsigned Integer
LONG: 32-Bit signed Integer
-----------------------------------------------------------------------------------
WORD XSVersion(void)
Liefert die Versionsnummer des vom XSDD-Treibers implementierten Protokolls
zurück, Major-Version im Hi-Byte, Minor-Version im Low-Byte (Beispiel: 0x0102
entspricht Version 1.2). Diese Nummer soll nicht etwa die Version des Treiber-
programms wiederspiegeln, sondern nur die des implementierten Protokolls.
Rückgabe:
Protokollversion.
-----------------------------------------------------------------------------------
WORD XSDriverInfo(BYTE *info, LONG *product, WORD *version)
Dieser Aufruf liefert einen Info-String, eine Produktkennung, sowie die Version
des jeweiligen Treiberprogramms zurück. `info' muß dabei auf einen mindestens 80
Bytes großen Puffer zeigen, in den der Info-String nullterminiert eingetragen
wird (der String kann z.B. den Author und den Namen des Treibers enthalten). In
den LONG, auf den `product' zeigt, wird die Produktkennung eingetragen, sowie in
das WORD, auf das `version' zeigt, die Treiberversion.
Rückgabe
0
-----------------------------------------------------------------------------------
WORD XSDevName(WORD device, BYTE *name)
Ermittelt den Namen des zum BIOS-Device gehörigen Ports (z.B. "Modem1"). `name'
muß auf ein mindestens 9 Bytes großes Array zeigen. Dort wird der Name nulltermi-
niert eingetragen.
Rückgabe:
0 bei Erfolg
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
WORD XSReserve(WORD device)
Device reservieren. Es handelt sich hier um ein "advisory" Locking, d.h. es ist
darauf angewiesen, daß jedes Programm den Lock abfragt und freiwillig auf weitere
Zugriffe verzichtet, wenn das Device bereits belegt ist. Jedes Programm hat vor
irgendeinem Zugriff auf das Device diesen Aufruf durchzuführen. Wenn das Device
noch frei war, ist es nach dem Aufruf reserviert. Wenn es bereits reserviert war,
wird ein Fehlercode zurückgeliefert. In diesem Fall sollte keinerlei Zugriff mehr
auf das Device erfolgen.
Rückgabewert:
0 - das Device ist jetzt reserviert
EACCDN - das Gerät war bereits reserviert
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
WORD XSRelease(WORD device)
Device wieder freigeben. Dieser Aufruf darf NUR gemacht werden, wenn vorher
ein erfolgreicher XSReserve durchgeführt werden konnte (mit Rückgabe 0).
Falls auf dem Device noch eine XSCtlSig-Routine angemeldet war, wird sie
automatisch freigegeben.
Rückgabewert:
0 bei Erfolg,
EACCDN - wenn das Device nicht reserviert war.
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSCapMap(WORD device)
Fragt diverse Eigenschaften von Treiber und Device ab. Wenn kein Fehler vorliegt,
wird ein Bitvektor zurückgeliefert. Folgende Bits sind z.Zt. definiert:
#define XS_BREAK 0x01 /* Device kann Break senden */
#define XS_RTSCTS 0x02 /* Device beherrscht RTS/CTS-Handshaking */
#define XS_TANDEM 0x04 /* Device beherrscht XON/XOFF-Handshaking */
#define XS_IOBAUD 0x08 /* Device beherrscht verschiedene I- und O-Baudraten */
#define XS_BIOSRW 0x8000 /* Treiber benutzt BIOS zum Lesen/Schreiben */
Alle anderen Bits sind reserviert und sollten bis auf weiteres ignoriert
werden.
Rückgabewert:
>=0 (LONG!) - Verfügbare Fähigkeiten
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSIBaud(WORD device, LONG baudrate)
Eingabe-Baudrate (genauer: bps) des angegebenen Devices setzen/abfragen. Die Baud-
rate wird unkodiert im "Klartext" angegeben (38400L entspricht z.B. 38400 bps).
Wenn -1L angegeben wird, wird die Baudrate nicht verändert (nur Abfrage). Falls
eine Baudrate angfordert wird, die auf dem Device nicht zur Verfügung steht, wird
die nächst niedrigere verfügbare eingestellt und zurückgeliefert.
Die meisten Devices unterstützen keine getrennten Baudraten für Ein- und Aus-
gabe. In diesem Fall wird mit einem XSIBaud gleichzeitig auch die Ausgabe-
Baudrate verändert (dies kann mit XSCapMap abgefragt werden).
Rückgabewert:
>0 - eingestellte Baudrate
EUNDEV - Ungültiges Device
Anmerkung: Durch die Rückgabe der nächst niedrigen verfügbaren Baudrate kann
der Aufrufer alle für dieses Device verfügbaren Baudraten durch "Abklappern"
von oben nach unten ermitteln.
-----------------------------------------------------------------------------------
LONG XSOBaud(WORD device, LONG baudrate)
Ausgabe-Baudrate (genauer: bps) des angegebenen Devices setzen/abfragen. Die
Funktionsweise ist ansonsten analog zu XSIBaud.
Die meisten Devices unterstützen keine getrennten Baudraten für Ein- und Aus-
gabe. In diesem Fall wird mit einem XSOBaud gleichzeitig auch die Eingabe-
Baudrate verändert (dies kann mit XSCapMap abgefragt werden).
Rückgabewert:
>0 - eingestellte Baudrate
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
WORD XSBreak(WORD device, WORD on)
Ein BREAK auf dem Device setzen/löschen. Wenn `on' ungleich 0 ist, wird BREAK
gesetzt, ansonsten gelöscht. Wenn das Device BREAK nicht beherrscht, wird der
Aufruf ignoriert.
Rückgabe:
0 bei Erfolg
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSSetFlags(WORD device, UWORD flags)
Übertragungsparameter einstellen. Versuche, Einstellungen zu machen, die auf dem
Device nicht möglich sind (d.h. solche, die XSCapMap als nicht verfügbar meldet),
werden ignoriert. `flags' enthält die Einstellung in folgender Kodierung (ent-
spricht der des TIOCGFLAGS-Fcntl von MiNT):
Maske: TF_STOPBITS 0x0003
Werte:
0x0000 Ungültig
0x0001 1 Stop-Bit
0x0002 1.5 Stop-Bits
0x0003 2 Stop-Bits
Maske: TF_CHARBITS 0x000C
Werte:
0x0000 8 Bits pro Zeichen
0x0004 7 Bits
0x0008 6 Bits
0x000C 5 Bits
Maske: TF_PARITY 0xc000
Werte:
0x0000 Keine Parität
0x4000 Gerade Parität
0x8000 Ungerade Parität
0xc000 Ungültig
Weitere Bits:
T_TANDEM 0x1000 XON/XOFF Handshake
T_RTSCTS 0x2000 RTS/CTS Handshake
Alle übrigen Bits sind reserviert und sollten 0 sein.
Rückgabewert:
>=0 (LONG!) - die vor dem Aufruf eingestellten Flags
ERANGE - es wurden ungültige Parameter festgestellt
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSGetFlags(WORD device)
Übertragungsparameter abfragen.
Rückgabewert:
>=0 (LONG!) - Eingestellte Parameter (Kodierung siehe XSSetFlags).
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSCtlMap(WORD device)
Auf dem Device verfügbare Kontrolleitungen abfragen. Wenn kein Fehler vorliegt,
wird ein Bitvektor zurückgeliefert, in dem für die verfügbaren Kontrolleitungen
das entsprechende Bit 1 ist, für die nicht verfügbaren 0. Folgende Bits sind
definiert:
#define TIOCM_LE 0x01 /* line enable */
#define TIOCM_DTR 0x02 /* data terminal ready */
#define TIOCM_RTS 0x04 /* ready to send */
#define TIOCM_CTS 0x08 /* clear to send */
#define TIOCM_CAR 0x10 /* carrier detect */
#define TIOCM_RNG 0x20 /* ring */
#define TIOCM_DSR 0x40 /* data set ready */
Alle anderen Bits sind reserviert und sollten bis auf weiteres ignoriert
werden.
Rückgabewert:
>=0 (LONG!) - Verfügbare Kontrolleitungen
EUNDEV - Ungültiges Device
Anmerkung: Die Werte werden möglicherweise noch geändert, um sie an die (hof-
fentlich bald festgelegten) Definitionen der entsprechenden MiNT-Fcntls anzu-
passen.
-----------------------------------------------------------------------------------
LONG XSGetCtl(WORD device)
Status der Kontrolleitungen abfragen (DCD, RI etc.). Falls kein Fehler auf-
tritt, wird ein Bit-Vektor geliefert (Kodierung wie bei XSCtlMap beschrieben).
Die Bits sind 1, wenn die entsprechende Leitung aktiviert ist, sonst 0.
Rückgabewert:
>=0 (LONG!) - Status der Kontrolleitungen
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
WORD XSSetCtl(WORD device, UWORD ctl)
Kontrolleitungen setzen. Kodierung wieder wie in XSCtlMap. Manche Leitungen (z.B.
CTS) sind Read-only und können daher nicht beeinflußt werden (das sollte aus dem
Kontext hervorgehen). Versuche, solche und Leitungen, die nicht von dem Device
unterstützt werden (d.h. von XSCtlMap als nicht verfügbar gemeldet wurden), zu
beeinflussen, werden ignoriert.
Rückgabewert:
0 bei Erfolg
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
WORD XSOnCtl(WORD device, UWORD on_mask)
Die Kontrolleitungen, deren Bit in `on_mask' gesetzt ist, aktivieren, ohne die
anderen zu beeiflussen. Ansonsten gelten dieselben Bedingungen, wie bei XSSetCtl.
Rückgabewert:
0 bei Erfolg
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
WORD XSOffCtl(WORD device, UWORD off_mask)
Die Kontrolleitungen, deren Bit in `off_mask' gesetzt ist, ausschalten, ohne die
anderen zu beeiflussen. Ansonsten gelten dieselben Bedingungen, wie beiXSSetCtl.
Rückgabewert:
0 bei Erfolg
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSInStat(WORD device)
Ermittelt Anzahl der Zeichen, die z.Zt. auf dem Device zum Lesen verfügbar sind.
Der zurückgelieferte Wert muß nicht exakt sein. Es ist nur garantiert, daß mit
dem nächsten Lesezugriff mindestens soviele Bytes gelesen werden können, es
können aber auch mehr sein.
Rückgabewert:
>=0 - Anzahl der verfügbaren Zeichen
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSOutStat(WORD device)
Ermittelt Anzahl der Zeichen, die z.Zt. auf das Device geschrieben werden können.
Der zurückgelieferte Wert muß nicht exakt sein. Es ist nur garantiert, daß mit
dem nächsten Schreibzugriff mindestens soviele Bytes ausgegeben werden können,
es können aber auch mehr sein.
Rückgabewert:
>=0 - Anzahl der Zeichen, die ausgegeben werden können
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
LONG XSRead(WORD device, LONG count, BYTE *buffer)
Maximal `count' Zeichen in den durch `buffer' angegebenen Speicherbereich lesen.
Wenn z. Zt. nicht soviele Zeichen verfügbar sind, kehrt XSWrite sofort zurück
(non-blocking).
Rückgabewert:
>=0 - Anzahl der Zeichen, die gelesen wurden wurden
EUNDEV - Ungültiges Device
Weitere (negative) TOS-Fehlernummern bei I/O-fehlern
-----------------------------------------------------------------------------------
LONG XSWrite(WORD device, LONG count, BYTE *buffer)
`count' Zeichen aus dem durch `buffer' angegebenen Speicherbereich auf das Device
schreiben. Wenn z. Zt. nicht so viele Zeichen geschrieben werden können, kehrt
XSWrite sofort zurück (non-blocking).
Rückgabewert:
>=0 - Anzahl der Zeichen, die geschrieben wurden
EUNDEV - Ungültiges Device
Weitere (negative) TOS-Fehlernummern bei I/O-Fehlern
-----------------------------------------------------------------------------------
WORD XSFlush(WORD device, WORD mode)
Verwerfe Zeichen, die noch im Puffer des Treibers stehen. `mode' gibt genauer
an, was verworfen wird:
0: Verwerfe Zeichen, die empfangen, aber noch nicht ausgelesen wurden
1: Verwerfe Zeichen, die geschrieben, aber noch nicht gesendet wurden
2: Verwerfe alle noch gepufferten Zeichen
Wenn die Operation auf dem Device nicht möglich ist, wird der Aufruf ignoriert.
Rückgabewert:
0 bei Erfolg
ERANGE - wenn `mode' nicht 0, 1 oder 2 ist
EUNDEV - Ungültiges Device
-----------------------------------------------------------------------------------
WORD XSInSig(WORD device, void (*func)(WORD device))
Weist den Treiber an, die durch `func' angegebene Funktion anzuspringen, sobald
ein neues Zeichen von dem Device eingetroffen ist. Der Routine wird dabei die
Device-Nummer auf dem Stack übergeben. Die angegebene Routine wird sehr wahr-
scheinlich aus einem Interrupt heraus aufgerufen. Dementsprechend darf sie keine
Register verändern und sollte möglichst kurz sein. Die Routine wird nur genau
einmal aufgerufen, danach wird der XSInSig automatisch wieder deaktiviert. Wenn
vor dem Aufruf bereits ein XSInSig aktiv war, wird der neue nicht installiert
und EACCDN zurückgeliefert.
Wenn als `func' ein Null-Zeiger übergeben wird, wird ein vorher gesetzter XSInSig
annuliert.
XSInSig muß nicht auf jedem Device verfügbar sein; in diesem Fall wird EINVFN
zurückgeliefert.
Rückgabe:
0 - bei Erfolg
EINVFN - Device unterstützt XSInSig nicht
EACCDN - Es ist bereits ein XSInSig aktiv
EUNDEV - Ungültiges Device
Anmerkung: Diese Funktion ist in der Hauptsache zur Implementation von MiNT-
Treibern gedacht und sollte von Anwendungsprogrammen nicht verwendet werden.
-----------------------------------------------------------------------------------
WORD XSOutSig(WORD device, void (*func)(WORD device))
Weist den Treiber an, die durch `func' angegebene Funktion anzuspringen, sobald
ein neues Zeichen auf das Device ausgegeben werden kann. Die Funktionsweise ist
ansonsten analog zu XSInSig.
Wenn als `func' ein Null-Zeiger übergeben wird, wird ein vorher gesetzter
XSOutSig annuliert.
XSOutSig muß nicht auf jedem Device verfügbar sein; in diesem Fall wird EINVFN
zurückgeliefert.
Rückgabe:
0 - bei Erfolg
EINVFN - Device unterstützt XSOutSig nicht
EACCDN - Es ist bereits ein XSOutSig aktiv
EUNDEV - Ungültiges Device
Anmerkung: Diese Funktion ist in der Hauptsache zur Implementation von MiNT-
Treibern gedacht und sollte von Anwendungsprogrammen nicht verwendet werden.
-----------------------------------------------------------------------------------
LONG XSCtlSig(WORD device, UWORD ctl_mask, void (*func)(WORD device, UWORD ctl))
Weist den Treiber an, die durch `func' angegebene Funktion anzuspringen, sobald
sich der Zustand einer der in `ctl_mask' spezifizierten Kontrolleitungen ändert
(Kodierung wie bei XSCtlMap angegeben). Der Routine wird dabei die Device-Nummer
und ein Bitvektor, in dem das Bit der auslösenden Kontrolleitung gesetzt ist,
auf dem Stack übergeben. Die angegebene Routine wird sehr wahrscheinlich aus
einem Interrupt heraus aufgerufen. Dementsprechend darf sie keine Register ver-
ändern und sollte möglichst kurz sein. Die Routine wird nur genau einmal aufge-
rufen, danach wird der XSCtlSig automatisch wieder deaktiviert. Wenn vor dem
Aufruf bereits ein XSCtlSig aktiv war, wird der neue nicht installiert und
EACCDN zurückgeliefert.
Wenn als `func' ein Null-Zeiger übergeben wird, wird ein vorher gesetzter
XSCtlSig annuliert.
XSCtlSig muß nicht auf jedem Device verfügbar sein; in diesem Fall wird EINVFN
zurückgeliefert. Ebenso muß er nicht für alle verfügbaren Kontrolleitungen ver-
fügbar sein. Wenn in `ctl_mask' Kontrolleitungen angegeben werden, die durch
XSCtlSig nicht unterstützt werden, wird das ignoriert. Auf welche Leitungen
tatsächlich reagiert wird, kann man aus dem Rückgabewert ersehen.
Sobald ein Device mit XSRelease freigegeben wird, werden noch darauf installierte
XCtlSig automatisch abgemeldet.
Rückgabe:
>0 (LONG!) - Maske mit den tatsächlich berücksichtigten Kontrolleitungen.
EINVFN - Device unterstützt XSCtlSig nicht
EACCDN - Es ist bereits ein XSCtlSig aktiv
EUNDEV - Ungültiges Device
Anmerkung: Diese Funktion kann z.B. verwendet werden, um effizient die RI- oder
DCD-Leitungen zu überwachen (man installiert eine Routine, die im eigenen Pro-
gramm ein Flag setzt und fragt dieses periodisch ab). ACHTUNG: Ein Programm,
daß diese Funktion benutzt, darf keinesfalls vergessen, den XSCtlSig vor dem
Beenden wieder zu annulieren.
END-OF-TEXT