Initialize an array starting at a specific address in memory - C programming

You have an idea to initialize an array of structures, starting from a specific address in memory (not virtual, physical DDR memory). I am working on implementing TxRx on SoC (ARM-FPGA). Basically, ARM (PS) and FPGA (PL) communicate with each other using shared RAM memory. Currently, I work on the transmitter side, so I need to constantly download the packets that I receive from the MAC layer into memory, then my Tx reads the data and sends it to the air. To do this, I want to implement a ring-side FIFO buffer on the (ARM) side, so that I can store up to 6 packets in the buffer and send them one by one, while loading other packets to the places of the packets already sent. Since I need to use specific memory addresses, I wonder if it is possible to initialize an array of structure that will be stored at specific addresses in memory. For example, I want my array to start at 0x400000 and end at 0x400000 + MaximumNumberOfPackets x SizeOfPackets . I know how to do this for one instance of the structure, for example: buffer_t * tmp = (struct buffer_t *) 234881024;

But how to do this for an array of structures?

+8
c arrays shared-memory
source share
3 answers

A pointer to one structure (or int, float, or something else) is essentially a pointer to an array of them. The pointer type provides the sizeof () value for writing the array, and thus allows you to work with pointer arithmetic.

So with a struct buffer you can just do

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

and then just access myFIFO as an array

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

It works as you expect.

What you cannot do (using the pure C standard) declares an array at a specific address like this:

 struct buffer myFIFO[23] @ 0x400000; 

However, your compiler may have extensions to enable this. Many built-in compilers do (after all, often how they declare memory-mapped device registers), but they will be different for each compiler provider and, possibly, for each chip, as this is a vendor extension.

GCC allows you to use it for AVR processors through an attribute, for example

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

But he does not support it for ARM.

+5
source share

As a rule, @kdopen is right, but for the hand you need to create an entry in the linker of the MEMORY script section, which shows the linker where your memory is:

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

And than, when you declare a variable, just use

 __attribute__((section("ExternalDDR"))) 
+2
source share

I found a way to do this. So I could do it like this. I installed this in the linker script:

 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 

And then I installed this in code

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

All Articles