Forum: PC-Programmierung Parallelport in C ansteuern


von alex (Gast)


Lesenswert?

Hallo,

Ich versuche ebenfalls den Parallelport anzusteuern. Das Port wird
erfolgreich mit CreateFile(...) geöffnet. Wenn ich dann aber
WriteFile(...) aufrufe, hängt sich mein Rechner auf und ich muss die
Anwendung schließen. Mit _outp(...) passiert das selbe.
Muss ich die ganzen Parameter für den Port vorher unbedingt setzen?
Müsste doch so auch funktionieren!

Vielen Dank im Voraus,
Alex

von Jens. (Gast)


Lesenswert?

Hallo, ich hatte damals ein kleines tool geschrieben, was mir die bits
am paralelport toggelt
ich poste hier einfach mal den code:
1
#include <asm/io.h>
2
#include <stdio.h>
3
#include <math.h>
4
#include <unistd.h>
5
#include <stdio.h>
6
#include <unistd.h>
7
8
int main(int argc, char **argv)
9
{
10
        int i;
11
        int n;
12
        int old;
13
        int z;
14
15
        n = atoi(argv[2]);
16
17
        ioperm(0x378, 1, 1);
18
        i = atoi(argv[1]);
19
        old = inb(0x378);
20
21
        ioperm(0x378, 8, 1);
22
23
        if(n != 0)
24
        {
25
                for (z = 0; z < n;  ++z)
26
                {
27
                        if(i == 0)
28
                        {
29
                                outb(5, 0x378);
30
                                usleep(800000);
31
                                outb(6, 0x378);
32
                                usleep(200000);
33
                        }
34
                        if(i == 1)
35
                        {
36
                                outb(9, 0x378);
37
                                usleep(200000);
38
                                outb(10, 0x378);
39
                                usleep(800000);
40
                        }
41
                        if(i == 2)
42
                        {
43
                                old = old | 2;
44
                        }
45
                }
46
                outb(old, 0X378);
47
        }
48
}

ich hoffe du kannst damit etwas anfanngen es laeuft so unter Debian
Linux (2.6er kernel)

Gruss Jens

von Hans (Gast)


Lesenswert?

@jens
nachdem sich das nach windows anhört nehm ich mal an er wird nix mit
linux-code anfangen können... aber den code werd ich mir mal bei zeiten
für ein schönes logic-analyzer-plugin grapschen wenns recht ist ;)

@alex

sag mal welches os du laufen hast und in wie weit das
crasht...bluescreen-crash oder nur "normaler" crash ;)

aja und das was er beim crash sagt wär auch nett.. sofern es kein
"neu-boot"-crash ist g

73

von Jens. (Gast)


Lesenswert?

ggggggggggg
windows der groesste virus =)
hmmh unter windoof kompiliert sollte esauch unter windoof laufen
aber google hat da schon einiges an informationen zu und c ist ja nicht
ungedingt c
ach ja ich hatte es mit GCC kompiliert k/a, in wie weit es gleich mit
windoof ist
gruss

von Rufus T. Firefly (Gast)


Lesenswert?

Unter einem ernstgemeinten* Windows funktioniert der gepostet Code
nicht. Das liegt daran, daß direkte I/O-Operationen vom OS abgefangen
werden, und das aus gutem Grund.

(Mal ganz von den Problemen beim Übersetzen von Codezeilen wie
  outb(5, 0x378);
abgesehen, das mag kaum ein Compiler für Win32 übersetzen)

So etwas lässt sich nur mit Devicetreibern umgehen.

Dabei gibt es zwei Ansätze; mit einem undokumentierten Hack kann ein
Devicetreiber das Abfangen der I/O-Operationen für einen laufenden
Prozess abschalten (das berühmte "giveio.sys" oder "givelpt.sys"),
danach kann, wie unter DOS und vergleichbaren OS-losen Umgebungen
direkt mit I/O-Operationen auf Hardware zugegriffen werden.
Dieser Mechanismus kann mit Tricks sogar dazu verwendet werden, alten
DOS-Programmen den Zugriff auf Hardware zu ermöglichen; ich habe so mal
einen alten Parallelport-EPROMMer unter NT 4.0 zum Laufen gebracht.

Der "sauberere" und portierbarere Weg allerdings ist die Benutzung
eines Treibers, der mit dem betriebssystemeigenen Treiber der
Parallelschnittstelle zusammenarbeitet; oft gehört zum Treiber auch
eine DLL, die für Usermode-Programme die entsprechenden
Zugriffsfunktionen zur Verfügung stellt. Hier ist einer der Vorzüge,
daß das Usermode-Programm sich nicht um die I/O-Adressen der
verwendeten Parallelschnittstelle kümmern muss, weil der OS-eigene
Treiber sich um diese Details kümmert.
Damit ließe sich eine derartige Lösung auch mit nichtstandardisierten
Parallelschnittstellen verwenden, was bei einem direkten I/O-Zugriff
verständlicherweise nicht möglich ist.


