您是否知道如何从内存中的特定地址(非虚拟,物理DDR内存)开始初始化结构数组。我正致力于在SoC(ARM-FPGA)上实现TxRx。基本上ARM(PS)和FPGA(PL)通过使用共享RAM存储器相互通信。目前我正在处理发送器端,所以我需要不断加载从MAC层到内存的数据包,然后我的Tx读取数据并将其发送到空中。为了实现这一点,我想在(ARM)端实现循环FIFO缓冲,以便我可以将最多6个数据包存储到缓冲区并逐个发送,同时在已发送的包的位置加载其他数据包。因为我需要使用特定的内存地址,我感兴趣的是可以初始化将存储在内存中特定地址的结构数组。 例如,我希望我的数组从地址0x400000开始,到地址0x400000结束+ MaximumNumberOfPackets x SizeOfPackets 我知道如何为结构的一个实例化执行此操作,例如: buffer_t * tmp =(struct buffer_t *)234881024;
但是如何为结构数组做到这一点?
答案 0 :(得分:6)
指向单个结构(或int,float或其他任何东西)的指针本质上是指向它们数组的指针。指针类型为数组条目提供sizeof()值,从而允许指针算法工作。
因此,给定struct buffer
你可以简单地做
static struct buffer * const myFIFO = (struct buffer *) 0x40000
然后只需将myFIFO
作为数组
for (size_t i = 0; i < maxPackets; ++i)
{
buffer[i].someField = initialValue1;
buffer[i].someOtherField = 42;
}
这就像你期望的那样。
你不能做什么(使用纯标准C)是在特定地址声明一个数组,如下所示:
struct buffer myFIFO[23] @ 0x400000;
但是,您的编译器可能具有允许它的扩展名。许多嵌入式编译器(毕竟,它们通常是如何声明内存映射设备寄存器),但对于每个编译器供应商而言都是不同的,并且可能对于每个芯片都是不同的,因为它是供应商扩展。
GCC允许通过属性将其用于AVR处理器,例如
volatile int porta __attribute__((address (0x600)));
但它似乎不支持ARM。
答案 1 :(得分:2)
一般来说@kdopen是正确的,但是对于arm,你应该在MEMORY部分链接器脚本中创建一个条目,向链接器显示你的内存:
MEMORY
{
...
ExternalDDR (w) : ORIGIN = 0x400000, LENGTH = 4M
}
而且,当您声明变量时,只需使用
__attribute__((section("ExternalDDR")))
答案 2 :(得分:1)
我找到了怎么做的方法。我可以这样做吗?我将其设置为链接器脚本:
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
然后我将其设置为代码
static buffer_t __attribute__((section("DAC_DMA"))) buf_pool[6];