Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage Hardware Access auf Embedded Linuxsystemen


von Thomas B. (escamoteur)


Lesenswert?

Hi,

ich versuche immer noch ein Gefühl dafür zu bekommen, wie die 
Entwicklung auf einem Linux-System funtioniert.

Ich habe verstanden, dass ich als Applikation nur über Treiber auf die 
darunterliegende Hardware zugreifen kann. Und dass hierfür nur die 
File-IO-Funktionen und ioctl() zur Verfügung stehen.

Wie mache ich das aber wenn ich meherer Schnittstellen überwachen möchte 
ohne zu pollen, für die ich auf einem µC Interrupthandler einrichten 
würde?

Erzeuge ich für jedes Device einen Thread und lass ihn mit FileRead() 
auf Daten warten?

Oder kann ich vom UserSpace IRQ-Handler registrieren? Gibt es außerhalb 
von Treibern die Möglichkeit auf Phsysikalische Adressen zuzugreifen 
z.B. Register? Unter Windows CE konnte ich mir einen Pointer auf 
Hardware-Adressen geben lassen.


Wäre toll wenn einer von euch mir helfen könnte das Big-Picture zu 
verstehen.


Gruß
Tom

von Max G. (l0wside) Benutzerseite


Lesenswert?

Ohne dein System im Einzelnen zu kennen, ein paar Linux/Unix-Grundlagen:

- Everything is a file. D.h. auch Devices wie GPIOs werden vermutlich 
als virtuelle Datei angelegt.
- Warten auf mehrere Ereignisse geht auch in einem einzelnen Thread (he, 
ich erinnere mich noch an die iX, die irgendwann Ende der Neunziger das 
mit den Threads erklärte - Warten auf mehrere Dateien konnten wir aber 
schon lange vorher). Dafür gibt es select(), das zwar reichlich 
unintuitiv, dafür aber mächtig ist. Wenn dich ioctl() nicht schreckt, 
ist select() kein Thema.
- Was ist FileRead()? Hört sich verdächtig nach Windows an. fget() nimmt 
man da (beispielsweise).

Max

: Bearbeitet durch User
von Martin S. (strubi)


Lesenswert?

Tach,

zum select() könnte man speziell bei Linux den poll() erwähnen. Schenkt 
sich nicht viel zwischen den Beiden, der eine ist POSIX compliant, der 
andere hat eine gewisse Limite (Anzahl Filedeskriptoren) nicht.
Im Prinzip implementierst du auf Treiberseite die poll-Methode, die 
typischerweise die 'wait queue'-Mechanismen benutzt. Dabei weckt der 
IRQ-Handler (den man per Treiber registrieren muss) eine 
WaitQueue-Struktur auf. Das Kernel garantiert damit, dass der Prozess 
schläft, solange er im poll() verharrt und kein Interrupt auftritt.

Die Möglichkeit, auf 'harte' Pointer zuzugreifen, gibt es ansich auch, 
z.B. im video4linux2-Treiber. Aber I/O-Pointerzugriffe sind schon mal 
extrem unsauber, sollte man nur für unike Puffer-Adressen machen. Die 
Adressen werden ebenfalls per ioctl() zwischen Kernel und Userspace 
kommuniziert.
Gefährlich wird's da mit physikalischen Adressen, obiges ist leicht 
unter uClinux (ohne MMU) zu implementieren, bei virtual Memory wirds 
haariger.

Mehrere Threads brauchst du nicht unbedingt, die poll()s oder select() 
kannst du auch in die Mainloop hängen. Ist dann eine Frage nach der Wahl 
des Timeouts, bzw was sonst alles in deiner Mainloop passiert, bzw. auf 
welches Interface du am schnellsten reagieren musst. Bei bestmöglicher 
Antwort-Performance würde man wohl auf verschiedene Threads  oder gar 
Realtime-Erweiterungen setzen, wenn ein Prozess binnen garantierter Zeit 
auf ein Ereignis reagieren muss.

Salute,

- Strubi

von Gästlein (Gast)


Lesenswert?

Das ist vom Kernel alles gut gepuffert.
Und das Handshaking greift ein wenn nötig ...

Also alles recht problemlos

von Gerd E. (robberknight)


Lesenswert?

Thomas Burkhart schrieb:
> Ich habe verstanden, dass ich als Applikation nur über Treiber auf die
> darunterliegende Hardware zugreifen kann.

genau. Der Treiber muss aber nicht unbedingt im Kernel laufen, der 
meiste Teil davon kann auch im Userspace laufen:

http://free-electrons.com/kerneldoc/latest/DocBook/uio-howto/

Allerdings laufen die meisten Treiber die Du unter Linux so findest 
komplett im Kernel da das eine höhere Performance bringt.

> Und dass hierfür nur die
> File-IO-Funktionen und ioctl() zur Verfügung stehen.

Das ist meist das bequemste, aber nicht das einzig mögliche. Du könntest 
Dir z.B. auch Zugriff auf shared memory geben lassen oder vieles andere 
mehr.

> Wie mache ich das aber wenn ich meherer Schnittstellen überwachen möchte
> ohne zu pollen, für die ich auf einem µC Interrupthandler einrichten
> würde?

wie schon geschrieben, über filedescriptoren und poll() oder select().

> Erzeuge ich für jedes Device einen Thread und lass ihn mit FileRead()
> auf Daten warten?

wäre auch ne Möglichkeit. Ob mehrere Tasks, ein Task mit asynchronem IO 
oder ein Task mit mehreren Threads günstiger sind, hängt von der 
Aufgabe, der threadsicherheit und async-Unterstützung Deiner Libs und 
Deiner Erfahrung mit diesen 3 Methoden ab.

> Oder kann ich vom UserSpace IRQ-Handler registrieren? Gibt es außerhalb
> von Treibern die Möglichkeit auf Phsysikalische Adressen zuzugreifen
> z.B. Register? Unter Windows CE konnte ich mir einen Pointer auf
> Hardware-Adressen geben lassen.

Irgendwie könnte man das sicher hinbiegen. Das widerspricht aber so 
manchen sinnvollen Linux-Prinzipien. Über kurz oder lang wird das stabil 
zu bekommen vieeeel aufwendiger als es so zu machen wie unter Linux 
eigentlich vorgesehen (siehe oben).

von Thomas B. (escamoteur)


Lesenswert?

Ich habe in einem Beagleboard Tutorial jetzt gesehen, dass sogar die 
einzelnen Register als Virtuelles File angelegt werden.

Wie groß ist denn die Performance-Einbuße durch den Filezugriff? Wenn 
man vom µC kommt hört sich das ziemlich furchtbar an.

Welche Controlle habe ich über das Buffering dieser Funktionen? Bei den 
GPIOs des Beaglebones muss man anscheinend jedesmal das Fileschließen, 
damit das Signal auch wirklich am IO-Pin anliegt.

Wer kümmert sich um das entprellen von GPIOs? Macht das der Treiber?

von Svenska (Gast)


Lesenswert?

Schau dir mal mmap() an. Damit mappst du eine Datei in deinen virtuellen 
Adressraum und kannst dann darauf zugreifen wie auf normalen Speicher. 
Wenn es dir um schnell und schmutzig geht, dann kannst du mit /dev/mem 
auch direkt auf den physischen Adressraum zugreifen.

Die Performance-Einbußen durch das VFS kannst du getrost ignorieren, die 
geht im Linux unter. Für die Metadaten gibt es zudem Caches.

von Thomas B. (escamoteur)


Lesenswert?

Dank euch, jetzt hab ich einen besseren Überblick!

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.