LPT-Schnittstelle unter Linux einlesn

Post Reply
Message
Author
Gast

LPT-Schnittstelle unter Linux einlesn

#1 Post by Gast »

hallo erstmal,
ich muß für die schule ein projekt umsetzen und bin jetzt auf ein problem gestoßen bei dem ich ohne fremde hilfe einfach nicht weiterkommen. es geht darum den lpt-port einzulesen. ich habe schon unter dos mit dem von der schule gestellten 16bit c-compiler das programm geschrieben. da gibt es die funktion inportb(). das von mir geschriebene dos-programm läuft ohne probleme und liefert mir immer die aktuellen werte des ports. aber ich brauche ein multitasking-os und am besten nicht windows... :)
meine linux-kentnisse sind allerdings noch nicht so prall (hey, ich kann squid konfigurieien und ein bisschen skripten).
also ich benutze denn gcc und wäre sehr dankbar wenn jemand ein kurzes programm schreiben könnte welches einfach nur den aktuellen wert am lpt.port ausgibt oder in einer variablen speichert. den rest sollte ich dann selber hinbekommen. eine erklärung zum allgemeinem verständnis wäre auch nicht verkehrt...

danke

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#2 Post by jochen »

Hi,

ohne selbst schon mal so was gemscht zu haben, finde ich auf Anhieb mit "parallel port linux programming example" bei google folgende Links:

Etwas höher angesiedelt:
http://people.redhat.com/twaugh/parport ... guide.html
http://www.linuxfocus.org/common/src/ar ... ppdev.html

Ziemlich Lowlevel:
http://www.tldp.org/HOWTO/IO-Port-Programming.html
http://www.epanorama.net/circuits/paral ... rogramming
http://parapin.sourceforge.net/doc/parapin.html

Ich denk mal, dass da was dabei ist...?

Jochen
Die grösste Lüge der EDV? "Mal eben..."

Gast

#3 Post by Gast »

hm...das hilft mir leider nicht wirklich weiter. hier geht es wieder hauptsächlich darum etwas auf dem lpt-port auszugeben. ich möchte allerding etwas einlesen.
mal abgesehen davon habe ich bei google selber schon gesucht. aber wenn jemand noch andere findet ist das natürlich auch nicht schlecht.
wie gesagt, ich bin schüler (schulische ausbildung) und kenne mich nur bedingt mit programmierung aus (structe, pointer, listen). unter dos kam dann einfach noch die funtion inportb() dazu und schon konnte ich lesen und schreiben auf dem lpt-port. gut, unter linux ist das wie unter den aktuellen windows versionen nicht mehr so einfach möglich. ein anderer aus meiner klasse macht sein projekt unter vb mit windows. er braucht lediglich eine dll einzubinden. das kann doch unter linux nicht viel schwerer sein.
das ist doch höchstens ein 10-zeiler sein.
hat nicht vielleicht jemand soetwas schon gemacht.

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

#4 Post by Janka »

Gast wrote:hm...das hilft mir leider nicht wirklich weiter. hier geht es wieder hauptsächlich darum etwas auf dem lpt-port auszugeben. ich möchte allerding etwas einlesen.
Wenn du dich mit der Hardware auskennst, kannst du auch einfach die outb()/inb()-Makros aus <sys/io.h> verwenden. Du musst dann allerdings unbedingt -O2 bzw. höher als Compilerschalter angeben, sonst klappts nicht. :!:

Achja, ioperm() brauchst du auch noch, um die Ports für Benutzerprogramme freizuschalten, sonst kann nur der Kernel drauf zugreifen. Außerdem musst du den parport-Treiber entladen, bzw. so konfigurieren, dass er den einen Port, den du von Hand schalten willst, ignoriert.

Das alles ist aber äußerst unsauber, korrekt wäre es, den parport-Treiber zu benutzen (Der kann auch einlesen). :?

Kannst du mehr Hinweise geben, was du überhaupt ansteuern willst?

Janka

Gast

#5 Post by Gast »

