2015-02-11 5 views
8

Haben Sie eine Idee, wie Array von Strukturen ab einer bestimmten Adresse im Speicher (nicht virtuellen, physischen DDR-Speicher) zu initialisieren. Ich arbeite an der Implementierung von TxRx auf SoC (ARM-FPGA). Grundsätzlich kommunizieren ARM (PS) und FPGA (PL) miteinander, indem sie einen gemeinsamen RAM-Speicher verwenden. Derzeit arbeite ich auf der Senderseite, also muss ich ständig Pakete laden, die ich von der MAC-Schicht in den Speicher bekomme, dann liest mein Tx Daten und sendet sie in Luft. Um dies zu erreichen, möchte ich einen zirkulären FIFO-Puffer auf der (ARM-) Seite implementieren, so dass ich bis zu 6 Pakete in den Puffer speichern und sie einzeln nacheinander senden kann, während andere Pakete auf bereits gesendete Pakete geladen werden. Da ich bestimmte Speicheradressen, die ich interessiere, verwenden muss, ist es möglich, ein Array von Strukturen zu initialisieren, die an bestimmten Adressen im Speicher gespeichert werden. Zum Beispiel möchte ich, dass mein Array an Adresse 0x400000 beginnt und an Adresse 0x400000 + MaximumNumberOfPackets x SizeOfPackets Ich weiß, wie man es für eine Instanz der Struktur zum Beispiel wie folgt macht: buffer_t * tmp = (struct buffer_t *) 234881024;Initialisieren Array von bestimmten Adresse im Speicher - C-Programmierung

Aber wie es für Array von Strukturen zu tun?

+0

Was ist Ihr Compiler & O (falls vorhanden)? –

+0

Hallo, es ist ARM gcc Compiler – elem

+0

Könnte helfen: http://StackOverflow.com/Questions/4067811/How-to-Place-a-Variable-at-Agiven-Absolute-Address-in-Memory-with- gcc –

Antwort

5

Ein Zeiger auf eine einzelne Struktur (oder int, float oder irgendetwas anderes) ist inhärent ein Zeiger auf ein Array von ihnen. Der Zeigertyp stellt den Wert sizeof() für einen Array-Eintrag bereit und ermöglicht so, dass die Zeigerarithmetik funktioniert.

So gegeben ein struct buffer Sie einfach

tun können
static struct buffer * const myFIFO = (struct buffer *) 0x40000 

und dann Zugriff auf einfach myFIFO als Array

for (size_t i = 0; i < maxPackets; ++i) 
{ 
    buffer[i].someField = initialValue1; 
    buffer[i].someOtherField = 42; 
} 

Dies funktioniert genau so, wie Sie es erwarten.

Was Sie nicht tun (unter Verwendung von reinem Standard-C) ist ein Array an einer bestimmten Adresse wie folgt erklären:

struct buffer myFIFO[23] @ 0x400000; 

jedoch Compiler kann Erweiterungen haben es zu ermöglichen. Viele Embedded-Compiler tun das (immerhin deklarieren sie häufig Speicherregister für Speicherkarten), aber es wird für jeden Compiler-Hersteller und möglicherweise für jeden Chip anders sein, da es sich um eine Erweiterung des Herstellers handelt.

GCC macht es für AVR-Prozessoren erlauben über ein Attribut, zum Beispiel

volatile int porta __attribute__((address (0x600))); 

Aber es scheint nicht, es für einen ARM zu unterstützen.

+0

kdopen danke für die antwort Ich werde es so machen. Initialisiere buffer_pool am Anfang und fülle dann für for loop auf. – elem

2

Allgemeinen @kdopen ist richtig, aber für Arm sollten Sie einen Eintrag in dem Speicherabschnitt Linker Skript erstellen, das Linker zeigt, wo Ihr Gedächtnis ist:

MEMORY 
{ 
    ... 
    ExternalDDR (w) : ORIGIN = 0x400000, LENGTH = 4M 
} 

Und als, wenn Sie Variable deklarieren benutzen Sie einfach die

__attribute__((section("ExternalDDR"))) 
+0

Gaskoin Ich bin nicht so erfahren mit Linker-Skripten, aber ich werde versuchen, es sieht interessant aus. Ich werde lernen, wie man Linker-Skripte schreibt. – elem

+0

Ich weiß nicht, wie Sie Ihren Code erstellen, damit ich Ihnen keine Details zur Verfügung stellen kann. Wenn Sie eine dedizierte IDE für Ihren ARM haben, können Sie vielleicht etwas in der Konfiguration finden. Wenn Sie gcc verwenden, sollten Sie irgendwo eine Datei mit der Erweiterung ld haben -> das ist, was Sie brauchen :) – Gaskoin

+0

Sehr geehrte Ich benutze Xilinx SDK, es basiert auf Eclipse. Ich habe den Weg gefunden, wie es geht. Also könnte ich es so machen. Ich habe dies in Linker-Skript: MEMORY { ps7_ddr_0_S_AXI_BASEADDR: ORIGIN = 0x00100000, Länge = 0x1FF00000 ps7_ram_0_S_AXI_BASEADDR: ORIGIN = 0x00000000, Länge = 0x00030000 ps7_ram_1_S_AXI_BASEADDR: ORIGIN = 0xFFFF0000, Länge = 0x0000FE00 DAC_DMA (w): ORIGIN = 0xE000000, LÄNGE = 64K } Und dann habe ich dies in Code gesetzt statisch buffer_t __attribute __ ((Abschnitt ("DAC_DMA"))) buf_pool [6]; – elem

0

Ich fand den Weg, wie es geht. Also könnte ich es so machen.Ich habe dies in Linker-Skript:

MEMORY { 
     ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x00100000, LENGTH = 0x1FF00000   
     ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0x00000000, LENGTH = 0x00030000 
     ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0x0000FE00 
     DAC_DMA (w) : ORIGIN = 0xE000000, LENGTH = 64K 
     } 

.dacdma : { 
    __dacdma_start = .; 
    *(.data) 
    __dacdma_end = .; 
} > DAC_DMA 

Und dann stelle ich dies in Code

static buffer_t __attribute__((section("DAC_DMA"))) buf_pool[6];