Forum: PC-Programmierung Linux Treiber, mehrere Devices


von Thomas B. (thomasb)


Lesenswert?

Hallo !

Ich bin gerade dabei die notwendigen Linux-Treiber für ein Bedienpanel 
zu schreiben.
Angesteuert werden hierbei folgende Komponenten:
Ein LCD (SPI, wird als Framebuffer Device eingebunden), und 2 
verschiedene I2C Bausteine zur Steuerung und Kontrolle von LEDs und 
Tasten (MCP23017 Portexpander und ein MCP4725 DAC)

Mein Problem bzw. meine Frage dreht sich jetzt weniger um die 
eigentliche Programmierung der Treiber (die Treiber für die I2C 
Bausteine laufen als "standalone" schon) sondern darum, wie ich diese 
gesamte Bedieneinheit am besten in einem Treiber zusammenführe. (Also 
folgende logische Geräte: Framebuffer, 2 I2C Treiber und zusätzlich noch 
ein Input-Treiber der die Daten von einem der I2C-Bausteinen benötigt)

Wie gehe ich z.B. vor, wenn ich die beiden I2C-Bausteine einrichten will 
? Kann ich da in normal_i2c einfach beide Adressen angeben und dann in 
der probe-Funktion je nach Adresse unterscheiden welche Treiber-Struktur 
dem client übergeben wird ? Ist das eine saubere Lösung ?
Oder wäre es in dem Fall besser die Adresse und den Adapter fix 
vorzugeben, da sich dies ja nicht ändert ? (Wobei ich hier jetzt nicht 
wüsste wie ich an die Adapter-Struktur komme).

Ein kleines "Problem" bei der Implementierung könnte sein, dass der 
Reset für das LCD über einen der beiden I2C-Bausteine geführt wird. D.h. 
bevor ich das LCD und somit den Framebuffer initialisieren kann, muss 
der Treiber für diesen I2C-Baustein schon laufen. (Meine "Sorge" ist 
hierbei, dass der I2C Baustein noch nicht initialisiert ist und der 
Treiberteil fürs LCD ihn schon verwendet, bin mir also nicht sicher ob 
ich das irgendwie synchronisieren sollte/müsste/könnte)

Hat jemand grundsätzlich Vorschläge wie ich das am besten aufbaue ?

Vielen Dank und schöne Grüße,
Thomas B.

: Verschoben durch Admin
von zwieblum (Gast)


Lesenswert?

warum willst du das überhaupt mit einem einzigen treiber erledigen? 
teile und herrsche!

von Thomas P. (Gast)


Lesenswert?

Hey,

ich erschlage das, in dem ich einen misc-treiber drüber setze.
also misc-bedienpanel, dieser greift dann auf i2c, spi zu.

von Thomas B. (thomasb)


Lesenswert?

Hi

@zwieblum
Naja wollen, den Treiber für den MCP4725 könnte ich problemlos als 
einzelnen Treiber realisieren. Aber die Trennung von LCD/Framebuffer, 
MCP23017 und Input-Treiber ist wahrscheinlich nicht so einfach, da ich 
den MCP23017 ja für das LCD bzw. den Framebuffer und den Inputtreiber 
benötige. Zumindest wüsste ich noch nicht wie ich die Trennung hier 
mache.

Kann man überhaupt innerhalb eines Treibers direkt auf einen anderen 
Treiber zugreifen ? Hab dazu in keinem meiner Bücher über 
Treiberprogrammierung etwas gefunden.

@Thomas P.
Ja so hätte ich mir das auch vorgestellt. Wobei ich mir wie gesagt nicht 
sicher bin wie ich da die zwei I2C-Bausteine sauber reinbekomme.


Steige gerade erst so wirklich in die Treiberprogrammierung ein (bisher 
nur kleinere Treiber für einzelne Bausteine), daher fehlt mir leider 
noch etwas der Überblick wie man gewisse Probleme am besten angeht.

Bei der CPU handelt es sich übrigens um einen AT91SAM9261 (erwähne ich, 
weil der Beitrag in den Bereich PC-Programmierung verschoben wurde ;) )

von Markus -. (mrmccrash)


Lesenswert?

Kannst du nicht deinem LCD-Treiber sagen, dass er eine Abhängigkeit von 
dem I2C Treiber hat? modinfo auf der Kommandozeile bringt mir z.b. auch 
eine "depends:" Zeile. Eventuell solltest du dich mal bei den 
Alsa-Treibern umschauen, dort wird viel mit Abhängigkeiten von Modulen 
gearbeitet. (z.b. snd-ice1712 oder snd-emu10k1)

