zynq平臺PS端對DDR絕對地址訪問
阿新 • • 發佈:2018-11-25
當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端可以讀取到儲存的資料。