mikrocontroller.net

Forum: PC-Programmierung Realtime Treiber Zeitproblem (inb/outb)


Autor: Daniel A. (insanity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe heute meinen ersten Realtime Treiber für eine MESA 4A23 24Bit 
AD-Karte (16 Kanäle) fertiggestellt.

Ich arbeite unter Ubuntu 10.04 und der Treiber wird benötigt um mit EMC2 
eine Messmaschine anzusteuerun und eine Wägezelle sowie einen LVDT 
auszuwerten.

Mein Problem ist nun, dass der Treiber zwar funktioniert, jedoch beim 
Lesen und Schreiben mit inb() und outb() ca. 300.000ns Prozessorzeit 
benötigt wird. 50.000ns wären gerade noch tolerierbar.

Die Karte ist ohnehin sehr langsam (max. 200Hz) und ich habe deswegen 
den Treiber so geschrieben, dass die Abfrageroutine sofort wieder 
verlässt wenn keine Daten anstehen.

Die 300.000ns Rechenzeit entsteht somit nur dann, wenn Daten am Port 
verfügbar sind und abgefragt werden. Ausgewertet wird immer nur ein 
Kanal, erst nach auslesen des Werts wird zum nächsten geschaltet.

Zu sagen wäre noch, dass die Daten seriell (SPI) über den ISA-Bus 
übertragen werden. Die Daten sind 24Bit lang.

Pro Abfrage wird ein 8 Bit langer Befehl in den AD Wandler reingeschoben 
(max. 24x outb(), min. 16x outb()) und danach ein 24 Bit langer Wert 
ausgelesen (24x inb() und 48x outb()).

Kann es sein, dass 72x outb() und 24x inb() 300ms braucht?

Das System ist ein PC/104+ Intel Atom N450 Board mit 30GB SSD Festplatte 
und 2GB 666MHz RAM. Sogar Linux mit emulierten Windows 7 ohne Probleme 
darauf.

MfG
Daniel

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel A. schrieb:
> 300.000ns

Damit meinst Du 300 ns oder 300 µs?

Autor: Daniel A. (insanity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
300.000ns = 300µs = 0,3ms

Hab gerade einen Link gefunde mit einer Übersicht über die Zeitdauer von 
gewissen Befehlen: 
http://inf3-www.informatik.unibw-muenchen.de/resea...

Hier wird inb(0x378) mit 1,6µs angegeben. Mit 96 x 1,6µs = 153,6µs

Testmaschine war ein AMD K6 400MHz. Wenn sich die Zykluszeit linear zur 
Frequenz verhalten würde, dann wär ich bei ca. 35µs, auch schon sehr 
Grenzwertig und erklärt auch nicht meine 300µs.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Dauer eines I/O-Zugriffs hängt nicht von der Taktfrequenz der CPU 
ab, sondern von der Geschwindigkeit des verwendeten Busses. 1.6 µs 
lassen auf den ISA-Bus schließen; I/O-Zugriffe auf dem PCI-Bus sind 
erheblich schneller.

Wenn 96 I/O-Befehle in 300 µs ausgeführt werden, dann ist da noch 
irgendwas anderes geschwindigkeitsbegrenzendes im Spiel.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kenne mich mit Ubuntu zugegebenermaßen nicht wirklich aus. Ich habe 
aber vor gefühlten 300 Jahren in der Betriebssytemvorlesung gelernt, das 
*X*-Betriebssystem nicht realtime-fähig sind. Es gibt wohl das eine oder 
andere Derivat, das das leistet, aber ein normales Unix-basiertes BS 
kann das nicht.

Von daher halte ich Deine Antwortzeiten für durchaus normal. Es dauert 
eben, bis ein wartender Prozess wieder rechenbereit ist.

Gruß
Markus

Autor: Sam Spade (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Kann es sein, dass 72x outb() und 24x inb() 300ms braucht?
Es hängt davon ab welches Hardwaredevice du ansprichst. Selbst wenn dir 
das Gerät die Daten als verfügbar meldet, heisst das nicht automatisch, 
dass es dich diese in einem Rutsch auslesen lässt. Du kennst den 
internen Aufbau der Karte nicht und wenn es die Flusskontrolle auf dem 
Bus bedient dann steht eben der Rechner still.

>Hier wird inb(0x378) mit 1,6µs angegeben. Mit 96 x 1,6µs = 153,6µs
Das ist pauschaler Quark. Der Linux-Kernel selbst ist zwar nicht 
unterbrechbar aber wenn das Modul über einen Hardwareinterrupt 
angesteuert wird ist das zu deinem Vorteil. Die Frage ist also auch wie 
du in das Modul hineinspringst.

Autor: Daniel A. (insanity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> ...das *X*-Betriebssystem nicht realtime-fähig sind. Es gibt wohl das eine oder
> andere Derivat, das das leistet, aber ein normales Unix-basiertes BS
> kann das nicht.

Schon mal was von RTAI gehört? Linux mit wird mit einem Patch neu 
kompiliert und kann dann Realtime Tasks mit höchster Priorität 
ausführen. Ist seit

Sam Spade schrieb:
> Das ist pauschaler Quark. Der Linux-Kernel selbst ist zwar nicht
> unterbrechbar aber wenn das Modul über einen Hardwareinterrupt
> angesteuert wird ist das zu deinem Vorteil. Die Frage ist also auch wie
> du in das Modul hineinspringst.

Ich schreibe keinen Device Treiber für einen normalen Kernel, sondern 
ein Realtime Modul.

Grundsätzlich ist beides sehr ähnlich, nur dass ich keine 
read/write-Funktionen definiere die bei Zugriff auf die Gerätedatei 
aufgerufen werden. Bei einem RTAI Modul werden periodisch (später alle 
100µs) die Daten zwischen RTAI und User-Space aktualisiert.

Bei einer Device-Treiber read-Funktion wäre die Wartezeit kein Problem, 
Linux würde selbst den Prozess unterbrechen. Beim RTAI hängt sich das 
System jedoch auf. Wird die Lesefunktion schneller aufgerufen als sie 
ausgeführt wird, so bekommt der Kernel keine Rechenzeit mehr. Das 
Problem hatte ich schon.

Ich kann also probieren 2 Threads zu machen, einen davon sehr langsam 
für die AD Karte (5ms) und einen schnelleren für die restlichen Module 
(100µs). RTAI teilt dann selbst die Prozesse auf.

Oder ich teile das Auslesen auf mehrere Zyklen auf, wobei wieder mehr 
Rechenleistung benötigt wird und die 100µs Thread-Periode bei 200Hz auf 
keinen Fall ausreicht.

Somit kann ich nur sagen, scheiß serieller Bus.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel A. schrieb:
> Somit kann ich nur sagen, scheiß serieller Bus.

Welcher serielle Bus? Deine Karte ist eine PC/104-Karte, also eine 
stinknormale ISA-Karte.

Das Timing von I/O-Zugriffen ist hier 
http://www.techfest.com/hardware/bus/isa_sokos.htm zu erahnen.

Autor: Daniel A. (insanity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. Firefly schrieb:
> Welcher serielle Bus? Deine Karte ist eine PC/104-Karte, also eine
> stinknormale ISA-Karte.

Ich weis schon dass PC/104 ein ISA Bus ist, sonst hätte ich ja keinen 
Treiber dafür schreiben können.

Der AD-Wandler darauf ist aber ein CS5526 und dieser wird seriell 
angesteuert auch wenn er an einem ISA Bus hängt. Andere AD-Wandler geben 
den Wert parallel aus, meine Karte benötig zum Schreiben von einem Bit 3 
Schreibbefehle (outb) und zum Lesen eines Bits auch wieder 2 Schreib und 
1 Lesebefehl.

24 Bit könnten bei parallelem Ausgang mit mindestens 3 inb() gelesen 
werden, bei mir sind dafür aber 96 Befehle nötig.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn das Hardwaredesign der Karte so aussieht, daß die Ansteuerung per 
Bitbanging erfolgt, dann ist das gelinde gesagt ziemlicher Schrott.
Haben die Hardwaredesigner der Karte noch nie etwas von Schieberegistern 
gehört?

Autor: Daniel A. (insanity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Aufbau der Hardware ist ein bisschen komplexer als dass man das mit 
einem Schieberegister so einfach lösen könnte.

Es befinden sich zwei GALs drauf, die Interrupts und Eingangsmultiplexer 
ansteuern.

Die bessere Karte hat auch schon einen FPGA drauf, die kostet aber auch 
das doppelte.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mal sagen, in dem Falle ist die Karte halt ungeeignet... es 
wird schon seinen Grund haben das die andere Karte teurer ist.

Autor: Daniel A. (insanity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Läubi .. schrieb:
> Ich würde mal sagen, in dem Falle ist die Karte halt ungeeignet... es
> wird schon seinen Grund haben das die andere Karte teurer ist.

Hab mich geirrt, die andere Karte kostet gleich viel, obwohl ein FPGA 
und ein 200kHz 16Bit AD Wandler drauf ist.

Ist schon bestellt und wird hoffentlich auch so schnell laufen.

Die 4A23 funktioniert jedoch auch schon tadellos unter EMC2. Hab wie 
oben geschrieben 2 Threads gemacht, einen langsamen mit 1ms und einen 
schnellen mit 100µs. Hab derzeit noch keinen Realtime delay bekommen, 
die Threads werden also untereinander brav unterbrochen.

Die Daten sind auch immer schön zyklisch alle 5ms verfügbar, weswegen 
die Abfragerate von 1ms auch passt. Bei 16 Kanälen wirds natürlich ganz 
schön langsam (12,5Hz/Kanal), aber ein Sigma-Delta Wandler ist ja eh 
mehr für Genauigkeit als Geschwindigkeit.

Beim Treiber für die 4A23 werd ich noch ein paar Konfigurationen 
implementieren und dann online stellen.

Falls wen interessiert werd ich das hier natürlich auch posten.

Die Anwendung ist nebenbei bemerkt ein Prüfstand für 
Mountainbikekomponenten der mit EMC2 angesteuert wird.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.