[F] SPI-Interrupt auf Raspberry Pi löst nicht aus -> warum?

Gast #4592276
Lesenswert?
• ▲
▼
Hallo,

ich fange an mich mit dem Programmieren eines Device Treibers für Linux 
zu beschäftigen.
Als erstes Projekt zum Üben soll das Modul auf die SPI Hardware eines 
Raspberry Pi (erste Version, Modell B) ansprechen. Bytes ausgeben und 
einlesen geht schon mal. Was nicht geht ist ein Interrupt am Linux 
Kernel (4.1.13) anmelden und von der SPI Hardware auslösen lassen. Ich 
hab den Quelltext des Moduls mal auf das runter gebrochen was minimal 
nötig ist damit der Interrupt ausgelöst werden sollte.

Bitte nicht vom Umfang des Codes abschrecken lassen, die wichtigsten 
Stationen:

Z.267: wird aufgerufen wenn der Treiber eingehängt wird
Init für die SPI-Hardware, hier wird auch der Interrupt beim Kernel 
angemeldet

Z.344: wird beim Start eines Schreibzugriffs auf den Treiber aufgerufen,
Setzt die Clock der SPI Hardware,
aktiviert auch die Interrupts
-> an sich müsste dann gleich ein Interrupt ausgelöst werden

Z.251: "driver_write"
Hier landen die Daten die in den Treiber geschoben werden. Die Daten 
werden aber ignoriert, es wird immer die gleiche Funktion aufgerufen die 
zwei Bytes in den SPI-FIFO schiebt. Diese beiden Bytes werden von der 
SPI Hardware gesendet, diese kann ich auf der Gegenstelle empfangen.

Z.377: Wird aufgerufen wenn der Schreibzugriff zu Ende ist

Z.414: wird beim Entladen des Treiber aufgerufen

Z.454: Das ist die ISR (interrupt service routine) die offensichtlich 
nie aufgerufen wird (keine Daten am SPI-Ausgang und das Status-Wort wird 
auch nicht beschrieben)


Kann man an dem Beispiel sehen was schief läuft? Melde ich den Interrupt 
nicht richtig am Kernel an? Löst die SPI Hardware nie einen Interrupt 
aus weil ich was nicht initialisiert habe?
Leider gibt das Netz nicht viel her zum Thema SPI-Interrupt beim 
Raspberry Pi.
Und der "offizielle" Treiber ist sowas von abstrakt programmiert 
(http://lxr.free-electrons.com/source/drivers/spi/spi-bcm2835.c) dass 
ich nicht erkennen kann was da genau wie initialisiert wird.
Ich persönlich programmiere lieber etwas konkreter, selbst wenn es am 
Ende nicht so portabel ist.
Angehängte Dateien:
(Firma: fritzler-avr.de) #4594498
Lesenswert?
• ▲
▼
Ist denn überhaupt der passende IRQ in den SPI Registern UND beim 
Interrupt Pendingregister freigeschalten? (Kapitel 7 im DB)

Weiterhin kann es sein, dass im Linuxkernel die IRQ Nummer anders ist 
als im Datenblatt, hab ich beim ZYNQ schonmal so erlebt, da warn Offset 
von 32 drauf.
Gast #4595165
Lesenswert?
• ▲
▼
Vielen Dank für den Hinweis, das war der entscheidende Punkt: Die IRQ 
Nummer im Kernel stimmt nicht mit der Hardware-IRQ-Nummer überein. Für 
den Kernel liegt der SPI-Interrupt auf der Nummer 80:

https://nigelborrington.ie/2016/04/27/device-irqs-interrupt-requests-a-definition/

Es ist wohl unsauber das fest im Sourcecode zu codieren weil sich das 
mit einer neuen Kernelversion ändern könnte. Aber es funktioniert jetzt 
und für mich ist das erst mal gut genug um weiter zu machen.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.