Paralellport ansteuern + NetBSD

becki

War lange weg....
Hi,
kann mir jemand mal ein HowTo oder Tuturial sagen, in dem ich erfahre, wie ich unter NetBSD den Paralellport in C ansteuern kann? Es geht dadrum, dass ich ein LCD ansteuern will und mir das ganze für eine einfache Textausgabe selbst coden will. Also einfaches standart I/O.
Ich habe schon mehrere Stunden dauergegooglet und durch die Suchfunktion nichts gefunden :mad:
Kann mir da jemand helfen?
Gruß Becki
 
Wenn ich mich nicht irre, was ich heute allerdings bereits mehrfach getan habe, dann ist das Parallelport-Device /dev/lpt0, Deine Freunde zum ansteuern sind:
open(2), read(2), write(2), close(2)

Viel Spass & Erfolg :)
 
spontan wuerde ich sowas vorschlagen:

Code:
#include <stdio.h>

int main(void)
{
   FILE *f;
   f=fopen("/dev/lpt0","a+");
   fprintf(f,"der parallelport funktioniert!!!\n");
   fclose(f);
}
 
Also wie k3rn3lpanic schrieb geht es wohl damit, nur hänge ich mitlerweile daran, was denn nun der file descriptor ist. Sprich muss es vom Typ int oder char sein, etc. Mir würde jetzt ein Codeschnipsel genügen, der aus datei.txt, in der eine Zahl steht, liest, das mit printf ausgibt und die Datei mit einer anderen Zahl überschreibt. Wäre das möglich? Mit fopen() das leuchtet mir nun ein, aber wasist nun der Unterschied zwischen open() und fopen()?
Gruß becki

[edit] und was ich vergaß: wie kann ich damit nun einzellne Pins ansteuern? Denn ich kann ja Bit für Bit ändern, aber welches Bit steht für welchen Pin?[/edit]
 
Wenn Du open benutzt, dann is der Filedescriptor ein int, den Du eben von open bekommst:
Code:
int file = open("/dev/lpt0", O_RDWR | O_EXLOCK, 0);
write(file, mybuffer, 255);
Das wuerde z.B. 255 Bytes aus dem Buffer mybuffer nach /dev/lpt0 schreiben. Mit dem open hast Du lpt0 auf Read/Write geoeffnet und per O_EXLOCK einen exklusiven Lock darauf bekommen, damit Dir keiner, warum auch immer, dazwischenfunkt.
Auf eine if-Abfrage, ob das geklappt hat mit dem Oeffnen hab ich jetzt mal verzichtet, wie sich das realisieren laesst, findest Du in der manpage.

Viel Spass & Freude & Erfolg :D

Edit: Einzelne Pins kanns Du damit nicht ansteuern, Du schiebst einfach was rein, und der Parallelport spuckt es aus.
Die Pinbelegung findet sich dort: http://de.wikipedia.org/wiki/Parallelport#Pinbelegung
 
Oder du inkludierst die asm/io.h und schickst deine Bits mit outb()
direkt an die Adresse des Parallelports (meist 378h).
 
Und wie finde ich die adresse raus?

Aber schonmal vielen dank für die vielen Antworten, mal sehn, was ich draus aachen kann.
 
0815Chaot schrieb:
Sollte normalerweise im dmesg stehen.
Oder direkt im Bios, wo man sie meistens auch ändern kann...

PS. Warum behauptest du, beim Googeln nicht fündig geworden
zu sein? Hier sollte alles drinstehen, was du brauchst :)
 
Zuletzt bearbeitet:
wie ich schon in einem anderen thread schrieb:
du magst den komplizierten weg, hum?

ws ist falsch an dem code den ich dir geschickt habe?
warum willst du am kernel vorbeigehen und nicht auf /dev/lpt0 schreiben?

das habe ich nicht verstanden.
 
Dettus:
Nach dem Quellcode, den du oben gepostet hast, müsste es auch mit
Code:
#> echo "32" > /dev/gerätedatei
funktionieren, oder?

Tut es aber nicht - oder habe ich da was falsch verstanden?
 
Ich will ja jeden Pin einzeln haben.
Dettus: Nach deinem weg könnte es gehn, wenn ich die Daten bitweise in ne int hau und die dann da rein schreibe, aber wie gesagt, das probiere ich nun mal alles aus, die Methode mit outb() sieht da etwas einfacher aus und nciht so fummelig. Naja, ich werd mal deine Lösung und die mit outb() näher ansehn, wie ich es am schönsten machen kann.
@meáigh: Die Seite habe ich echt nicht gefunden, thx
 
Kleine Anmerkung mal noch: Betrifft zwar die serielle Schnittstelle, aber ich hab vor einer Weile mal an einer kleinen Ueberwachungssoftware fuer eine APC-USV gebastelt. Wenn man da die serielle Schnittstelle per fopen geoeffnet und dann mit fwrite etc. geschrieben hat, ging's nicht. Mit open und Konsorten ging es allerdings. Keine Ahnung wieso. Weiss das vielleicht jemand, womit das zusammenhaengt?
 
kein ding:
Code:
#define SETBIT(a,b,c,d,e,f,g,h) (((a&1)<<7)|((b&1)<<6)|((c&1)<<5)|((d&1)<<4)|((e&1)<<3)|((f&1)<<2)|((g&1)<<1)|(h&1))
printf("byte: %i\n",SETBIT(1,1,0,0,0,0,1,0));
printf("byte: %i\n",SETBIT(1,1,0,0,1,0,1,0));

@kernelpanic: bei der seriellen schnittstelle musst du auch noch solche parameter uebergeben, von wegen wie schnell die bits ueber die leitung fliegen sollen.
keine ahnung ob open die (im gegensatz zu fopen) schon automatisch setzt.
 
