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

27 篇文章 8 订阅

环境

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端读写测试
在这里插入图片描述
在linux下执行读写测试app:
在这里插入图片描述
此时R5端
在这里插入图片描述

END

对于ZynqZynq Ultrascale的选型,首先需要考虑项目的需求和性能要求。Zynq是Xilinx推出的一款SoC(片上系统),主要特点是集成了ARM处理器和FPGA。而Zynq Ultrascale是Zynq的进一步升级版,采用了更先进的Ultrascale架构。 在选型时,首先要考虑的是项目的性能需求。如果项目对性能要求较高,需要更高的处理能力和计算性能,那么Zynq Ultrascale可能更适合。它采用了先进的架构和更高的时钟频率,可以提供更好的性能和计算能力。 其次,还需要考虑系统的功耗和成本。通常来说,Zynq相对来说功耗相对较低,适用于低功耗应用,而Zynq Ultrascale的功耗可能较高一些。此外,Zynq Ultrascale作为升级版,价格可能更高,因此在成本方面也需要考虑。 然后,还需要根据项目的特殊要求来选择。如果项目对接口和外设的需求较高,那么需要查看ZynqZynq Ultrascale所支持的接口类型和数量,以及外设资源的分配情况。不同型号可能在接口和外设方面有所差异,需要根据具体情况进行选择。 最后,还需要考虑对开发工具和生态系统的支持需求。ZynqZynq Ultrascale都有相应的开发工具和生态系统支持,但可能有差异。需要考虑项目开发团队的熟悉程度以及所需的技术支持,选择适合的型号。 综上所述,选型时应综合考虑项目的性能要求、功耗和成本、外设需求,以及开发工具和生态系统支持等因素,最终选择适合的ZynqZynq Ultrascale型号。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值