ZYNQ DDR讀寫(xiě)實(shí)驗(yàn) 與 簡(jiǎn)單的雙核共享內(nèi)存通信(LINUX + BARE METAL)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
裸機(jī)下,讀寫(xiě)DDR
測(cè)試代碼如下:
void WRITE_DDR(u8 ddr_value){ xil_printf("\r\nwrite data\r\n"); u32 addr=TEST_ADDR; u32 i; for(i=0;i<10;i++) { Xil_Out8(addr++,ddr_value); xil_printf("ddr_value=0x%X,",ddr_value); } xil_printf("\r\n");} void READ_DDR(void){ xil_printf("\r\nraed data\r\n"); u32 addr=TEST_ADDR; u32 i; u8 ddr_value; for(i=0;i<10;i++) { ddr_value=Xil_In8(addr++); xil_printf("ddr_value=0x%X,",ddr_value); } xil_printf("\r\n");} void soft_delay(u32 count){ for(;count>0;count--);} int main(){ print("Hello World\n\r"); Xil_SetTlbAttributes(TEST_ADDR,0x14de2); //關(guān)閉cache READ_DDR(); u8 value=0x0; while(1) { READ_DDR(); WRITE_DDR(value++); READ_DDR(); soft_delay(0xfffffff); } return 0;}
LINUX下,讀寫(xiě)DDR
1.涉及到一個(gè)工具:devmem。其用法如下:
root@zedboard:~# devmemBusyBox v1.24.1 (2019-11-28 16:33:01 CST) multi-call binary. Usage: devmem ADDRESS [WIDTH [VALUE]] Read/write from physical address ADDRESS Address to act upon WIDTH Width (8/16/...) VALUE Data to be written
實(shí)驗(yàn)效果如下:
root@zedboard:~# devmem 0x10000000 80xD0root@zedboard:~# devmem 0x10000000 8 0x63root@zedboard:~# devmem 0x10000000 80x63
2.LINUX應(yīng)用程序調(diào)用函數(shù)
/* * ddr read linux application interface */ /*****************************************************************************/ __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0) /*****************************************************************************/ /*****************************************************************************/ /*** @brief 從實(shí)際物理地址讀取數(shù)據(jù)。* @details 通過(guò) mmap 映射關(guān)系,找到對(duì)應(yīng)的實(shí)際物理地址對(duì)應(yīng)的虛擬地址,然后讀取數(shù)據(jù)。* 讀取長(zhǎng)度,每次最低4字節(jié)。* @param[in] readAddr, unsigned long, 需要操作的物理地址。* @param[out] buf,unsigned char *, 讀取數(shù)據(jù)的buf地址。* @param[in] bufLen,unsigned long , buf 參數(shù)的容量,4字節(jié)為單位,如 unsigned long buf[100],那么最大能接收100個(gè)4字節(jié)。* 用于避免因?yàn)閎uf容量不足,導(dǎo)致素組越界之類(lèi)的軟件崩潰問(wèn)題。* @return len,unsigned long, 讀取的數(shù)據(jù)長(zhǎng)度,字節(jié)為單位。如果讀取出錯(cuò),則返回0,如果正確,則返回對(duì)應(yīng)的長(zhǎng)度。*/static int Devmem_Read(unsigned long readAddr, unsigned long* buf, unsigned long len){ int i = 0; int fd,ret; int offset_len = 0; void *map_base, *virt_addr; off_t addr = readAddr; unsigned long littleEndianLength = 0; if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno)); return 0; } /* Map one page */ //將內(nèi)核空間映射到用戶空間 map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK); if(map_base == (void *) -1) { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno)); close(fd); return 0; } for (i = 0; i < len; i++) { // 翻頁(yè)處理 if(offset_len >= MAP_MASK) { offset_len = 0; if(munmap(map_base, MAP_SIZE) == -1) { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno)); close(fd); return 0; } map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK); if(map_base == (void *) -1) { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno)); close(fd); return 0; } } virt_addr = map_base + (addr & MAP_MASK); // 將內(nèi)核空間映射到用戶空間操作 buf[i] = *((unsigned long *) virt_addr); // 讀取數(shù)據(jù) addr += 4; offset_len += 4; } if(munmap(map_base, MAP_SIZE) == -1) { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno)); close(fd); return 0; } close(fd); return i;} /* * test sample */int main(void){ unsigned long len = 2; unsigned long readData[1024*1024]; //1MB unsigned long addr = TEST_ADDR; unsigned long i = 0; while(1) { printf("read data\n"); memset(readData, 0, len); Devmem_Read(addr, readData, len); // 讀取數(shù)據(jù) for (i = 0; i < len; i++) { printf("address = 0x%08x, data = 0x%08x\n", (addr + i * 4), readData[i]); } sleep(1); }}
簡(jiǎn)單的核間通信
按照《ZYNQ下LINUX+FREERTOS同時(shí)運(yùn)行》這篇文章編譯CPU0程序,生成BOOT.BIN文件。運(yùn)行。
注意要禁止掉cache緩存!如下,0x1F00 0000 是被禁止cache的內(nèi)存地址,要根據(jù)實(shí)際情況修改。
Xil_SetTlbAttributes(0x1F000000,0x14de2); //關(guān)閉cache
本實(shí)驗(yàn)實(shí)現(xiàn)了CPU1裸核向DDR寫(xiě)入數(shù)據(jù),CPU0 LINUX應(yīng)用程序讀取出剛寫(xiě)入DDR的數(shù)據(jù)。
實(shí)驗(yàn)效果:
CPU1(裸機(jī))效果:
write dataddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6, raed dataddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6, raed dataddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6,ddr_value=0xC6, write dataddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7, raed dataddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7, raed dataddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7,ddr_value=0xC7, write dataddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8, raed dataddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8, raed dataddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,ddr_value=0xC8,
CPU0(LINUX),DEVMEM工具效果:
root@zedboard:~# devmem 0x1F000000 80xC6root@zedboard:~# devmem 0x1F000000 80xC7root@zedboard:~# devmem 0x1F000000 80xC8root@zedboard:~# devmem 0x1F000000 80xC8root@zedboard:~# devmem 0x1F000000 80xC9
CPU0(LINUX),APP效果:
read dataaddress = 0x1f000000, data = 0xcecececeaddress = 0x1f000004, data = 0xcecececeread dataaddress = 0x1f000000, data = 0xcecececeaddress = 0x1f000004, data = 0xcecececeread dataaddress = 0x1f000000, data = 0xcfcfcfcfaddress = 0x1f000004, data = 0xcfcfcfcf
文章知識(shí)點(diǎn)與官方知識(shí)檔案匹配,可進(jìn)一步學(xué)習(xí)相關(guān)知識(shí)
https://blog.csdn.net/weixin_41922484/article/details/103700465





