Forum: PC-Programmierung LinuxTreiberEntwicklung Userspace-Kernelspace-Treiber


von Markus R. (mark989)


Lesenswert?

Hallo alle zusammen,

ich bin gerade dabei einen Netzwerktreiber für das Raspberry Pi zu 
schreiben. Als NIC benutze ich einen Profinet fähigen Chip der über SPI 
mit dem RPi kommunizieren soll. D.h. genauso wie beim enc28j60 soll mein 
Netzwerkinterface über SPI realisiert werden.

Mein Anliegen:

Ich habe auf dem RPi folgenden SPI Treiber installiert:
http://www.brianhensley.net/2012/07/getting-spi-working-on-raspberry-pi.html

Da es sich hier um einen Userspace Treiber handelt, frage ich mich: kann 
ich einfach einen Netzwerktreiber(Kernelspace) schreiben, der den obigen 
SPI-Treiber(Userspace) benutzt???
Heißt ich kopiere einfach alle Includes/Felder/Funktionen/... in meinen 
Netzwerktreiber!
Funktioniert dieser Ansatz ??
Danke für jede Hilfe

Gruß Markus

von Andreas B. (andreas_b77)


Lesenswert?

Wieso soll es sich da um einen Userspace-Treiber handeln? Auf der 
verlinkten Seite wird doch anscheinend ein Kernel-Treiber demonstriert.

von Markus R. (mark989)


Lesenswert?

