zynq平台PS端对DDR绝对地址访问
来源:互联网 发布:学云计算用了解嵌入式 编辑:程序博客网 时间:2024/05/22 15:58
当PL端需要通过AXI总线访问DDR时,而PS端同样要访问到DDR,为了实现PL和PS对相同地址访问,可以通过定义变量到绝对地址的方法。
1. 单个变量
当只有一个变量情形下,可以定义一个指向DDR内存中的指针,比如:
int* p=(int*)(0x100000);
2. 数组
对于数组不能用分配指针的方式来分配地址,这样在通过指针写或者读数据时,有可能同其它变量发生冲突。
需要修改linker generator script来定义一个内存空间,将数组定义在这个空间中。http://sourceware.org/binutils/docs/ld/Scripts.html#Scripts
(1)首先定义memory空间
MEMORY{ ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x100000, LENGTH = 0x1FF00000 ps7_qspi_linear_0_S_AXI_BASEADDR : ORIGIN = 0xFC000000, LENGTH = 0x1000000 ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0x0, LENGTH = 0x30000 ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00 HEADMEM_BASEADDR : ORIGIN = 0x20000000, LENGTH = 0x00800000 IMAGE1MEM_BASEADDR : ORIGIN = 0x20800000, LENGTH = 0x00200000 IMAGE2MEM_BASEADDR : ORIGIN = 0x20A00000, LENGTH = 0x00200000 KERNELMEM_BASEADDR : ORIGIN = 0x20C00000, LENGTH = 0x04000000}
其中HEADMEM_BASEADDR ,IMAGE1MEM_BASEADDR ,IMAGE2MEM_BASEADDR ,KERNELMEM_BASEADDR 是我定义的。然后我们在这四个区间中定义section:
SECTIONS{.headSection : { __headSection_start = .; *(.headSection) __headSection_end = .; } > HEADMEM_BASEADDR.image1Section : { __image1Section_start = .; *(.image1Section) __image1Section_end = .; } > IMAGE1MEM_BASEADDR.image2Section : { __image2Section_start = .; *(.image2Section) __image2Section_end = .; } > IMAGE2MEM_BASEADDR.kernelSection : { __kernelSection_start = .; *(.kernelSection) __kernelSection_end = .; } > KERNELMEM_BASEADDR}
然后在C程序中通过attribute属性来定义数组到相应空间中,数组需要时全局变量。
/*data.h*/extern u32 head_info[];extern u32 image1_info[];extern u32 image2_info[];extern u32 kernel_info[];
/*data.c*/#include "data.h"u32 head_info[HEAD_SIZE] __attribute__((section(".headSection")));u32 image1_info[IMAGE_SIZE] __attribute__((section(".image1Section")));u32 image2_info[IMAGE_SIZE] __attribute__((section(".image2Section")));u32 kernel_info[KERNEL_SIZE] __attribute__((section(".kernelSection")));void data_init(){ int k=0; for(int i=0;i<sizeof(head_info);i++){ head_info[i]=k%1024; k++; }}
/*main.c*/#include "data.c"int main(){ data_init();}
然后我们通过AXI总线访问DDR,在PL端可以读取到存储的数据。
阅读全文