Forum: Compiler & IDEs [F] SPI-Interrupt auf Raspberry Pi löst nicht aus -> warum?


von asd (Gast)


Angehängte Dateien:

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.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


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.

von asd (Gast)


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.

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.