Guten Tag, leider bin ich im Umgang mit SoCs noch etwas unerfahren und hänge an einem Problem. Daher würde ich euch gerne um etwas Hilfe bitten. Vielleicht reicht bereits das eine oder andere Schlagwort, um weiter zu kommen. Die Hardware ist ein DE0-nano-SoC. Mit Hilfe des FPGA-Teils möchte ich ADUs und serielle Signale kontinuierlich erfassen. Hierfür sind bereits Schnittstellen implementiert. Die so gewonnenen Daten werden periodisch aus den entsprechenden FIFOs in 16Bit-Register abgelegt. Z.B. ADU1 und SER1. Nun möchte ich aus dem HPS-Teil, auf welchem Linux läuft, unter C++ auf diese Register zugreifen können. Doch deren virtuellen Speicheradressen sind mir(Linux) natürlich unbekannt. Zudem müsste ich vor dem Zugriff verhindern, dass die Register während des Zugriffs durch den FPGA beschrieben werden und somit schreibend den Refresh sperren. Wie kann ich also die Adressen von ADU1 und SER1 identifizieren/festlegen, um hierauf mit dem HPS-Teil lesend und schreibend zugreifen zu können? Läuft diese Kommunikation über die HPS2FPGA / LWHPS2FPGA Brücke? Leider ist das Thema offenbar recht komplex. Könntet Ihr mich daher auf Beispiele verweisen? Mit vielem Dank
Schubert schrieb: > Wie kann ich also die Adressen von ADU1 und SER1 > identifizieren/festlegen, um hierauf mit dem HPS-Teil lesend und > schreibend zugreifen zu können? > > Läuft diese Kommunikation über die HPS2FPGA / LWHPS2FPGA Brücke? Ich gehe mal davon aus das mit dem Platformdesigner zusammen klickst und nich masochistisch händisch von Hand. D.h. du hast für deine FPGA-Cores schon passende hw.tcl Dateien erstellt. Anhand dieser Dateien baut Platform Designer die Adressmap und verschiedene Dateien, u.a. eine .sopcinfo Datei. Daraus generiert man mit sopc2dts einen Device Tree in Source-Form der mit einem weiteren Tool in ein Device Tree Binary kompiliert wird. Dieser wird dann vom Bootloader an den Linuxkernel beim Start übergeben. Ab diesem Zeitpunkt stehen dann Infos wie Namen, Adressen und Interrupts im Kernel zur Verfügung. Ab da geht es am saubersten, aber auch aufwendigsten, mit einem von dir zu schreitenden Kerneltreiber weiter der eine Schnittstelle für dein Userspace Programmm zur Verfügung stellt. Aber es gibt wohl auch Wege wie man aus dem Userspace auf reale Adresse zugreift. Sehr viel Infos dazu gibt es auf https://rocketboards.org/ . Schau dir auch das Referenzdesign (GSRD) an. Das ganze ist ein spannendes Thema aber ein großer Brocken. Wenn es nur um einzelne Register geht ist die LWHPS2Bridge ausreichend . Bei mehr nötigen Durchsatz die normale Bridge aber dann sollte dein Slave auch Features wie Burst unterstützen.
Hallo, vielen Dank für deine Antwort. Naja, den VHDL-Code habe ich schon händisch geschrieben :). Also keine fertigen IP-Cores. Das hatte sich bisher als praktisch erwiesen. Ich verstehe deinen Ansatz, die Ausführung hingegen natürlich noch nicht. Ist eine direkter Verweis zwischen dem programmierten Register und einem Speicheraddressbereich möglich, auch ohne höhere Systemprogramme? Es wird etwa um zehn 16-Bit-Register gehen, die mit max. 100kHz beschrieben werden. Auf einen Trigger hin sollen diese Register vom HPS übernommen und ausgewertet werden. Es fallen somit maximal 16MBit/s an. Einen Kerneltreiber für Linux zu schreiben würde meine Studienarbeit sprengen, da die mit dem SoC gewünschte Funktion nur der Datengewinnung dient. Die eigentliche Arbeit kommt danach... :( Daher muss ich sehen, wie ich aus dem Userspace über den virtuellen Speicheradressbereich zugriff erlange. Ich werde deine Quelle durchstöbern. Vielen Dank für den Hinweis.
Am einfachsten hast du's wohl, wenn du dir in Vivado einen AXI-Lite-Slave generieren lässt und da deinen VHDL-Code dazubastelst. http://www.fpgadeveloper.com/2014/08/creating-a-custom-ip-block-in-vivado.html
Wups, da hab ich wohl zwei Threads vermischt. Sorry.
Ohne Treiber gibt es den Weg über /dev/mem und mmap. Kapitel 11 von https://rocketboards.org/foswiki/Documentation/EmbeddedLinuxBeginnerSGuide hat ein Beispiel.
Samuel C. schrieb: > Am einfachsten hast du's wohl, wenn du dir in Vivado einen > AXI-Lite-Slave generieren lässt und da deinen VHDL-Code dazubastelst. AXI wird auch von Intel/Altera unterstützt aber das native Interface ist Avalon. Ein simpler Avalon-MM Slave ist genauso leicht zu implementieren wie ein AXI-Lite. Aber ich habe den Fragesteller so verstanden dass er das eh schon hat und es ihm um den Zugriff aus Linux raus auf seinen eigenen IP-Core geht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.