Zugriff auf die Steuerleitungen der seriellen Schnittstelle

Post Reply
Message
Author
Meini

Zugriff auf die Steuerleitungen der seriellen Schnittstelle

#1 Post by Meini »

Hi,

ich habe ein kleines Problem: ich habe eine Platine, die ich über die Steuerleitungen der seriellen Schnittstelle anspreche. Das Beispielprogramm dazu läuft unter DOS-BASIC.
Ich probiere das gerade in ANSI-C unter Linux nachzuprogrammieren.

Ich muss die DTR-Leitung umschalten, ausserdem muss TX auf Space liegen. Das klappt soweit auch.
Nun muss ich (mehrere tausend mal pro Sekunde) RTS ganz kurz von Mark auf Space legen. Die abfallende Flanke lädt dann in einem Flip-Flop ein Bit, was ich über DCD abfragen kann.
Seit dem ich das Umschalten der RTS- und Abfrage der DCD-Leitung aufgenommen habe, macht das Programm *manchmal* bei den ioctl-Aufrufen einen ioctl-Input/Output Error. Interessant: es schlagen dann immer ALLE ioctl-Aufrufe fehl (d.h. der Fehler beginnt nicht erst mitten drin).
Aber selbst wenn es keine Fehler gibt, kann ich die RTS-Leitung nur einmal schalten. Danach werden alle weiteren ioctl's dazu ignoriert. Ich habe sogar diverse sleep(1) eingefügt, das ändert aber auch nichts. Und so langsam kann der FIFO doch eigentlich nicht sein...

Kann mir jmd. weiter helfen?

Viele Grüsse
Meinhard

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#2 Post by Janka »

Der FIFO ist doch aber nur für RxD und TxD! Und er ist auch nicht immer vorhanden -- nur bei 16550-kompatiblen Chips.

Die Steuerleitungen sind für so schnelles Umschalten ja eigentlich nicht gedacht. Unter Linux brauchst du dafür unter Umständen eigenen Kernelcode. -- serial.ko bietet meines Wissens nicht einmal automatischen DTR/DSR-Handshake an, nur RTS/CTS, denn das macht der Chip selbst.

Was soll das denn genau werden?

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Meini

#3 Post by Meini »

Janka wrote: Was soll das denn genau werden?
Ach, bei dem ganzen handelt es sich um einen Zufallszahlengenerator. Dazu wird das Rauschen einer Z-Diode im Kennlinienknick verstärkt und digitalisiert. Die Schaltung ist aus der Zeitschrift FUNKAMATEUER, Heft 12/2002, Seite 1337 ff.
Die dort abgedruckten Programme laufen (wie gesagt) mittles BASIC unter DOS. Ich würde gerne einen Kernel-Treiber dafür schreiben. Dazu wollte ich als ersten Schritt ein Programm schreiben, dass bei Aufruf die Zufallswerte ausliest.

Meinhard

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#4 Post by Janka »

Auf Kernelebene kannst du die Register des seriellen Ports direkt ansprechen, wie du das unter DOS mit einem eigenen exe auch könntest. Alternativ kannst du auch den Treiber für den seriellen Port anweisen, diesen einen Port zu ignorieren, und stattdessen inb() und outb() direkt auf die UART-Register anwenden. Das darf allerdings nur root, und auch der muss sich mit ioperm() erst einmal die Rechte dafür reservieren.

Allerdings gibt es immer die Einschränkung, dass Linux ja ein Multiprozesssystem ist, und daher Busy-Loops vermieden werden müssen.

Wenn du in einem normalen Programm genaue Zeiten unter ~4ms einhalten (bei einer Clock von 250Hz, Linux-Standard) musst, musst du zumindest die zeitkritischen Teile des Prozesses mit Echtzeitpriorität ablaufen lassen (Siehe sched_setscheduler()). Ansonsten ist die kleinste Einheit bei usleep() und nanosleep() eben diese 4ms, weil der Prozess bei vollständigem Ausnutzen seiner Zeitscheibe ja in der Priorität runtergestuft wird.



Ergänzung:

Die RTS-Leitung kann vom UART je nach Stand des In-FIFO auch automatisch geschaltet werden. Evtl. kommt da ja einiges durcheinander?

Datenblatt des 16C550:
http://www.datasheetcatalog.com/datashe ... C550.shtml

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Post Reply