IO-Warrior 40 unter Linux einrichten
Moderator: Guido Körber
-
- Posts: 543
- Joined: Mon Dec 01, 2003 6:09 pm
Vielleicht sollte man mal zu lesen anfangen.
Der IO-Warrior meldet sich als zwei Geraete an. In diesem Fall als iowarrior0 und iowarrior1. iowarrior0 ist fuer die IO Pins zustaendig und bei einem IO-Warrior 24 ist der Report einschliesslich ReportID eben nur 3 Byte lang.
Ein IO-Warrior 40 erwartet 5 Byte.
iowarrior1 ist fuer die Special Mode Functinos des IO-Warrior zustaendig und dort werden Reports mit 8 Byte benutzt.
Der IO-Warrior meldet sich als zwei Geraete an. In diesem Fall als iowarrior0 und iowarrior1. iowarrior0 ist fuer die IO Pins zustaendig und bei einem IO-Warrior 24 ist der Report einschliesslich ReportID eben nur 3 Byte lang.
Ein IO-Warrior 40 erwartet 5 Byte.
iowarrior1 ist fuer die Special Mode Functinos des IO-Warrior zustaendig und dort werden Reports mit 8 Byte benutzt.
hast recht, man sollte sich erstmal alles durchlesen, sorry. jetzt klappt´s auch. mit dem beispiel von wayoda und meine überarbeitete version. vielen dank. wenn ich jetzt darauf schreiben will, welche report id muss ich benutzen? habe in dem datasheet nichts darüber gefunden, nur die special funktions sind erklärt!!! danke noch mal.
Zum Thema ReportId:
Die 3 (bzw. 5) Bytes beim lesen von interface0 haben nichts mit ReportID's des IOWarrior zu tun.
Ich erklär das mal kurz am Beispiel des IOWarrior24:
Beim Lesen kann man sich aussuchen ob man 2 oder 3 Byte lesen will.
Bei 2 byte enthält puffer[0] den Zustand von port0, und puffer[1] den Zustand von port1.
Liest man aber 3 bytes erhält man zusätzlich in puffer[2] eine Seriennummer für den gerade gelesenen Zustand, den das Kernel-Modul intern führt.
Das Kernel-Modul verwaltet alle Daten die der IOWarrior liefert in einem eigenen FIFO-Puffer der maximal 16 Werte lang ist.
Die Seriennummer wird für jeden neuen Zustand den der IOWarrior meldet, um 1 erhöht.
(Überlauf bei 256, ist ja nur ein unsigned byte).
Jeder read-Aufruf eines Programms liest nun den Zustand am Kopf des Modul-Puffers.
Produziert der IOWarrior jedoch mehr Daten als von der Applikation gelesen werden, gehen bei einem Überlauf des Puffers Werte verloren.
Anhand der Seriennummer kann man dies überprüfen. Treten hier Lücken auf hat man einige Werte verpasst.
Die gleiche Möglichkeit hat man auch bei interface1 des IOWarrior, hier kann man 9 Byte lesen und erhält dann ebenfalls eine Seriennummer im letzen byte.
Wenn man die Seriennummern nicht braucht, reichen 2 byte (IOWarrior24) , 4 byte (IOWarrior40) für die IO-Pins und 8 byte (Alle IOWarrior) für die SpecialMode-funktionen.
Mit Seriennummer, wie gesagt alle Werte +1.
Jeder Versuch eine andere Anzahl an bytes zu lesen wird vom Modul jedoch abgewiesen (errno == EINVAL).
Eberhard
Leider nicht ganz richtig.Robert Marquard wrote: iowarrior0 ist fuer die IO Pins zustaendig und bei einem IO-Warrior 24 ist der Report einschliesslich ReportID eben nur 3 Byte lang.
Ein IO-Warrior 40 erwartet 5 Byte.
iowarrior1 ist fuer die Special Mode Functinos des IO-Warrior zustaendig und dort werden Reports mit 8 Byte benutzt.
Die 3 (bzw. 5) Bytes beim lesen von interface0 haben nichts mit ReportID's des IOWarrior zu tun.
Ich erklär das mal kurz am Beispiel des IOWarrior24:
Beim Lesen kann man sich aussuchen ob man 2 oder 3 Byte lesen will.
Bei 2 byte enthält puffer[0] den Zustand von port0, und puffer[1] den Zustand von port1.
Liest man aber 3 bytes erhält man zusätzlich in puffer[2] eine Seriennummer für den gerade gelesenen Zustand, den das Kernel-Modul intern führt.
Das Kernel-Modul verwaltet alle Daten die der IOWarrior liefert in einem eigenen FIFO-Puffer der maximal 16 Werte lang ist.
Die Seriennummer wird für jeden neuen Zustand den der IOWarrior meldet, um 1 erhöht.
(Überlauf bei 256, ist ja nur ein unsigned byte).
Jeder read-Aufruf eines Programms liest nun den Zustand am Kopf des Modul-Puffers.
Produziert der IOWarrior jedoch mehr Daten als von der Applikation gelesen werden, gehen bei einem Überlauf des Puffers Werte verloren.
Anhand der Seriennummer kann man dies überprüfen. Treten hier Lücken auf hat man einige Werte verpasst.
Die gleiche Möglichkeit hat man auch bei interface1 des IOWarrior, hier kann man 9 Byte lesen und erhält dann ebenfalls eine Seriennummer im letzen byte.
Wenn man die Seriennummern nicht braucht, reichen 2 byte (IOWarrior24) , 4 byte (IOWarrior40) für die IO-Pins und 8 byte (Alle IOWarrior) für die SpecialMode-funktionen.
Mit Seriennummer, wie gesagt alle Werte +1.
Jeder Versuch eine andere Anzahl an bytes zu lesen wird vom Modul jedoch abgewiesen (errno == EINVAL).
Eberhard
-
- Posts: 543
- Joined: Mon Dec 01, 2003 6:09 pm
Zum Thema schreiben auf den IOWarrior:
Man muß hier also keine Länge für die zu schreibenden Werte angeben.
Der IOWarrior24 holt sich genau 2 bytes aus dem übergebenen Puffer um sie zu den IO-Pins zu schreiben, der IOWarrior40 dementsprechend 4 bytes. Ein ReportId ist nicht nötig, denn das Modul weiss ja, das es sich um IO-Daten handelt wenn man auf interface0 schreibt.
Eberhard
Daten werden per ioctl zum IOWarrior übertragen. Das sieht dann ungefähr so aus:dummbatz wrote: wenn ich jetzt darauf schreiben will, welche report id muss ich benutzen? habe in dem datasheet nichts darüber gefunden, nur die special funktions sind erklärt!
Code: Select all
int retval=-1;
unsigned char puffer[2];
puffer[0]=0xAA;
puffer[1]=0xCC;
if((retval=ioctl(fd,IOW_WRITE,&puffer[0]))<0) {
perror("schreiben fehlgeschlagen");
}
Der IOWarrior24 holt sich genau 2 bytes aus dem übergebenen Puffer um sie zu den IO-Pins zu schreiben, der IOWarrior40 dementsprechend 4 bytes. Ein ReportId ist nicht nötig, denn das Modul weiss ja, das es sich um IO-Daten handelt wenn man auf interface0 schreibt.
Eberhard
es funktioniert alles fantastisch. vielen dank. besonders dank an wayoda-- mein neuer iowarrior idol, haha. danke noch mal. wenn wir schon bei kaffee trasch und klatsch sind, vielleicht habt ihr eine ahnung, wie man die kernelmodule umschreiben muss , damit sie auch mit einem 2.4.xxx kernel funktionieren würden? hat jemand schon so etwas gemacht oder daran gedacht?
make ist ein Programm das so ziemlich auf jedem Linux-System installiert ist.kalleplom wrote:ich kann mir nicht helfen, ich finde kein make im driver verzeichnis.
hat sich das geändert? oder hab ich einfach zu wenig ahnung? :?
Im Fall des IOWarrior-Kernel-Moduls muss man nur eine Console öffnen, in das Treiber-Verzeichniss wechseln und dann make eintippen.
make benutzt dann automatisch die Datei Makefile in diesem Verzeichnis.
Eberhard
naja, das dachte ich mir ja auch schon so. also bin ich ins verzeichnis, habe make eingegeben und ehalte die fehlermeldung:
kann leider nichts mit den meldungen anfangen...
:?
Code: Select all
linux:/src/Kernel_2.6/Driver # make
make -C /lib/modules/2.6.13-15-default/build SUBDIRS=/src/Kernel_2.6/Driver modules
make[1]: Entering directory `/usr/src/linux-2.6.13-15-obj/i386/default'
make[1]: *** Keine Regel, um »modules« zu erstellen. Schluss.
make[1]: Leaving directory `/usr/src/linux-2.6.13-15-obj/i386/default'
make: *** [default] Fehler 2
:?
Die Kernel-Sourcen müssen auch installiert und konfiguriert sein.
Siehe hierzu das Topic :
http://www.codemercs.de/phpBB2/viewtopic.php?t=274
Eberhard
Siehe hierzu das Topic :
http://www.codemercs.de/phpBB2/viewtopic.php?t=274
Eberhard
Wenn /usr/src/linux nicht existiert, sind auch die Kernel-Quellen nicht installiert. Als erst mal per yast die Kernel-Dateien installieren, dann den Kernel konfigurieren, dann den IOWarrior-Driver compilieren.kalleplom wrote:leider habe ich nicht das verzeichnis /usr/src/linux
Die ersten 2 Punkte (Yast/Konfigurieren) sind im Suse-Handbuch beschrieben, was auch mit auf der CD/DVD ist.
Eberhard
Hallo, dieser Thread hat mir sehr geholfen, ich hab nur bei Suse 10.0 kein Verzeihnis /dev/usb gehabt, deshalb brachte das make_nodes bei mir eine Fehlermeldung.
Man muss also, wenn das /dev/usb nicht vorhanden ist, dieses einfach vor der Installation des Treibers kreieren:
mkdir /dev/usb
dann hats bei mir geklappt!
Und wie weiter oben beschrieben das libiowkit.so aus LinuxSDK/Kernel_2.6/iowkit/src/ nach /usr/lib/ kopieren, dann geht auch der Blinklichtblinktest :lol:
Vielleicht hilft es jemand anderem, der dasselbe Problem hat.
EDIT:
Ih hab grad gemerkt, dass das Verzeichnis /dev/usb nach jedem Neustart wieder verschwunden ist.
Man muss also jedesmal das Verzeichnis wieder anlegen und dann nochmal "make_nodes" in LinuxSDK/Kernel_2.6/Driver/ ausführen.
Natürlich wird sich das auch irgendwie dauerhaft anlegen lassen, aber da muss ich erstmal schauen...
Man muss also, wenn das /dev/usb nicht vorhanden ist, dieses einfach vor der Installation des Treibers kreieren:
mkdir /dev/usb
dann hats bei mir geklappt!
Und wie weiter oben beschrieben das libiowkit.so aus LinuxSDK/Kernel_2.6/iowkit/src/ nach /usr/lib/ kopieren, dann geht auch der Blinklichtblinktest :lol:
Vielleicht hilft es jemand anderem, der dasselbe Problem hat.
EDIT:
Ih hab grad gemerkt, dass das Verzeichnis /dev/usb nach jedem Neustart wieder verschwunden ist.
Man muss also jedesmal das Verzeichnis wieder anlegen und dann nochmal "make_nodes" in LinuxSDK/Kernel_2.6/Driver/ ausführen.
Natürlich wird sich das auch irgendwie dauerhaft anlegen lassen, aber da muss ich erstmal schauen...