Zynq UltraScale Linux A53和裸机 R5共享内存通信

环境

Petalinux2019.1
ubuntu16.04
ZCU106开发板

开始

接着上一篇文章,主要实现一个共享DDR,A53可以读写数据且不被 Linux system Ram占用,裸机也可以读写。
一、开始,修改petalinux config Memory size修改为5fffffff,然后修改设备树,

/include/ "system-conf.dtsi"
/include/ "pl.dtsi"
/ {
	reserved-memory {
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;
		
		reserved: buffer@0 {
			no-map;
			reg = <0x0 0x60000000 0x0 0x20000000>;		
		};	
	};
	reserved-driver@0 {
		compatible = "xlnx,reserved-memory";
      		memory-region = <&reserved>;
   	};
};

&roi_get_axi_dma_0 {
	status = "disabled";
};

&axi_uartlite_0 {
	status = "disabled";
};

注意这里从0x60000000开始,大小是0x20000000,注意后面从0x70000000开始是R5的256M内存地址,不能乱用,只有0x6000000~0x6ffffffff这段256M空间是共享的。
二、我试过直接用dev/mem去读写,结果发现不对,可能因为cache的原因,所以这里直接写驱动,在探测时直接ioremap入下,这样就不会cache了,应该有更好的方法,但我比较菜,不会。。。

	share_mem_dev.mem_start = 0x60000000;//regdata[1];
	share_mem_dev.mem_end = 0x6fffffff;//regdata[1] + regdata[2];
	
	if (!request_mem_region(share_mem_dev.mem_start,
				share_mem_dev.mem_end - share_mem_dev.mem_start + 1,
				DRIVER_NAME)) {
		printk("Couldn't lock memory region at %p\n",
			(void *)share_mem_dev.mem_start);
		//rc = -EBUSY;
	}

	share_mem_dev.base_addr = ioremap(share_mem_dev.mem_start, share_mem_dev.mem_end - share_mem_dev.mem_start + 1);
	if (!share_mem_dev.base_addr) {
		printk("share-mem-drv: Could not allocate iomem\n");
	}
	setup_cdev();
	printk("memstart %x, end %x, vaddr %x\r\n", share_mem_dev.mem_start, share_mem_dev.mem_end, share_mem_dev.base_addr);
	return 0;

然后read、write就是读写了
三、测试
R5程序如下:

for(i = 0; i < 100; i++){
 	   shared_mem_write_int(i, i);
    }

    for(i = 0; i < 100; i++){
 	   if(shared_mem_write_read(i) != i)
 		   xil_printf("mem test err : %d !!\r\n", i);
    }
    xil_printf("shared Mem write finished!! \r\n");
    while(1){
    	Xil_DCacheFlushRange(0x60000000, 0x10000000);
		sleep(2);
    	xil_printf("0x60000000 val %d\r\n", shared_mem_write_read(0));
    	xil_printf("0x60000004 val %d\r\n", shared_mem_write_read(1));
    	xil_printf("0x60000008 val %d\r\n", shared_mem_write_read(2));
    	xil_printf("0x6000000C val %d\r\n", shared_mem_write_read(3));
    }

Linux下程序如下:

int main(int argc, char* argv[])
{
    //char *data = argv[1];
    //if(!data) printf("no data input\r\n");
    int data[100];

    int fd = open("/dev/shared-mem-drv", O_RDWR);
    read(fd, data, 100*4);
    for(int i = 0; i < 20; i++){
        printf("data[%d]: %d\r\n", i , data[i]);
    }
    for(int i = 0; i < 100; i++){
        data[i] = 200 - i;
    }
    write(fd, data, 100*4);

    close(fd);

    return 0;
}

然后开机,成功探测到驱动,Linux端:
在这里插入图片描述
R5端读写测试
Zynq UltraScale Linux A53和裸机 R5共享内存通信_第1张图片
在linux下执行读写测试app:
Zynq UltraScale Linux A53和裸机 R5共享内存通信_第2张图片
此时R5端
Zynq UltraScale Linux A53和裸机 R5共享内存通信_第3张图片

END

你可能感兴趣的:(zynq,ARM)