Forum: PC-Programmierung Parallel-/ Lpt-Port ansteuern mit C


von Fabian T. (ftee)


Lesenswert?

Hallo allerseits,

da ich seit einiger Zeit versuche den Parallelport meines Computers 
anzusteuern es aber einfach nicht hinbekomme, frage ich jetzt hier 
direkt nach. Die bereits zu dem Thema verfassten Tips habe ich soweit 
ich sie gefunden habe versucht zu realisieren, bin bisher aber noch 
nicht zu einem Ergebnis gekommen. Mein Manko sind die noch nicht 
vorhandenen C-Kenntnisse.

Betriebssystem: Windows 2000
Programmiersprache: C
Entwicklungsumgebung: Dev-C++
Compiler: Standart Compiler von Dev-C++, soweit ich weiss an gcc 
angelehnt

Die Möglichkeiten die ich bis jetzt sehe sind:
a)zu DOS zurückzukehren (fällt aber raus)
b)mittels Assembler auf die Hardware zugreifen und das irgendwie in mein 
C-Programm integrieren (wäre dieser Weg gangbar? wie bekomme ich dev-c++ 
dazu, dass es die Assemblerbefehle versteht und weitergibt?)
c)einen Treiber verwenden (was für einen, wie kann ich den Treiber 
verwenden? z.B. giveio.sys konnte ich installieren und starten, ein 
einfaches programm mit _outp() konnte aber trotzdem nicht ausgeführt 
werden, Meldung blabla.exe hat Fehler verursacht und wird geschlossen. 
Woran könnte das liegen?)

Gibt es weitere Möglichkeiten?

Viele Grüße

Fabian

edit: _out()=> _outp()

von Stefan E. (sternst)


Lesenswert?


von Matthias (Gast)


Lesenswert?

Ich benutze die "inpout32.dll". Damit hatte ich bisher unter keiner 
Windowsversion Probleme. Selbst auf Vista-Maschinen klappte es bisher 
immer.

http://www.franksteinberg.de/win32bit.htm

http://logix4u.net/Legacy_Ports/Parallel_Port/Inpout32.dll_for_Windows_98/2000/NT/XP.html

von Jörg (Gast)


Lesenswert?

Hallo,

ich verwende für Hardwarezugriff unter Windows32 (XP,2000,.. ausser
Vista) WinIO. Es wird eine komplette Schnittstelle für Port- als auch
Speicherzugriffen mitgeliefert.
_in,_out unter Windows zu verwenden hat immer eine Exception zur Folge,
ohne entsprechende Treiber "no chance"..

Hier der Link (glaube ist der richtige, evtl per google nochmal suchen):

   http://www.internals.com/


Gruss

Jörg

von Fabian T. (ftee)


Lesenswert?

Hallo,
danke für die Antworten.

@sternst
Die Seite zu giveio ist mir bereits bekannt, leider habe ich es trotzdem 
nicht hinbekommen. Vielleicht kannst Du mir weiterhelfen. Die 
Installation des Treibers hat funktioniert und ich konnte den Treiber 
mit dem empfohlenen Tool manuell starten.
Sobald der Treiber gestartet ist müsste ja eigentlich _outp() 
funktionieren, da der Treiber mir die Erlaubnis von Windows holt um den 
Speicher des Parallelport aus einem Programm heraus beschreiben zu 
können. Der Compiler beschwert sich nicht und erstellt die .exe, die 
beim ausführen aber abstürzt, sobald _outp() ausgeführt wird.
Wo steckt hier der Fehler, oder stelle ich mir das zu einfach vor?
Muss ich den Treiber aus dem Programm heraus starten oder sollte auch 
ein manueller start gehen?

@Matthias
bei der inpout32.dll bin ich daran gescheitert den Treiber zu 
installieren und zu starten. Wie machst Du das? Kann ich das mit einem 
externen Tool machen oder wird das direkt aus dem Programm selber 
gemacht?

Zu den anderen Treibern kann ich jetzt noch nichts sagen, muss ich erst 
mal damit herumexperimentieren.

Viele Grüße

Fabian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Sobald der Treiber gestartet ist müsste ja eigentlich _outp()
> funktionieren,

Der Treiber muss auch initialisiert werden, das geschieht mit einem 
einfachen Dateizugriff aus der Applikation heraus, die den Parallelport 
ansprechen will.

