Ich muss einen Interrupt von meinem benutzerdefinierten FPGA-IP-Kern an das HPS-System eines DE0_nano_SoC (Cyclone V HPS-FPGA-Architektur) weitergeben und unter Linux verarbeiten. Ich habe ziemlich viel gegoogelt, um mit Zuversicht sagen zu können, dass dieses Thema nicht gut behandelt wird.
Erforderliche Funktionalität
Der benutzerdefinierte FPGA-IP-Core setzt ein Interrupt-Signal. Das HPS registriert dieses Signal ( schreibt möglicherweise in den benutzerdefinierten FPGA-IP-Kern, um das Unterbrechungssignal zu deaktivieren) und kopiert einige Bytes aus Registern im FPGA in ein Programm, das unter Linux ausgeführt wird.
Die Wahl von Linux ist willkürlich, vorzugsweise Angstrom/Yocto, das ich gerade am Laufen habe, aber wenn das FreeRTOS eine einfachere Implementierung bieten würde, würde ich es wählen.
Meine Annahmen (bitte korrigieren Sie mich, wenn falsch)
1) Der Interrupt-Controller im HPS erkennt die vom FPGA generierten Interrupts ab der Nummer 73 (es gibt einige Verschiebungen, aber sie werden im Prinzip mit konstanten Werten abgebildet).
2) Linux für ARM Cortex A9, kann herstellerspezifische Interrupts erkennen (für verschiedene Peripheriegeräte wie I2C0/1/2, UART0/1 usw.).
Frage
1) Erkennt Linux die vom HPS Interrupt Controller abgebildeten Interrupts vom FPGA?
2) Muss ich einen Treiber entwickeln, damit Linux die FPGA-Interrupts erkennen kann?
3) Dies scheint ein ziemlich wichtiges Merkmal der gesamten Cyclone V-Architektur zu sein. Hat Altera solche Treiber nicht bereits entwickelt, um einfache FPGA-zu-HPS-Interrupts unter Linux zu handhaben?
Die HPS-Brücke ist so konzipiert, dass sie FPGA-Interrupts entgegennimmt und sie in den General Interrupt Controller (GIC) im ARM-Prozessor einspeist. Soweit es den Prozessor betrifft, unterscheiden sich Interrupts vom FPGA nicht von Interrupts aus anderen Quellen. Genau wie die I2C- oder UART-Peripheriegeräte rufen FPGA-Interrupts dieselbe Antwort im GIC auf.
Der Linux-Kernel wurde bereits für den jeweiligen Prozessor und Interrupt-Controller angepasst. Der Kernel weiß bereits, wie er auf einen Interrupt reagieren muss – er führt einfach einen beliebigen Interrupt-Handler (ISR) aus, der vom Kernel eingerichtet wurde, um einen bestimmten Interrupt zu behandeln. Im Falle einer Interrupt-Quelle, die keinen eingerichteten Handler hat, wird sie wahrscheinlich einen Standard-Handler haben, der den Interrupt stillschweigend beseitigt (wahrscheinlich indem er ihn einfach ignoriert).
Wie gehen Sie damit um? Genauso wird jeder andere Interrupt gehandhabt - ein Treiber. Sie müssen einen Code, Treibersoftware, bereitstellen, der einen Interrupt-Handler für die spezifische Interrupt-Quelle registriert. Zum Beispiel gibt es bereits Treiber für die I2C- und UART-Peripherie, diese werden Interrupt-Handler haben.
Es gibt viele nützliche Dokumente im Internet zum Umgang mit Treibern, eine schnelle Google-Suche hat dies gefunden, was ziemlich gut erscheint. Von dort aus können wir sehen, dass alle Interrupts eine Nummer haben, deren Handler durch Ausführen des Befehls angezeigt werden können cat /proc/interrupts
. In Ihrem Fall sehen Sie für Interrupt Nummer 73 (den ersten FPGA-Interrupt) nichts, da kein Treiber dafür eingerichtet ist.
TL;DR; Sie müssen einen Linux-Treiber schreiben. Da der Interrupt vom FPGA kommt, muss nichts Besonderes beachtet werden, das bereits hardwareseitig von der HPS-Bridge erledigt wird.
Mitu Raj
Tom Tischler