*) Windows NT in egal welcher Version (das schließt Windows 2000, XP
und 2003 ein).
95 und seine Aufgüsse 98 und Me scheiden da ebenso aus wie Windows 3.1
...

von Hans (Gast)


Lesenswert?

windows lässt direkte port zugriffe NICHT zu... also so wies sein
sollte...

unter lin dürfte dein code auch nur als root laufen.. und root soll man
nicht sein... => gutes os min so böse und schlecht gemacht wie windows
;)

73

von Jens. (Gast)


Lesenswert?

@Hans

nope man kann ja rechte fuer schnitstellen von hand aendern chmod
/dev/lpt1

oder den user, der es nutzen soll in die passende gruppe setzen

Gruss

von alex (Gast)


Lesenswert?

Ich verwende Windows XP; Das mit dem Crash hab ich etwas dramatisch
beschrieben: Es passiert einfach nichts. Nach dem Funktionsaufruf
bleibt die Anwendung einfach hängen und ich muss sie schließen.

Was ist eigentlich der Unterschied der 2 Versionen von outp:
"outp()" und "_outp()" ???

gruss alex

von Hans (Gast)


Lesenswert?

@jens

dein code dürfte trotzdem nicht rennen...
 ioperm(0x378, 1, 1);
i = atoi(argv[1]);
old = inb(0x378);

das ist nix lpt sonder io !!!!!!! wenn es rennen sollte.. dann werde
ich lieber bei windows bleiben.. weil das wäre ein MEGA sicherheits
loch...

/dev/lpt ist übers file system.. sprich mit fopen ugl. sollte mann dan
arbeiten... unter win wäre das mit createfile und readfile/writefile
möglich....

aber direkte io geht wie rufus so nett vor mir gepostet hat nur über
driver... (es gibt sowas schon als freeware im netz.. siehe anderen lpt
thread hier im forum)

73

von Rolf Magnus (Gast)


Lesenswert?

@Jens
Der Code ist fürchterlich. Dafür braucht man doch wohl root-Zugang.
Nichts für ungut, aber Hardware-Ports direkt anzusprechen ist ja wohl
mehr als veraltet. Warum nimmst du nicht das parport-device? Das ist
viel eleganter, sicherer und nicht am Kernel vorbei. Außerdem
funktioniert es mit jedem Parallelport und nicht nur dem eingebauten
Standardport.

von Martin (Gast)


Lesenswert?

Gibt es ioperm() unter Windows ?
Also Windows oder Linux ?
Wenn Linux dann macht man dass am besten über parport Kernel-Modul
Funktionen. Wenn Interesse besteht kann ich ein Beispiel posten aber
alex sagte doch WindowsXP.

Und ioperm() sollte man höchstens zu versuchszwecken verwenden.

von Hans (Gast)


Lesenswert?

@martin

bitte beispiel an mich mailen ;)

73

von Hans (Gast)


Lesenswert?

solang hab ich mir auf die adresse schon nix mehr schicken lassen g

ein sbox.tugraz muss da stehn bei meiner mail addy ;)

73

von Jens. (Gast)


Lesenswert?

Hey hey das hatte ich mal nebenher gebastelt um etwas zu testen
funktioniert aber mit root rechnen nicht ohne das stimmt
da ich kaum ahnung von c habe und diesen code im netz gefunden und eben
schnell uebrnommen wie gesagt da hatte ich 0 ahnung

von Hans (Gast)


Lesenswert?

ist ja nicht bösgemeint gewesen (zumindest nicht von mir ;)

nix für ungut.. aber schau dir mal den artikel bzgl. ports benutzen
(gcc) an.. oder php.. wobei bei php bin ich noch immer nicht zum code
ummurksn gekommen...

73

von Martin (Gast)


Lesenswert?

@Hans
Ich hoffe die Email ist angekommen

von Hans (Gast)


Lesenswert?

ich auch ;) weil meine testmails an den acc sinds noch nicht...aber ich
hab auch noch keine unzustellbarkeitsmail bekommen....

egal.. wenns icht kommen sollte mail ich dir ...

73

von JojoS (Gast)


Angehängte Dateien:

Lesenswert?

