[英]Initialize array starting from specific address in memory - C programming
Do you have idea how to initialize array of structs starting from specific address in memory (not virtual, physical DDR memory). 您是否知道如何从内存中的特定地址(非虚拟,物理DDR内存)开始初始化结构数组。 I am working on implementation of TxRx on SoC (ARM-FPGA).
我正致力于在SoC(ARM-FPGA)上实现TxRx。 Basically ARM (PS) and FPGA (PL) communicate to each other by using shared RAM memory.
基本上ARM(PS)和FPGA(PL)通过使用共享RAM存储器相互通信。 Currently I am working on transmitter side, so I need to constantly load packets that I get from MAC layer to memory, then my Tx reads data and sends it in air.
目前我正在处理发送器端,所以我需要不断加载从MAC层到内存的数据包,然后我的Tx读取数据并将其发送到空中。 To achieve this I want to implement circular FIFO buffer on (ARM) side, in way that I can store up to 6 packets into buffer and send them one by one, in same time loading other packets on places of already sent packages.
为了实现这一点,我想在(ARM)端实现循环FIFO缓冲,以便我可以将最多6个数据包存储到缓冲区并逐个发送,同时在已发送的包的位置加载其他数据包。 Because I need to use specific memory addresses I am interested is it possible to initialize array of structure that will be stored on specific addresses in memory.
因为我需要使用特定的内存地址,我感兴趣的是可以初始化将存储在内存中特定地址的结构数组。 For example I want that my array starts at adress 0x400000 and ends at address 0x400000 + MaximumNumberOfPackets x SizeOfPackets I know how to do it for one instantiate of structure for example like this: buffer_t *tmp = (struct buffer_t *)234881024;
例如,我希望我的数组从地址0x400000开始,结束地址0x400000 + MaximumNumberOfPackets x SizeOfPackets我知道如何为结构的一个实例化做这样的事情,例如:buffer_t * tmp =(struct buffer_t *)234881024;
But how to do it for array of structures? 但是如何为结构数组做到这一点?
A pointer to a single struct (or int, float, or anything else) is inherently a pointer to an array of them. 指向单个结构(或int,float或其他任何东西)的指针本质上是指向它们数组的指针。 The pointer type provides the sizeof() value for an array entry, and thus allows pointer arithmetic to work.
指针类型为数组条目提供sizeof()值,从而允许指针算法工作。
Thus, given a struct buffer
you can simply do 因此,给定
struct buffer
您可以简单地做
static struct buffer * const myFIFO = (struct buffer *) 0x40000
and then simply access myFIFO
as an array 然后只需将
myFIFO
作为数组访问
for (size_t i = 0; i < maxPackets; ++i)
{
buffer[i].someField = initialValue1;
buffer[i].someOtherField = 42;
}
This works just the way you expect. 这可以按照您的预期方式工作。
What you can't do (using pure standard C) is declare an array at a particular address like this: 你不能做的(使用纯标准C)是在特定地址声明一个数组,如下所示:
struct buffer myFIFO[23] @ 0x400000;
However, your compiler may have extensions to allow it. 但是,您的编译器可能具有允许它的扩展。 Many embedded compilers do (after all, that's often how they declare memory-mapped device registers), but it will be different for every compiler vendor, and possibly for every chip because it is a vendor extension.
许多嵌入式编译器(毕竟,它们通常是如何声明内存映射设备寄存器),但它对于每个编译器供应商都是不同的,并且可能对于每个芯片都是不同的,因为它是供应商扩展。
GCC does allow it for AVR processors via an attribute, for example 例如,GCC允许通过属性将其用于AVR处理器
volatile int porta __attribute__((address (0x600)));
But it doesn't seem to support it for an ARM. 但它似乎不支持ARM。
Generally @kdopen is right but for arm you should create an entry in MEMORY section linker script that shows to linker where is your memory: 通常@kdopen是正确的,但是对于arm,你应该在MEMORY部分链接器脚本中创建一个条目,向链接器显示你的内存在哪里:
MEMORY
{
...
ExternalDDR (w) : ORIGIN = 0x400000, LENGTH = 4M
}
And than, when you are declaring variable just use the 而且,当你宣布变量时,只需使用
__attribute__((section("ExternalDDR")))
I found the way how to do it. 我找到了怎么做的方法。 So could I do it like this.
我可以这样做吗? I set this into 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 set this into code 然后我将其设置为代码
static buffer_t __attribute__((section("DAC_DMA"))) buf_pool[6];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.