Forum: PC-Programmierung Hilfe bei Linux Treiber-Modul Programmierung


von Thomas N. (thomas_n89)


Lesenswert?

Hallo allezusammen,

ich schreibe gerade einen Treiber für mein Pandaboard (Ubuntu 12.04) und 
habe damit ein kleines Problem...

Der Treiber soll die Daten einlesen (bzw. beschrieben werden), verändern 
(Parity usw hinzufügen) und dann an die SPI Schnittstelle des 
Pandaboards weitergeben. Ich habe ein Programm geschrieben, welches alle 
Funktionen beinhaltet und auch die SPI schnittstelle mit den Systemcalls 
(open, ioctl usw) ansprechen kann.
Ich habe ebenfalls einen Treiber programmiert, der Daten aufnehmen und 
wieder ausgeben kann.

Nun will ich die beiden Komponenten zusammenfügen - und schon kann ich 
das Modul nicht mehr erstellen.

Als Fehler beim kompilieren erhalte ich für jeden Systemcall ein "error: 
implicit declaration of function 'open'/'write'/'ioctl'..."
Laut Google erscheint der Fehler, wenn headerfiles fehlen - Ich hab 
jedoch genau die gleichen verwendet, wie bei dem funktionierenden 
Programmm.

Kennt sich jemand mit Treiberprogrammierung aus? Ich bin mir überhaupt 
nicht sicher, ob ich in Treibermodulen andere Devices öffnen kann.

Fachliteratur hilft mir bis jetzt auch nicht weiter, weil in allen 
Büchern nicht über so "aufgesetzte" Treiber gesprochen wird...

Kann hier jemand helfen oder kennt ein Forum, wo sich mit sowas 
beschäftigt wird?

Danke :)

von Tom M. (Gast)


Lesenswert?

Thomas N. schrieb:
> Als Fehler beim kompilieren erhalte ich für jeden Systemcall ein "error:
> implicit declaration of function 'open'/'write'/'ioctl'..."

Was meinst du mit "Treiber", ein Kernel Modul?

Wenn ja, wirst du darin wahrscheinlich keine Funktionen der libc 
verwenden können, sondern musst auf das kernel interface zurück greifen. 
Gibt es für deine Kernel-Major-Release kein "kernel module writing 
how-to"?

von Andreas B. (andreas_b77)


Lesenswert?

Thomas N. schrieb:
> Kennt sich jemand mit Treiberprogrammierung aus? Ich bin mir überhaupt
> nicht sicher, ob ich in Treibermodulen andere Devices öffnen kann.

Nein, geht nicht.

Wozu das alles? Willst du nicht vielleicht in Wirklichkeit eine Library 
statt eines Kernel-Moduls schreiben?

von hp-freund (Gast)


Lesenswert?

Tom M. schrieb:
> kernel module writing how-to

Stimmt. Ich hatte mich vor Jahren auch mal daran versucht. Eine 
Anleitung wie z.B. diese:

http://www.freesoftwaremagazine.com/articles/drivers_linux

machen die Sache bedeutend einfacher.

von Thomas N. (thomas_n89)


Lesenswert?

Erstmal Danke für die schnelle Antworten!

Der Hintergedanke ist folgender: Ich nutze ein Programm mit gegebenem(!) 
Output. Ich kann nur das Gerät auswählen, auf welches geschrieben werden 
soll. Diese Ausgabe leite ich auf meinen eigenen Treiber um, der die 
Daten anpassen soll und dann über SPI an einen uC mit eigener Hardware 
weierreicht.

Ich simuliere dh. eine Hardware, die ich selbst nachgebaut habe. Aus 
diesem Grund ist der eigene Treiber unerlässlich, der auch 
statusanfragen usw. abfängt und nur die Nutzdaten wirklich weitergibt. 
Diese Daten wollte ich dann per SPI (über einen devspi standardtreiber) 
weiterleiten...

Muss ich jetzt die SPI schnittstelle aus dem kernel herausansprechen? 
Ich dachte ich könnte einfach alle Daten vom kernelspace in den 
userspace verschieben und dann weitergeben.

von Peter II (Gast)


Lesenswert?