Das wird auf der von "sternst" verlinkten Seite beschrieben, hier 
entsprechender Code:
1
int giveio(void)
2
{
3
   OSVERSIONINFO osvi;
4
   int ret = 1;
5
6
   osvi.dwOSVersionInfoSize = sizeof osvi;
7
   GetVersionEx(&osvi);
8
   if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
9
   {
10
      HANDLE h;
11
      h = CreateFileA("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
12
      if (h == INVALID_HANDLE_VALUE)
13
         ret = 0;
14
      else
15
         CloseHandle(h);
16
   }
17
   return ret;
18
}

von Stefan E. (sternst)


Lesenswert?

Ich denke, das Missverständnis besteht darin, dass du denkst, nach dem 
Starten von giveio.sys könne man generell auf Ports zugreifen. Das 
stimmt aber nicht. Dein Programm muss die Erlaubnis explizit anfordern. 
Dafür ist der auf der Seite gezeigte Beispielcode.

von Matthias (Gast)


Lesenswert?

@Fabian

Auf den oben genanten Seiten zur "inpout32.dll" gibts genügend 
Beispiele, wie man die DLL verwendet. Man kann eigentlich kaum was 
falsch machen.

von Fabian T. (ftee)


Lesenswert?

Aha,

dass heißt ich muss aus meinem Programm heraus bei dem Treiber eine 
Erlaubnis anfordern. Das heisst der Treiber muss vcorher installiert und 
gestartet werden. Richtig soweit?

Zu dem geposteten Code: Einfach kopieren und einfügen geht leider nicht, 
der Effekt ist der gleiche wie im vorigen Post beschrieben.
Ich verstehe den Code nicht ganz und habe Kommentare eingefügt. Es wäre 
nett wenn ihr mich auf enthaltene Verständnisfehler hinweist. Ein paar 
dinge sind mir gar nicht klar was sie bedeuten!
1
int giveio(void)
2
{
3
   OSVERSIONINFO osvi;      //Was ist das?
4
   int ret = 1;
5
6
   osvi.dwOSVersionInfoSize = sizeof osvi;   //sizeof osvi liefert z.B. 5.0 für win2k was dann osvi.dwOSVersionInfoSize zugewiesen wird
7
   GetVersionEx(&osvi);
8
   if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)   //was sind osvi.dwPlatformId und VER_PLATFORM_WIN32_NT?
9
   {
10
      HANDLE h;
11
      h = CreateFileA("\\\\.\\giveio", GENERIC_READ, 0, NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);   //eigentliche Anforderung an den Treiber zur Portbenutzung, was ist das für ein Befehl?
12
      if (h == INVALID_HANDLE_VALUE)
13
         ret = 0;
14
      else
15
         CloseHandle(h);
16
   }
17
   return ret;
18
}

Viele Grüße

Fabian


Edit:
@ Matthias
offenbar besteht hier dennoch erklärungsbedarf, sonst hätte ich hier 
nicht nachgefragt. Aber vielleicht liegt es daran, dass ich mich bisher 
noch nicht mit c beschäftigt habe, die Entwicklungsumgebung für mich neu 
ist......

Auf jeden Fall Danke an alle für die Hilfe, vielleicht ist meine Leitung 
ja besonders lang..........

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Code fragt die Betriebssystemversion ab, bevor er die Anmeldung beim 
Devicetreiber durchführt.

Die eigentliche Anmeldung ist das hier
1
      HANDLE h;