Zuletzt bearbeitet:
So, nun habe ich einen Code, der mir nen Byte in ne Datei schriebt. Dieses Byte kann ich dank Dettus' letzen Code-Fetzen schön leicht manipulieren. Vielen Dank.
Jetzt habe ich eine letzte Frage: Ich habe die Pinbelegung angesehen und da steht, dass die 8 Output-Pins dem Byte entsprechen, das man an die Basisadresse schickt. Die Frage ist jetzt: Zeigt /dev/lpt0 auf die Basisadresse, so dass ich mein Byte einfach da reinschieben kann? Ich würde jetzt "ja" sagen, aber wollte sicherheitshalber nochmal nachfragen.

Ansonsten ist jetzt alles geklärt, Vielen Dank für die Hilfreichen Antworten!
 
Ich bastele übrigend gerade an der Geschichte mit dem
HD44780-Display, nach der Anleitung, die ich oben ge-
postet habe. Hatte zum Glück noch so ein Display rum-
fliegen, hab allerdings keinen Stecker mehr dür den Pa-
rallelport.....
 
Also, ich habe nun ein Programm, das mir die Daten auf /dev/lpt0 schriebt, nur passiert volgendes beim Ausführen:
Code:
$./code
Also es wird ausgeführt, macht scheinbar nichts. Musst man denn /dev/lpt0 noch irgendwie configurieren, dass so etwas geht?
Hier mal der code:
Code:
#include <stdio.h>
#define SETBIT(a,b,c,d,e,f,g,h) (((a&1)<<7)|((b&1)<<6)|((c&1)<<5)|((d&1)<<4)|((e&1)<<3)|((f&1)<<2)|((g&1)<<1)|(h&1))

int main() {
	FILE *f;
	f = fopen("/dev/lpt","w");
	fprintf(f,"%i\n",SETBIT(1,0,0,0,0,0,0,0));
	fclose(f);
}
(Der Code funtzt, ich kann in ne normale datei dieses bit schreiben)
 
Auch wenn Dettus mich wahrscheinlich jetzt steinigen wird.... ;)
Code:
#include <sys/io.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
 {
 	if(argc != 2)
 	 {
 	 	printf("Benutzung: %s <Wert>\n", argv[0]);
 	 	return;
 	 }
 	 
 	int base = 0x378;
 	int byte = atoi(argv[1]);
 	
 	ioperm(base, 3, 1,);
 	outb(byte, base);
 	ioperm(base, 3, 0);
 	
 	return 1;
 }

Der Nachteil daran: Das Programm benötigt root-Privilegien. Die Hardwareadresse
müsste eigentlich stimmen, überprüfe das vielleicht aber lieber nochmal...

Gruß meáigh
 
@meáigh: lol. aber 0x378 stimmt. 0x3f8 ist com0, 0x2f8 com1.
@becki: ich sehe da im code /dev/lpt statt /dev/lpt0.

was passiert wenn du einfach mal nur
Code:
% cat /dev/random >/dev/lpt0
machst? geht dann deine anzeige?
denk dran, dass du ggf. schreibrechte auf das device brauchst.
und bist du sicher, dass es lpt0 ist? und nicht lpt1?

ein
Code:
% echo "hallo welt" >/dev/lpt0

oft genug wiederholt produziert ein blatt papier mit den passenden woertern auf meinem drucker.
 
Ähm, ja, das /dev/lpt kam,w eil es mit /dev/lpt0 nicht ging als verzweiflungstat. Also das Device passt schon, dessen bin ich mir 100% sicher. Wenn ich versuche, etwas mit echo drauf zu haun, das gleiche. genauso wie ne Zahl mit cat. Rechte habe ich auch genügend.
@meáigh guter Code, nur ohne sys/io.h wirds bei mir nichts. Habe sie noch nicht drauf.
Aber es liegt denke ich am Parallelport oder an was andrem. Oder?
Gruß Becki
 
Ach ja: ich erhallte nach einiger Zeit die Meldung:
Code:
$./code
[1] Segmentation fault (core dumped) ./code
$
 
becki schrieb:
@meáigh guter Code, nur ohne sys/io.h wirds bei mir nichts. Habe sie noch nicht drauf.
Aber es liegt denke ich am Parallelport oder an was andrem. Oder?
Gruß Becki
Probier mal asm/io.h, wie in #7 beschrieben :)

Als ich das Ding mit der asm/io.h kompiliert hab, hat gcc sowas wie "asm/io.h is dep-
ricated, use sys/io.h instead" gemeldet, deswegen im Code eben die andere Variante.
Du hast dann möglicherweise eine ältere Version der glibc....
 
dein code schreibt aber nicht die bits %10000000 an den druckerport, sondern
Code:
00110001 00110010 00111000 00001010
mit dem %i gibst du eine zahl aus. kein einzelnes zeichen, sondern (in diesem fall) 3.
und SETBIT(1,0...) liefert als ergebnis nun einmal 128 zuerueck.
128 besteht aus dem ascii-zeichen 48,49 und 57. danach hast du \n geschrieben, das ist ein line-feed. der ist ascii-zeichen 10.

lpt statt lpt0 zu benutzen ist falsch. er hat jetzt einfach nur eine datei mit dem namen "/dev/lpt" angelegt.

dass du nicht von der konsole aus auf den druckerport zugreifen kannst halte ich schon fuer verdaechtig.

ES KANN ABER AUCH SEIN, dass du im bios fuer den port noch einen anderen modus einstellen musst. guck mal nach, was es dort fuer optionen gibt.
und schick auch nochmal dein dmesg.
 
Zurück
Oben