ah...informationen,
das mit den schaltern (-O2 oder höher) ist schonmmal sehr interessant. ich habe schon mit ioperm(), inb(), inp() herumexperminiert. das hat nicht so doll funktioniert. es fehlen mir einfach noch zuviele hintergrundinformationen was linux angeht. leider habe ich nicht die zeit mich wochenlang in die untiefen von linux einzuarbeiten.
naja, und quick und dirty sollte für den anfang reichen. ja ich weiß das das natürlich der falsche ansatz fürn programm ist. der rest wird dann aber auch ganz sauber.
also, mein programm soll den lpt-port ständig auslesen. am lpt-port hängen ein oder später vielleicht auch mehrere "Sensoren". die daten werden dann in einer datei gespeichert. wichtig ist vielleicht noch das die daten sehr schnell sich ändern können da sie seriel übertragen werden.die serielle schnittstelle ist hiefür allerdings ungeeignet oder macht es zumindest nicht leichter. unter dos war das alles mit dem lpt-port für mein programm kein problem.

kann mir nicht vielleicht jemand den fehlenden codeschnippsel zuschantzen. die zeit läuft mir unerbittlich davon.

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

#6 Post by Janka »

Gast wrote:ah...informationen,
das mit den schaltern (-O2 oder höher) ist schonmmal sehr interessant. ich habe schon mit ioperm(), inb(), inp() herumexperminiert. das hat nicht so doll funktioniert. es fehlen mir einfach noch zuviele hintergrundinformationen was linux angeht.
Naja, das stand aber auch in dem Howto http://www.tldp.org/HOWTO/IO-Port-Programming.html, das Jochen empfohlen hat drin.
leider habe ich nicht die zeit mich wochenlang in die untiefen von linux einzuarbeiten. naja, und quick und dirty sollte für den anfang reichen. ja ich weiß das das natürlich der falsche ansatz fürn programm ist. der rest wird dann aber auch ganz sauber.
Hm. So kann das aber langfristig nichts werden. Dreckig+Sauber ---> Dreckig.
also, mein programm soll den lpt-port ständig auslesen. am lpt-port hängen ein oder später vielleicht auch mehrere "Sensoren". die daten werden dann in einer datei gespeichert. wichtig ist vielleicht noch das die daten sehr schnell sich ändern können da sie seriel übertragen werden.die serielle schnittstelle ist hiefür allerdings ungeeignet oder macht es zumindest nicht leichter. unter dos war das alles mit dem lpt-port für mein programm kein problem.
Es gibt für solche Geräte bereits Treiber im Kernel. Einige Gamepads, die man an den Parallelport bzw . Gameport (die Buttonleitungen) anschließen kann funktionieren genau so. Für eine saubere Lösung kannst du dir also die entsprechenden Quellen aus dem Kernel vornehmen.
kann mir nicht vielleicht jemand den fehlenden codeschnippsel zuschantzen. die zeit läuft mir unerbittlich davon.
??? Was willst du noch? Ohne die genaue Ansteuerung zu kennen kann man nichts weiter sagen.

Janka

Gast

#7 Post by Gast »

@ Janka
du hast mit deinen ausfürungen sicherlich recht. allerdings soll dieses programm ja auch nicht in die nächste suse-linux-distibution rein...also was solls.
die ansteuerung selbst (der sensoren) bzw wie ich die daten anschließend auszuwerten habe ist aber nicht das problem. es muß doch möglich sein einfach nur die lesbaren pins des lpt-ports einzulesen. (inportb(0x379) - unter dos ist das nichts weiter)
das ist mein einziges problem (zumindest das einzige was ich hier mit euch besprechen wil :D )
kernel, treiber, gamepads - da setzt es bei mir aus, sorry.

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

#8 Post by Janka »