Thomas N. schrieb:
> Ich simuliere dh. eine Hardware, die ich selbst nachgebaut habe. Aus
> diesem Grund ist der eigene Treiber unerlässlich, der auch
> statusanfragen usw. abfängt und nur die Nutzdaten wirklich weitergibt.

das ist die Frage, eventuell tut es auch schon eine Pipe. Die kann von 
jeden Programm und nicht nur vom einem Treiber angelegt werden.

von Andreas B. (andreas_b77)


Lesenswert?

Und wenn eine Pipe nicht ausreicht (weil mehr als nur write() gemacht 
wird) gibt es mehrere Möglichkeiten:

– Mit FUSE (Filesystem in User Space) lassen sich anscheinend auch 
Character Devices emulieren. Hat den Vorteil, dass man wie ein normales 
Programm (was es auch ist) auf die Kernel-Schnittstellen zugreifen kann 
und außerdem eine größere Auswahl an Programmiersprachen hat (eine 
Anbindung an libfuse gibt es z.B. auch für Python).

– Man kann eine Shared Library schreiben, die per Umgebungsvariable 
LD_PRELOAD vor allen anderen geladen wird und Aufrufe in die libc 
abfängt. Dann implementiert man ein open(), das etwas spezielles macht, 
wenn die Device-Datei geöffnet wird und bei anderen Dateinamen einfach 
die open()-Implementierung der libc aufruft. Dann ein write(), ioctl(), 
… die spezielle Sachen machen wenn sie mit dem speziellen 
Dateideskriptor aufgerufen werden und sonst den Aufruf an die libc 
weiterleiten. Das ist ein wenig kompliziert.

– Wenn es doch ein Kernel-Modul sein soll, muss auf die internen 
Schnittstellen der SPI-Treiber zugegriffen werden (weiß grad nicht, was 
es da gibt) statt den Device-Dateien.

– Am besten wäre es, das Programm selbst anzupassen, aber das scheint ja 
keine Option zu sein.

von Thomas N. (thomas_n89)


Lesenswert?

Danke für die schnelle und ausführliche Antwort! Leider ist das Problem 
nicht so trivial wie ich dachte.


Andreas B. schrieb:
> Und wenn eine Pipe nicht ausreicht (weil mehr als nur write() gemacht
> wird) gibt es mehrere Möglichkeiten:
>

Ich brauche leider ioctl für bidirektionales schreiben...

> – Mit FUSE (Filesystem in User Space) lassen sich anscheinend auch
> Character Devices emulieren. Hat den Vorteil, dass man wie ein normales
> Programm (was es auch ist) auf die Kernel-Schnittstellen zugreifen kann
> und außerdem eine größere Auswahl an Programmiersprachen hat (eine
> Anbindung an libfuse gibt es z.B. auch für Python).
>

Klingt interressant - habe davon bis jetzt auch noch nichts gehört.

> – Man kann eine Shared Library schreiben, die per Umgebungsvariable
> LD_PRELOAD vor allen anderen geladen wird und Aufrufe in die libc
> abfängt. Dann implementiert man ein open(), das etwas spezielles macht,
> wenn die Device-Datei geöffnet wird und bei anderen Dateinamen einfach
> die open()-Implementierung der libc aufruft. Dann ein write(), ioctl(),
> … die spezielle Sachen machen wenn sie mit dem speziellen
> Dateideskriptor aufgerufen werden und sonst den Aufruf an die libc
> weiterleiten. Das ist ein wenig kompliziert.
>

Übersteigt -soweit ich das sehe- meine horizont

> – Wenn es doch ein Kernel-Modul sein soll, muss auf die internen
> Schnittstellen der SPI-Treiber zugegriffen werden (weiß grad nicht, was
> es da gibt) statt den Device-Dateien.
>

Ich überlege gerade den Standard devspi linux treiber zu nehmen und 
diesen dann einfach umzuschreiben. Kosten ein bisschen einarbeitungszeit 
- sollte aber machbar sein

> – Am besten wäre es, das Programm selbst anzupassen, aber das scheint ja
> keine Option zu sein.

Geht leider (erstmal) nicht.

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.