1. 程式人生 > >zynq平臺PS端對DDR絕對地址訪問

zynq平臺PS端對DDR絕對地址訪問

當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 = .;
   *(.image
1Section) __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端可以讀取到儲存的資料。
這裡寫圖片描述