Sorry hab ich vergessen zu schreiben.
Es wird dort gezeigt wie der SPI Treiber installiert wird,  und wie er 
benutzt wird,
siehe Bespiel spidev_test.c.
Ist es jetzt möglich die Vorgehensweise aus dem Beispiel(spidev_test.c) 
in meinen Netzwerktreiber einzubauen? Oder muss die SPI Funktionalität 
wie bei dem enc28j60
(http://lxr.free-electrons.com/source/drivers/net/ethernet/microchip/enc28j60.c)
selbst implementiert werden??

von Andreas B. (andreas_b77)


Lesenswert?

Dort wird gezeigt, wie man Debian installiert und ein Firmware Update 
macht, soweit ich das sehen kann. Ein Treiber wird da nicht installiert, 
der ist offensichtlich schon Teil des Kernels.

Markus R. schrieb:
> Ist es jetzt möglich die Vorgehensweise aus dem Beispiel(spidev_test.c)
> in meinen Netzwerktreiber einzubauen?

Nein, spidev_test.c ist nur ein Beispiel aus der Linux Dokumentation, 
wie man aus dem Userspace auf einen SPI-Treiber zugreift.

> Oder muss die SPI Funktionalität
> wie bei dem enc28j60
> (http://lxr.free-electrons.com/source/drivers/net/e...)
> selbst implementiert werden??

Dieser Treiber ist ein praktisches Beispiel, wie ein Kernel-Treiber auf 
einen SPI-Treiber zugreift. Da wird nichts "selbst implementiert". In 
den Linux Sourcen ist die Beschreibung in Documentation/spi/spi-summary 
für diesen Fall interessant (How do I write an "SPI Protocol Driver").

von Markus R. (mark989)


Lesenswert?

Vielen Dank!!!

Da werde ich mich gleich ma dranhängen.

Gruß Markus

von Markus R. (mark989)


Lesenswert?

Im Abschnitt "How do I write an "SPI Protocol Driver" wird lediglich 
demonstriert wie der struct spi_driver CHIP_driver={...}  und die 
probe-Funktion aussieht, etwas knapp wie ich finde um einen Treiber zu 
schreiben. Ich habe zunächst jetzt erstmal nach vorhandenen Treibern 
gesucht und diese dann mit dem RPi ausprobiert. Dabei bin ich hierdrauf 
gestoßen:
http://elk.informatik.fh-augsburg.de/pub/elinux/ngw100/AVR32743/spi/spi_example.c
Lässt sich auch fehlerfrei kompilieren und in den Kernel als Modul 
einbinden. Dann habe ich MISO und MOSI verbunden um einen Loopback zu 
probieren. Problem ist jetzt dass die probe-Funktion nie aufgerufen 
wird. Kann es sein das ich etwas in der Board-Datei 
(arch/arm/mach-bcm2708/bcm2708.c) modifizieren muss ??? Was hat das mit 
dem modalias auf sich?
In der Beschreibung dieses Treibers steht jedenfalls davon:
(http://www.atmel.com/Images/doc32098.pdf)
Ich frage mich nur warum ich jetzt noch einmal die Module kompilieren 
muss da es doch auch schon vorher im Userspace mit spidev_test.c 
funktioniert hat..

Gruß

von Markus R. (mark989)


Lesenswert?

Jemand eine Idee??

von Andreas B. (andreas_b77)


Lesenswert?

Markus R. schrieb:
> Im Abschnitt "How do I write an "SPI Protocol Driver" wird lediglich
> demonstriert wie der struct spi_driver CHIP_driver={...}  und die
> probe-Funktion aussieht, etwas knapp wie ich finde um einen Treiber zu
> schreiben.

Ich habe nur mal auf die Stelle hingewiesen, die mir relevant schien. 
Selber habe ich mit SPI in Linux nicht so viel Erfahrung. Also 
vielleicht noch den Rest von spi-summary anschauen. Natürlich beschreibt 
das dort auch nur die SPI spezifischen Dinge, wie man einen Treiber 
allgemein programmiert sollte man da schon wissen.

Markus R. schrieb:
> Kann es sein das ich etwas in der Board-Datei
> (arch/arm/mach-bcm2708/bcm2708.c) modifizieren muss ???

Auf jeden Fall bei der traditionellen Methode. SPI bietet im Gegensatz 
etwa zu PCIe oder USB keine automatische Erkennung angeschlossener 
Geräte, also muss diese Information im Initialisierungscode eingebaut 
werden. Auch das ist im spi-summary Dokument beschrieben.

Die nicht-traditionelle Methode ist, das in einer Flattened Device Tree 
Datei außerhalb des Kernels einzutragen und so die 
Hardware-Konfiguration separat vom Kernel zu halten. Damit kenne ich 
mich jetzt aber noch weniger aus.

von Hans Ulli K. (Gast)


Lesenswert?

Hallo Markus R.

Warum möchten alle Leute die WELT neu erfinden ??

Nimm doch einfach den Treiber in
drivers/net/ethernet/microchip/enc28j60.c
und passe ihn an deine Bedürfnisse an (inkl. neuer Dateiname !)

Und einen Userspace Treiber für eine Kernelfunktion zu schreiben, der 
quasi als Mittler zwischen dem SPI-Kerneltreiber und den Netdevice 
"Interface" des Kernels sitzt ist an sich ja schön braindead

Du mußt in dem ja zweimal die Schranke Kernel-Userspace überspreiten, 
was ernorm Performance kostet.

von Markus R. (mark989)


Lesenswert?

Ok hab den Kernel einmal mit der Änderung in bcm2708.c kompiliert, es 
funkioniert!
Danke;)!! Muss ich jetzt jedes mal wenn ich zB. die Taktrate der 
Übertragung ändern will den kompletten Kernel neu kompilieren?? Es muss 
doch irgendwie einfacher gehen..

von imonbln (Gast)


Lesenswert?

Markus R. schrieb:
> Ok hab den Kernel einmal mit der Änderung in bcm2708.c kompiliert, es
> funkioniert!
> Danke;)!! Muss ich jetzt jedes mal wenn ich zB. die Taktrate der
> Übertragung ändern will den kompletten Kernel neu kompilieren?? Es muss
> doch irgendwie einfacher gehen..

klar, da gibt es mittel und wege,
Mach ein Modul daraus dann musst du nur das Kompilieren ausserdem gibt 
es Interfaces wie das procfs und das sysfs um mit laufenden modulen zu 
Kommunizieren. Es gehen auch Modulparameter (kann man auch beim booten 
setzten) oder ioctls aber letzters gilt als veraltet.

von Markus R. (mark989)


Lesenswert?

imonbln schrieb:
> Mach ein Modul daraus dann musst du nur das Kompilieren ausserdem gibt
> es Interfaces wie das procfs und das sysfs um mit laufenden modulen zu
> Kommunizieren. Es gehen auch Modulparameter (kann man auch beim booten
> setzten) oder ioctls aber letzters gilt als veraltet.

Ich mache es als Modul, nur muss ich laut:
https://www.kernel.org/doc/Documentation/spi/spi-summary
den name des Moduls in bcm2708.c registrieren(dort wird als Beispiel der 
Namen "Chip" gewählt). Das funkt ja auch, nur ist es lässtig bei jeder 
Taktratenveränderung neu zu kompilieren. Wie genau läuft das mit 
Modulparameter?

Hans Ulli Kroll schrieb:
> Nimm doch einfach den Treiber in
> drivers/net/ethernet/microchip/enc28j60.c
> und passe ihn an deine Bedürfnisse an (inkl. neuer Dateiname !)

Genau das habe ich vor, es muss aber erstma die basic SPI-Kommunikation 
funktionieren.

von Georg A. (georga)


Lesenswert?

> Wie genau läuft das mit Modulparameter?

Such mal nach MODULE_PARAM in anderen Treibersourcen... Ist eigentlich 
nur eine Zeile, die auf eine Modul-statische Variable verweist.

Es gäbe auch die Möglichkeit, das on-the-fly übers sysfs (ex procfs) zu 
ändern, also ala "echo 10 > /sys/bus/spi/...". Dazu muss man aber 
einiges mehr machen. Dafür kann man darüber auch Debugging erledigen, 
die sys-Files lassen sich ja auch auslesen.

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.