zynq平台PS端对DDR绝对地址访问

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/anpingbo/article/details/78901620

当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端可以读取到存储的数据。
这里写图片描述

猜你喜欢

转载自blog.csdn.net/anpingbo/article/details/78901620