Hallo liebe Leute, ich habe mal eine Verständnis frage... Ich arbeite gerade mit dem RedPitaya (ein SoC von Xilinx). Das ist ein FPGA kombiniert mit 2 ARM9 Kernen. Zu dem RP gehört ein sogenanntes FPGA Memory Map Register. Das sieht in etwa so aus: 0x00000000 Beginn 0x40000000 House 0x40300000 Oszilloskop oder so... Jetzt beinhaltet das FPGA schon diverse Register und Funktionen, wie im Memory Map beschrieben. Auf dem System läuft ein Linux. In dem Memory Map steht, dass sich an der Adresse 0x40000030 8 LEDs befinden. Jetzt habe ich gelernt, dass die virtuelle Datei /dev/mem den gesamten Arbeitsspeicher des Systems abbildet. Wenn ich diese Datei öffne (open(/dev/mem) kann ich ja mit mmap(4096, , , 0x40000000) einen Pointer auf diese Adresse im Arbeitsspeicher bekommen. Mit einem weiteren offset von 0x30 habe ich tatsächlich Zugriff auf die LEDs. Woher in aller Welt weiß aber mmap() wo die Hardware Adressen von meinem FPGA stehen wenn /dev/mem meinen gesamten Arbeitsspeicher abbildet ??? Ich gebe doch lediglich den offset und die Pagegrösse an. Worauf bezieht sich dieser offset und wo im FPGA steht der ??? Danke schon im voraus Mattias
Bei Zynq ist es so 1) Die hardware wir zusammengebastelt mit Vivado IPI 2) HDF - Hardware Handout File wird exportiert 3) petalinux importiert die HDF und erzeigt device tree source code 4) ... build 5) linux bootet und die treiber holen die addressen von device tree binary Antti igg.me/at/zynq
> Woher in aller Welt weiß aber mmap() wo die Hardware Adressen von > meinem FPGA stehen wenn /dev/mem meinen gesamten Arbeitsspeicher > abbildet ??? mmap weiss gar nix. Was glaubst du gibst du mit dem 0x40000000 an?
Das weiss ich gerade nicht. Mir kommt es so vor,als würden meine Hardware Adressen bei Null beginnen. Deshalb die Frage, wie kann es sein, dass nur der offset ausreicht, um an die richtige Adresse zu kommen ??? Gruss Mattiad
Na ja, dein mmap()-Aufruf mapt den physischen Speicherbereich ab 0x40000000 auf virtuelle Adressen ab 4096 (0x1000). Greifst Du jetzt auf die (virtuelle) Adresse (0x1000 + 0x30) zu, geht der Speicherzugriff auf die physische Adresse 0x40000030 und damit auf dein im FPGA konfiguriertes Register. Klar soweit?
Ich dachte die 4096 ist nur die Grösse, die im Arbeitsspeicher gemappt wird. Die Adresse die mir mmap zurück gibt, ist sehr gross. So ungefähr 0x6B000000. Dann +0x30 komme ich an meine LEDs ran. Woher weiss mein Sytem ,dass Ox40000000 meine Hardware ist ?. Gruss Mattias
address Bereich 0x4000 0000 sind die "custom peripheres" die in FGPA implementiert sind. was da sind ist abhanging welches bitstream geladen ist
> Woher weiss mein Sytem ,dass Ox40000000 meine Hardware ist ?.
Deine Fragen drehen sich im Kreis... Die Basisadresse der HW wird in
irgendeinem SoC-Builder-Tool festgelegt/ausgewürfelt. An der
Schnittstelle CPU zum Rest-FPGA wird das dann auch so konfiguriert, dass
die CPU Zugriffe in dem Bereich auf das externe Interface gibt. Das Tool
schreibt das raus (Device-Tree, #defines, Text-Log, was auch immer) und
wer da "dran" hängt, nimmt das. Wenn du die 0x40000000 beim mmap
angibst, bist du derjenige, der das aus dem Log nimmt. Wenn die
0x30000000 angeben würdest, würde das mmap das auch dumm mappen. Wäre
halt vermutlich nichts sinnvolles dahinter...
Das ist ja eigentlich das schöne am mmap, man kann ohne Treiber und
sonstiges Systemvorkehrungen wild in der HW rumstochern.
:
Bearbeitet durch User
brushless schrieb: > ...Ich dachte... Das ist beim Programmieren immer schlecht. Wissen ist deutlich besser ;). Der erste Parameter bei mmap() ist (zumindest, solange Du nicht bei flags MAP_FIXED spezifizierst) lediglich (d)ein Vorschlag, wo im virtuellen Speicher Du den physikalischen Speicherbereich gerne gemappt hättest. Wenn das System meint, es passe, ist er nachher da (Returnwert) oder eben woanders. Das System weiß nichts von Hardware an Adresse 0x40000000. Das weißt nur Du selbst (hoffentlich) und deshalb gibst Du auch genau die Adresse bei mmap() an. Du solltest Dir klarmachen, daß alle Adressen, die dein Programm sonst so sieht, virtuelle Adressen sind, die die MMU "irgendwo" auf die Hardware mappt. Lediglich der bei mmap() übergebene Offset beschreibt eine physikalische Hardwareadresse. Das ist der einzige Weg (abgesehen davon, einen Kernel-Treiber zu programmieren), an der virtuellen Speicherverwaltung vorbei auf physische Adressen zuzugreifen.
:
Bearbeitet durch User
Hallo Antti, das ist ja mal eine Aussage. Wenn die Adresse 0x4000 0000 wirklich immer fest ist, dann verstehe ich das. Ich habe mich übrigens oben verschrieben. Ich mappe mit mmap(0, Page, , , 0x40000000). Damit kann das BS den Bereich selber festlegen, wo es die Page hinlegt. Jetzt müsste ich nur noch wissen, wo das mit der festen "custom peripheres" steht. Ist das bei dem Zynq immer so ? oder kann man das bei Vivado einstellen ? Gruß Mattias
So, vielen Dank für eure Hilfe, habe es jetzt gefunden. Im "System-Level Address Map" auf Seite 113 im Technical Reference Manual steht das "General Purpose Port #0 to the PL, M_AXI_GP0" von 0x4000 0000 bis 0x7FFF FFFF geht. Gruß Mattias
Wenn ich das richtig sehe, kann man das einstellen. Stellt man's nicht ein, vergibt die Software sinnvolle Defaults. Beim "Dranrumdrehen" wär' ich vorsichtig: schließlich müssen sich ja beide Seiten (FPGA-Config + ARM Kernel) drüber einig sein, wo die Hardware zu finden ist. Wenn der Linux-Kernel z.B. der Ansicht ist, daß da, wo Du Register hinkonfiguriert hast, Memory sein müsste, kracht's.
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.