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
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/research/linux/measure/tsc.pdf 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.
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.
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
>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.
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.
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.
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.
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?
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.
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.
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.