Gast wrote:@ Janka
es muß doch möglich sein einfach nur die lesbaren pins des lpt-ports einzulesen. (inportb(0x379) - unter dos ist das nichts weiter)
das ist mein einziges problem (zumindest das einzige was ich hier mit euch besprechen wil :D )
kernel, treiber, gamepads - da setzt es bei mir aus, sorry.
Es ist möglich: mittels ioperm() dem Userspace (nur root) die Rechte auf einen IO-Port zu geben, dann kann man mit inb() die Daten auslesen. So wie schon geschrieben.

Allerdings darf halt der parport-Treiber nicht dasselbe tun, sonst gibt es Knatsch. Also musst du lp, parport_pc und parport entladen, sonst funktioniert dein Programm nicht richtig. Und das ist dann trotzdem noch nicht genug, denn damit kann man auf einem zweiten parport dann nicht mehr drucken. Also musst du für diesen Fall parport_pc in /etc/modprobe.conf anweisen, nur den einen Parallelport nicht zu beachten, und dann die Treibermodule wieder laden wieder laden.

Wenn dir das alles nichts sagt, solltest du dich halt schlau lesen (Jochens Links). Ohne Wissen keine funktionsfähige Software.

Janka

Gast

#9 Post by Gast »

der pc hat nur den einen lpt-port und ist auch nur für das projekt gedacht.
na ok, dann probieren wir doch jetzt ein bisschen was handfesteres aus:

Code: Select all

# include <stdio.h>
# include <sys/perm.h>
# include <asm/io.h>
int main &#40;&#41;
&#123;
int rein;
ioperm&#40;0x3BC, 8, 1&#41;; /* port frieschalten &#40;ich weiß nichtmal ob das der richtige ist da ich hier wiedersprüchliche ausagen gelesen habe; was ist mit 0x379; mit dem habe ich es auch schon probiert*/
rein = inb&#40;0x3BC&#41;; //Daten einlesen
printf&#40;"%d",rein&#41;;
ioperm&#40;0x3BC, 8, 0&#41;;//port wieder freigeben 
return 0;
&#125;
so gehts nicht.

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

#10 Post by Janka »

Gast wrote:der pc hat nur den einen lpt-port und ist auch nur für das projekt gedacht.
na ok, dann probieren wir doch jetzt ein bisschen was handfesteres aus:

Code: Select all

# include <stdio.h>
# include <sys/perm.h>
# include <asm/io.h>
int main &#40;&#41;
&#123;
int rein;
ioperm&#40;0x3BC, 8, 1&#41;; /* port frieschalten &#40;ich weiß nichtmal ob das der richtige ist da ich hier wiedersprüchliche ausagen gelesen habe; was ist mit 0x379; mit dem habe ich es auch schon probiert*/
rein = inb&#40;0x3BC&#41;; //Daten einlesen
printf&#40;"%d",rein&#41;;
ioperm&#40;0x3BC, 8, 0&#41;;//port wieder freigeben 
return 0;
&#125;
so gehts nicht.
Was geht nicht: Compilieren, oder ausführen?

Und die Portranges solltest du schon wissen: 0x378,0x379,0x37a ist die Portrange für den ersten Parallelport, der zweite hat 0x278 etc.

Es sei denn, du hast eine Herculeskarte im Rechner, da ist der erste Port dann 0x3bc,0x3bd,0x3be, und 0x378.. der zweite etc.

Dann sollte man <sys/io.h> statt <asm/io.h> einbinden. Letzteres ist ein Include für die Kernelseite. <sys/perm.h> braucht man gar nicht.
Den Port vor dem Programmende "freigeben" brauchst du auch nicht. ioperm gilt nur für den laufenden Prozess.

Außerdem natürlich mit -O2 compilieren, und nur root darf das Ding ausführen. Und parport_pc muss rmmod'ed werden, damit er nicht reinpfuscht.

Gegenvorschlag:

Code: Select all

#include <stdio.h>
#include <sys/io.h>

int main &#40;&#41;
&#123;
  int rein;

  ioperm&#40;0x378,3,1&#41;;
  rein=inb&#40;0x379&#41;;
  printf&#40;"%d\n",rein&#41;;

  return 0;
&#125;
Janka