das oft genutzte Giveio.sys funktioniert auch noch Windows XP. Dazu wird
ein Devicetreiber genutzt der dem Prozess die IO Rechte gibt, zur
Nutzung sind also lediglich die CreateFile() und CloseHandle() für
giveio.sys nötig. Der Treiber muss natürlich auch installiert sein, der
ist an vielen Stellen im Web zu finden (z.B. in dem c't Irdeo Projekt).
An das origingal Archiv kommt man nur mit Registierung, einen Mirror
habe ich aber noch hier gefunden :
ftp://ftp.nsk.su/.3/magazins/ddj/1996/1996.05/directio.zip
Im Anhang habe ich eine VisualStudio 7 Solution reingepackt. Wenn man
die CreateFile/CloseHandle Funktionen auskommentiert gibt es eine
Schutzverletzung.  _inp() und _outp() werden mit Unterstrich
geschrieben weil es nicht zum Sprachumfang von C odere in die
Standardlibs gehört (plattformabhängig) und solche Routinen schreibt
man dan üblicherweise mit Unterstrich am Anfang.
Das ist natürlich nicht die eleganteste Lösung auf HW zuzugreifen (z.B.
können andere Rechner auch eine andere Portadresse für LPT1 verwenden),
aber für eine kleine Bastelei die nur auf dem eigenen Rechner laufen
soll wäre ein Device Treiber mit Kanonen auf Spatzen. Diese Lösung hält
sich immerhin schon hartnäckig seit 10 Jahren.
Alternativen wäre vielleicht die USB Schnittstelle,
a) über den IO-Warrior Chip: relativ einfach, allerdings langsames USB
und der Chip ist etwas zu teuer
b) über USB-RS232 Wandler auf einen µC: der µC kann dann schnelle
Vorverarbeitung machen, muss aber extra programmiert werden. Fertige
Boards für diese Lösung gibt es auch reichlich.
c) kommt eben drauf an was man machen will...

von alex (Gast)


Lesenswert?

Vielen Dank JojoS für die Erklärungen und das Beispielprogramm.

Und ein großes Lob ans Forum :-)!!! danke

alex

von alex (Gast)


Lesenswert?

Eine Frage hätte ich aber noch (zum Verständnis):

Im Beispiel wird der Port mit CreatFile() geöffnet, dann mit
CloseHandle() wieder geschlossen und dann erst werden die Daten mit
_outp() gesendet, oder???
Wenn das so stimmen würde, dann könnten doch keine Daten gesendet
werden oder?

mfg alex

von JojoS (Gast)


Lesenswert?

wenn der 'Treiber' geöffnet wird manipuliert er die IO-Permission
Tabelle und macht das beim Close() nicht wieder rückgängig. Deshalb
bleibt die Einstellung für den Prozess bis zum Ende erhalten und man
kann das Close() unkonventionllerweise sofort nach dem Create()
aufrufen. GiveIO ist eben kein richtiger Treiber.

von Michael E. (Gast)


Angehängte Dateien:

Lesenswert?

Hier mein Programm für Linux im Quellcode, welches mit ppdev(parport)
arbeitet.
Es läuft in einem Terminal mit Tastatursteuerung. Man kann die Portbits
einzeln setzen.
ppdev hat denn Vorteil, dass es im Userspace läuft mit normalen
Rechten. Leider wurde es ein ziemlich übler Hack, die ersten Versuche
mit C.

von Niels H. (monarch)


Lesenswert?

Gibt kein ioperm unter windows. Windows ist in der Beziehung etwas
restriktiver. Ein User-Space code kann nicht einfach auf die Hardware
zugreifen. Dafür gibts unter Windows etwas, was Linux von Haus aus
erstmal nicht kennt: eine HAL!

Hier ist eine Funktionslib, die sich beim ersten Aufruf in den Ring0
anmeldet und dann als Systemtreiber funktioniert. Wesentlich sicherer
als giveio.sys.

http://www.geekhideout.com/iodll.shtml

Programmierbar ist das Ganze dann als COM+-Objekt unter jeder
x-beliebigen Programmiersprache. Auch VBA, wenn man wollte.

von uli (Gast)


Lesenswert?

in der MDSN von Microsoft steht irgednwo ein kommplettes codebeispiel
für Serrielle und parrallele Schnittstelle drinnen, ist allerdings in
Basic geschrieben. den code müsste man eigentlich in c++ übersetzen
können da vielle register über den Kernel direkt angeprochen werden.
habe den code leider nicht zur hand, einfach mal googlen oder auf der
mdsn nachschauen.

code funktioniert auf alle fälle mal.

von Niels H. (monarch)


Lesenswert?

Die MicrosoftAPIs bieten i.d.R. keine direkte Kontrolle über die
einzelnen Portregister. Sie bieten nur eine höhere, abstraktere Form
des Zugriffs auf Geräte, die am paralellen Port angeschlossen sind.
Diese sind aber für unsere technischen Spielereien aber nicht zu
gebrauchen.

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
Noch kein Account? Hier anmelden.