2015-02-11 11 views
8

Hai idea di come inizializzare la matrice di strutture a partire da un indirizzo specifico in memoria (non una memoria DDR fisica virtuale). Sto lavorando all'implementazione di TxRx su SoC (ARM-FPGA). Fondamentalmente ARM (PS) e FPGA (PL) comunicano tra loro usando la memoria RAM condivisa. Attualmente sto lavorando sul lato trasmettitore, quindi ho bisogno di caricare costantemente i pacchetti che ottengo dallo strato MAC alla memoria, quindi il mio Tx legge i dati e li invia in aria. Per raggiungere questo obiettivo, voglio implementare il buffer circolare FIFO sul lato (ARM), in modo da poter memorizzare fino a 6 pacchetti nel buffer e inviarli uno per uno, caricando nello stesso tempo altri pacchetti su posizioni di pacchetti già inviati. Perché ho bisogno di utilizzare specifici indirizzi di memoria che mi interessa è possibile inizializzare array di strutture che verranno memorizzate su specifici indirizzi in memoria. Ad esempio, desidero che il mio array inizi all'indirizzo 0x400000 e termini all'indirizzo 0x400000 + MaximumNumberOfPackets x SizeOfPackets So come farlo per una istanza di struttura ad esempio in questo modo: buffer_t * tmp = (struct buffer_t *) 234881024;Inizializza array a partire da un indirizzo specifico in memoria - Programmazione C

Ma come si fa per una serie di strutture?

+0

Qual è il suo compilatore e sistema operativo (se del caso)? –

+0

Ciao, è il compilatore ARM gcc – elem

+0

Potrebbe aiutare: http://stackoverflow.com/questions/4067811/how-to-place-a-variable-at-a-given-absolute-ad-ress-in-memory-with- gcc –

risposta

5

Un puntatore a una singola struttura (o int, float o qualsiasi altra cosa) è intrinsecamente un puntatore a un array di essi. Il tipo di puntatore fornisce il valore sizeof() per una voce dell'array e quindi consente all'aritmetica del puntatore di funzionare.

Quindi, dato un struct buffer si può semplicemente fare

static struct buffer * const myFIFO = (struct buffer *) 0x40000 

e poi semplicemente accedere myFIFO come un array

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

Questo funziona solo nel modo previsto.

Quello che non può fare (usando puro di serie C) è dichiarare un array ad un indirizzo particolare come questo:

struct buffer myFIFO[23] @ 0x400000; 

Tuttavia, il compilatore può hanno estensioni per permetterlo. Molti compilatori incorporati (dopotutto, è spesso il modo in cui dichiarano i registri di dispositivi mappati in memoria), ma sarà diverso per ogni produttore di compilatori, e probabilmente per ogni chip perché è un'estensione del venditore.

GCC fa consentirgli di processori AVR mediante un attributo, ad esempio

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

Ma non sembra sostenerlo per un ARM.

+0

kdopen grazie per la risposta Lo farò così. Inizializza buffer_pool all'inizio e quindi riempi il ciclo for. – elem

2

Generalmente @kdopen è giusto, ma per il braccio è necessario creare una voce nel MEMORIA script del linker sezione che mostra al linker dove è la memoria:

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

e poi, quando si dichiara variabile basta utilizzare il

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

Gaskoin Non sono così esperto con gli script di linker, ma cercherò di farlo sembrare interessante. Imparerò a sapere come scrivere script di linker. – elem

+0

Non so come si costruisce il codice, quindi non posso fornire alcun dettaglio. Se hai IDE dedicato per il tuo ARM forse puoi trovare qualcosa nella configurazione. Se stai usando gcc dovresti avere da qualche parte un file con estensione ld -> questo è quello che ti serve :) – Gaskoin

+0

Caro Sto usando Xilinx SDK, è basato su eclipse. Ho trovato il modo in cui farlo. Quindi potrei farlo in questo modo. Ho impostato questo in script del linker: MEMORIA { ps7_ddr_0_S_AXI_BASEADDR: ORIGINE = 0x00100000, LUNGHEZZA = 0x1FF00000 ps7_ram_0_S_AXI_BASEADDR: ORIGINE = 0x00000000, LUNGHEZZA = 0x00030000 ps7_ram_1_S_AXI_BASEADDR: ORIGINE = 0xFFFF0000, LUNGHEZZA = 0x0000FE00 DAC_DMA (w): ORIGINE = 0xE000000, LENGTH = 64K } E poi l'ho impostato in codice static buffer_t __attribute __ ((section ("DAC_DMA"))) buf_pool [6]; – elem

0

Ho trovato il modo di farlo. Quindi potrei farlo in questo modo.Ho impostato questo in script del linker:

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 

E poi ho impostato questo in codice

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