当前位置:首页 > > ZYNQ
		


裸机下,读写DDR

测试代码如下:

#include #include "platform.h"#include "xil_printf.h"#include "xil_io.h"#include "xil_mmu.h"  #define TEST_ADDR 0x1F000000  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); //关闭cache   READ_DDR();   u8 value=0x0;   while(1) { READ_DDR(); WRITE_DDR(value++); READ_DDR(); soft_delay(0xfffffff); }   return 0;}


LINUX下,读写DDR

1.涉及到一个工具: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

实验效果如下:

root@zedboard:~# devmem 0x10000000 80xD0root@zedboard:~# devmem 0x10000000 8 0x63root@zedboard:~# devmem 0x10000000 80x63


2.LINUX应用程序调用函数

/* *  ddr read linux application interface */#include #include #include #include #include #include #include #include #include #include #include #include   /*****************************************************************************/#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)  #define MAP_SIZE 4096UL //映射的内存区大小(一般为一个叶框大小)#define MAP_MASK (MAP_SIZE - 1) //MAP_MASK = 0XFFF/*****************************************************************************/  #define TEST_ADDR 0x1F000000  /*****************************************************************************/  /*** @brief 从实际物理地址读取数据。* @details 通过 mmap 映射关系,找到对应的实际物理地址对应的虚拟地址,然后读取数据。* 读取长度,每次最低4字节。* @param[in] readAddr, unsigned long, 需要操作的物理地址。* @param[out] buf,unsigned char *, 读取数据的buf地址。* @param[in] bufLen,unsigned long , buf 参数的容量,4字节为单位,如 unsigned long buf[100],那么最大能接收100个4字节。* 用于避免因为buf容量不足,导致素组越界之类的软件崩溃问题。* @return len,unsigned long, 读取的数据长度,字节为单位。如果读取出错,则返回0,如果正确,则返回对应的长度。*/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 */ //将内核空间映射到用户空间 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++) { // 翻页处理 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); // 将内核空间映射到用户空间操作 buf[i] = *((unsigned long *) virt_addr); // 读取数据 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); // 读取数据 for (i = 0; i < len; i++) { printf("address = 0x%08x, data = 0x%08x\n", (addr + i * 4), readData[i]); }  sleep(1); }}


简单的核间通信

按照《ZYNQ下LINUX+FREERTOS同时运行》这篇文章编译CPU0程序,生成BOOT.BIN文件。运行。

注意要禁止掉cache缓存!如下,0x1F00 0000 是被禁止cache的内存地址,要根据实际情况修改。

Xil_SetTlbAttributes(0x1F000000,0x14de2); //关闭cache

本实验实现了CPU1裸核向DDR写入数据,CPU0 LINUX应用程序读取出刚写入DDR的数据。

实验效果:

CPU1(裸机)效果:

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

文章知识点与官方知识档案匹配,可进一步学习相关知识

https://blog.csdn.net/weixin_41922484/article/details/103700465

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