_.-=: MFG :=-._

von Wolfgang Mües (Gast)


Lesenswert?

Hallo Thomas,

Du benutzt natürlich mehrere Treiber. Dabei kannst Du von einem Treiber 
durchaus auf Funktionen eines anderen Treibers zugreifen. Schau mal nach 
EXPORT_SYMBOL. Modprobe kann auch ganze Ketten von Treibern gleichzeitig 
laden.

Wie realisiert man eigentlich einen Framebuffer-Treiber per SPI? Ist das 
nicht ein bisschen langsam, die ganzen Bilddaten über SPI zu übertragen? 
Und wie bekommst Du im Treiber mit, dass der Userspace in den gemappten 
Bildspeicher geschrieben hat?

Ein Framebuffer ist normalerweise der Bildspeicher, der vom 
LCD-Controller periodisch ausgelesen und dargestellt wird.

Gruß

Wolfgang

von Thomas B. (thomasb)


Lesenswert?

@Markus
Danke, die alsa Treiber werd ich mir mal anschaun.

@Wolfgang
EXPORT_SYMBOL könnte genau das sein was ich brauche, werd ich mir mal 
durchlesen, danke !
Also der Framebuffer wird kurz gesagt einfach im RAM angelegt und per 
SPI ans LCD übertragen. Zugriff im User-Space erhalte ich dann über 
mmap. Schau dir mal den Treiber von StefanH an, der hat das für ein S65 
Display gemacht. (Beitrag "Siemens S65 Ls020 Linux Framebuffer")
(Kann hier das Buch Essential Linux Device Drivers empfehlen, da wird 
das auch nett beschrieben)

Schöne Grüße,
Thomas

von Thomas B. (thomasb)


Lesenswert?

Hallo !

Ich habe wieder ein Problem :)

Inzwischen habe ich angefangen, die einzelnen Treiber getrennt zu 
schreiben und die entsprechenden Symbole zu exportieren.
Zusätzlich versuche ich das ganze möglichst "modular" aufzubauen. So 
habe ich z.B. die Funktionen für das sysfs in eine
eigene Datei ausgelagert. Die Funktion zum Einrichten der Attribute 
(z.B. "mcp23017_sysfs_init") exportiere ich dann über EXPORT_SYMBOL.

So weit funktioniert das auch, kompilieren kann ich es ohne Fehler.
Eingebunden hab ich (als Beispiel jetzt für den mcp23017 Treiber) die 
Files im Makefile des Build System mit
obj-$(CONFIG_MCP23017)  += mcp23017.o mcp23017_sysfs.o
Ich erhalte dabei zwei Module (mcp23017.ko und mcp23017_sysfs.ko).

Lade ich das Modul mcp23017.ko so gibt er mir als Fehlermeldung 
"mcp23017: Unknown symbol mcp23017_sysfs_init". Lade ich testweise das 
andere Modul, so erhalte ich die Fehlermeldungungen "module license 
'unspecified' taints kernel" und "Unknown symbol sysfs_create_group". 
Die erste Meldung ist mir prinzipiell klar (keine GPL), verstehe aber 
trotzdem nicht wieso das so ist ( in mcp23017.c habe als Lizenz GPL 
angegeben habe).

D.h. ich kann das mcp23017 Modul nicht starten weil er das Symbol aus 
mcp23017_sysfs nicht findet, und dieses kann ich nicht starten weil es 
sich nicht um eine GPL Lizenz handelt. Habe extra nach Beispielen im 
Kernel-Source gesucht, wo das genauso gemacht wird (z.B. der 
leo-framebuffer treiber, wo gewisse Funktionen in einem eigenen File 
liegen)
Zudem will auch eigentlich gar nicht, dass er mir zwei einzelne Module 
erstellt, die Funktionen in mcp23017_sysfs benötige ich ja nur für das 
mcp23017-Modul.

Wie kann ich das nun lösen ? Programmiere zwar jetzt schon viele Jahre 
in c, aber unter Windows und schönen Entwicklungsumgebungen, daher 
vermute ich mal, dass es sich um einen einfachen Anfänger-, oder 
zumindest um einen Verständnisfehler handelt.

Besten Dank und schöne Grüße,
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.