Gast

#11 Post by Gast »

wie gesagt, zu den portranges finde ich verschiedene angaben. also ich habe einen ganz normalen pc. bisschen alt, 166 mhz. der lpt ist auf dem mainboard.

wenn ich was über den lpt lesen will muß ich da nicht 0x379 verwenden?
mit 0x378 erreicht man doch den "daten-ausgang". (?)

"rmmod parport_pc" - was hat es damit auf sich? war das der druckertreiber? was muß ich mit dem machen? bzw was macht rmmod? ich hab hier keine möglichkeit mit "man" zu arbeiten. das ist so ein mini-linux. gcc hab ich nachträglich installiert und sonst habe ich nur die konsole.
vielleicht bekomme ich deswegen ne seite fehlermeldungen...
"first defined here" kommt mehrmals vor in "/usr/lib/crt*.o"
"multiple definition of '_init' " (_start und _fini)
und soweiter und sofort.

ich hätte ja gerne die komplette fehlermeldung gepostet, aber ich kann auf dem system die fehlermeldung nicht in eine datei umlenken. nichtmal "more" scheint es zu geben.

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

#12 Post by Janka »

Gast wrote:wie gesagt, zu den portranges finde ich verschiedene angaben. also ich habe einen ganz normalen pc. bisschen alt, 166 mhz. der lpt ist auf dem mainboard.

wenn ich was über den lpt lesen will muß ich da nicht 0x379 verwenden?
mit 0x378 erreicht man doch den "daten-ausgang". (?)
Ja, an Index 0 liegt das Ausgangsregister, an Index 1 das Eingangsregister (das bei sehr alten Rechnern übrigens nur die Eingänge zurücklesen kann, wenn man zuvor 0xff in das Ausgangsregister geschrieben hat), an Index 2 das Steuerregister, mit dem man die BUSY- und ACK-Leitungen vom Drucker abfragen und die Interrupts freigeben kann.

Wenn du genaueres Wissen musst, solltest du aber mal nach "parport hardware" suchen.
"rmmod parport_pc" - was hat es damit auf sich? war das der druckertreiber?
Nein, lp ist der Druckertreiber, parport_pc ist der parport-Treiber für PC-Hardware. parport ist der generische Unterbau dafür.

Das ist deswegen so aufgeteilt, weil Linux ja auch auf anderer als PC-Hardware läuft, und weil man an den Parport ja nicht nur Drucker anschließen kann.

was muß ich mit dem machen? bzw was macht rmmod? ich hab hier keine möglichkeit mit "man" zu arbeiten. das ist so ein mini-linux. gcc hab ich nachträglich installiert und sonst habe ich nur die konsole.
vielleicht bekomme ich deswegen ne seite fehlermeldungen...
"first defined here" kommt mehrmals vor in "/usr/lib/crt*.o"
"multiple definition of '_init' " (_start und _fini)
und soweiter und sofort.

ich hätte ja gerne die komplette fehlermeldung gepostet, aber ich kann auf dem system die fehlermeldung nicht in eine datei umlenken. nichtmal "more" scheint es zu geben.
Hm. Wie wäre es, wenn du deine Versuche auf einem Rechner fährst, der sich komfortabler bedienen lässt? Wenn du da nichts installieren darfst, kannst du ja immer noch Knoppix o.ä. nehmen.

Janka

j

j

#13 Post by j »

jochen wrote:Hi,

ohne selbst schon mal so was gemscht zu haben, finde ich auf Anhieb mit "parallel port linux programming example" bei google folgende Links:

Etwas höher angesiedelt:
http://people.redhat.com/twaugh/parport ... guide.html
http://www.linuxfocus.org/common/src/ar ... ppdev.html

Ziemlich Lowlevel:
http://www.tldp.org/HOWTO/IO-Port-Programming.html
http://www.epanorama.net/circuits/paral ... rogramming
http://parapin.sourceforge.net/doc/parapin.html

Ich denk mal, dass da was dabei ist...?

Jochen

Post Reply