2
      h = CreateFileA("\\\\.\\giveio", GENERIC_READ, 0, NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
3
      if (h == INVALID_HANDLE_VALUE)
4
         ret = 0;
5
      else
6
         CloseHandle(h);

Diese Operation ist für die DOS-basierenden Frickelversionen wie Windows 
95, 98 und Me nicht erforderlich.

Wenn Du sicher bist, diesem Murks nie zu begegnen, kannst Du die 
Betriebssystemversionsprüfung auch einfach weglassen.

CreateFile öffnet eine Datei, wo ist hier das Verständisproblem? Der 
Devicetreiber wird dadurch "freigeschaltet", daß eine von ihm zur 
Verfügung gestellte (virtuelle) Datei "angefasst" wird, und genau das 
macht der Code.

von Fabian T. (ftee)


Lesenswert?

Ok,
ich verstehe jetzt wie die Anmeldung beim Treiber erfolgt.
Mir ist allerdings noch nicht ganz klar woher die folgenden Befehle 
stammen: OSVERSIONINFO, HANDLE, CreateFileA
Sind das Befehle die Windows zur Verfügung stellt?

Ist es richtig, dass der Treiber lediglich installiert sein muss damit 
man aus einem Programm auf ihn zugreifen kann?

Was kann dann eigentlich schiefgehen wenn ich den geposteten code 
integriere und danach mit _outp() versuche einen Wert in den Port zu 
schreiben? Hat jemand eine Ahnung wo das Problem liegt? Irgenwas scheint 
da noch im argen zu liegen. Der Code lässt sich kompilieren, sobald ich 
jedoch beim ausführen der .exe zum Befehl _outp() komme verursacht das 
Programm einen Fehler und wird beendet. Bietet bei der Fehlersuche das 
Windows Fehlerprotokoll einen Abhaltspunkt?

Viele Grüße

Fabian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Mir ist allerdings noch nicht ganz klar woher die folgenden Befehle
> stammen: OSVERSIONINFO, HANDLE, CreateFileA

Die ersten beiden sind keine "Befehle", sondern Typdefinitionen. Die 
gehören zur Win32-API und sind in windows.h (resp. einer davon 
eingebundenen Datei) definiert.

CreateFileA ist die ANSI-Version der Win32-API-Funktion CreateFile; Du 
kannst hier getrost das A weglassen, je nach Projekteinstellungen Deines 
Projektes wird automatisch die korrekte Fassung CreateFileA oder 
CreateFileW (das ist die Unicode-Version) verwendet.


> Ist es richtig, dass der Treiber lediglich installiert sein muss
> damit man aus einem Programm auf ihn zugreifen kann?

Ja.

> Was kann dann eigentlich schiefgehen wenn ich den geposteten code
> integriere und danach mit _outp() versuche einen Wert in den Port zu
> schreiben?

Die "aktivierung" des Treibers kann beispielsweise fehlgeschlagen sein, 
so daß das OS nach wie vor direkte I/O-Zugriffe abfängt. Allerdings wird 
dann nicht "ein Fehler" verursacht, sondern eine Fehlermeldung 
ausgegeben, die dies besagt (privileged instruction o.ä.).

Es ist in solchen Fällen immer hilfreich, mehr als "ein Fehler" zu 
schreiben, nämlich welcher Fehler, welche Fehlermeldung.

Wenn Du Dein Programm im Debugger laufen ließest, könntest Du auch 
herausfinden, ob das Problem überhaupt mit _outp() zu tun hat, oder 
nicht vielleicht doch ein ganz anderer Fehler ist.

von Fabian T. (ftee)


Angehängte Dateien:

Lesenswert?

Da mein Programm bisher eigentlich nur den Code zum öffnen des Treibers 
und _outp() enthält kann ich mir nicht vorstellen das mir der Debugger 
da groß weiterhilft.
Ich gehe mal davon aus, dass _outp() das Problem verursacht da es im 
auskommentierten Fall funktioniert.

Die Meldung die beim Ausführen erscheint ist:
"Programmfehler
hello2.exe hat Fehler verursacht und wird geschlossen. Starten Sie das 
Programm neu.
Ein Fehlerprotokoll wird erstellt."
Leider kann ich das Fehlerprotokoll nicht finden.

Woran kann ich erkennen ob die Aktivierung de Treibers erfolgreich war?

Um Missverständnisse vorzubeugen habe ich den Quellcode mal angehängt.


Edit: Fehler über Fehler...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> ... kann ich mir nicht vorstellen das mir der Debugger
> da groß weiterhilft.

Das ist natürlich auch eine Herangehensweise. Versuchs doch mal, auch 
wenn Du es Dir nicht vorstellen kannst. "Vorstellung" ist beim 
Fehlersuchen ähnlich deplaziert wie "Glaube".

> Woran kann ich erkennen ob die Aktivierung de Treibers erfolgreich war?

Du könntest den Rückgabewert Deiner Funktion giveio auswerten.

von Tobi S. (Gast)


Lesenswert?

@ Stefan Ernst, hattest/hast du beim Jesorsky Vorlesung ?
Da du auf seine Site hinweist nehm ich das mal stark an ...
Schön dass hier im Forum Leute von der Ohm unterwegs sind.

von Stefan E. (sternst)


Lesenswert?

Tobi S. wrote:
> @ Stefan Ernst, hattest/hast du beim Jesorsky Vorlesung ?
> Da du auf seine Site hinweist nehm ich das mal stark an ...

Nein, ich muss dich enttäuschen. Ich habe lediglich auf die erstbeste 
Seite mit den nötigen Informationen zu giveio verwiesen, die ich über 
Google finden konnte.

von Fabian T. (ftee)


Lesenswert?

Hallo,

ich habe jetzt mal versucht mit dem Debugger das Problem zu finden. 
Allerdings ist mir nicht ganz klar wie dieser in Dev-c++ funktioniert. 
Es erscheint immer die Meldung "Your Project does not have debugging 
information, do you want to enable debugging and rebuild your project?"
Laut faq muss ich aktivieren, dass der Compiler debug-Informationen 
ausgibt. Nachdem ich diese Option gesetzt habe kann ich mein Programm 
nicht mehr compilieren. Auch nach dem zurücksetzen der option 
(deaktivieren der debug-Informationen) geht nix mehr. Tausende Fehler in 
diversen Dateien wie win***.h von denen ich bisher noch gar nicht wusste 
das es sie gibt.

Weiss jemand woran das liegt und wie dem beizukommen ist?

Viele Grüße

Fabian

von Thomas H. (Gast)


Lesenswert?

Hallo,

ich bin auch gerade am herumtüfteln mit dem Parallelport und ich denke 
du musst anstatt _outp(255, 0x378) _outp(0x378, 255 ) benutzen, da nach 
der Definition die ich gefunden habe zuerst der Port und dann der Wert 
steht:
int _outp(unsigned int portid, int value);

ich hab allerdings das Problem das mein Compiler(Dev-C++) die Funktionen 
_inp() und _output() nicht erkennt hast du vorher noch irgendetwas 
eingebunden oder wo werden die Funktionen bereitgestellt?

Thomas

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.