zynq的axi-dma使用(1)

本文以下的描述均为建立在pl端已经创建好程序,本文主要描述不使用petalinux,使用原版的linux根据SDK提供的例程进行移植的。

demo工程测试

能够移植成功的前提是要先通过sdk工程的demo测试,建立axidma工程,在bsp system.mss里面选择下面的demo工程:
在这里插入图片描述
在这里插入图片描述
这是一个不带中断的轮训demo,通过不断查询总线是否空闲的标志位来判断pl端是否有数据写入,测试通过后,说明pl-pl的链路是没有问题的,可以基于此demo进行移植,这里我就不把我的测试结果贴出来的,可以通过查看内存值或者打印数据的方式来检验。

移植到linux应用程序中

这里说明几个特别的注意事项然后贴上自己的代码就好了,都是我使用的时候出现问题的地方。
1、MAX_PKT_LEN需要与pl端设置的每包长度保持一致,可以是其整数倍;
2、因为linux用户空间是没有办法看到物理地址的,所以需要进行寄存器地址的映射,基本上使用的都是mmap这个库函数实现。
下面主要是两段代码,一段是初始化,一段是数据搬运;
//初始化代码
int XAxiDma_Init(u16 DeviceId)
{
XAxiDma_Config *CfgPtr;
int Status;
int Tries = NUMBER_OF_TRANSFERS;
int Index;

	g_pio_fd = open("/dev/mem", O_RDWR|O_SYNC);

	g_rx_buffer_base_map = (unsigned char *)mmap(NULL,0xffff, 0x01|0x02,MAP_SHARED, g_pio_fd,RX_BUFFER_BASE);
	if(g_rx_buffer_base_map == MAP_FAILED)
	{
		iray_err("sharemen_map_base mapping for absolute memory access failed.\n");
		return -1;
	}
	g_dma_base_reg_map = (unsigned char *)mmap(NULL,0xffff, 0x01|0x02,MAP_SHARED, g_pio_fd,XPAR_AXI_DMA_0_BASEADDR);
	if(g_dma_base_reg_map == MAP_FAILED)
	{
		iray_err("sharemen_map_base mapping for absolute memory access failed.\n");
		return -1;
	}

	/* Initialize the XAxiDma device.
	 */
	CfgPtr = XAxiDma_LookupConfig(DeviceId);
	if (!CfgPtr) {
		printf("No config found for %d\r\n", DeviceId);
		return XST_FAILURE;
	}
	CfgPtr->BaseAddr = (UINTPTR)g_dma_base_reg_map;
//printf("ox%x, 0x%x\n", (UINTPTR)dma_base_reg_map, dma_base_reg_map);
	Status = XAxiDma_CfgInitialize(&g_AxiDma, CfgPtr);
	if (Status != XST_SUCCESS) {
		printf("Initialization failed %d\r\n", Status);
		return XST_FAILURE;
	}

	if(XAxiDma_HasSg(&g_AxiDma)){
		printf("Device configured as SG mode \r\n");
		return XST_FAILURE;
	}

	/* Disable interrupts, we use polling mode
	 */
	XAxiDma_IntrDisable(&g_AxiDma, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DEVICE_TO_DMA);
	XAxiDma_IntrDisable(&g_AxiDma, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DMA_TO_DEVICE);
	printf("当前代码行:%d\n", __LINE__);

	for(Index = 0; Index < Tries; Index ++) {}

	/* Test finishes successfully
	 */
	return XST_SUCCESS;
}

//数据搬运代码
int XAxiDma_Read_From_Pl(void)
{
	int Status;

	Status = XAxiDma_SimpleTransfer(&g_AxiDma,(UINTPTR) RX_BUFFER_BASE,
				MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	return Status;
}

主要程序实现就是这些了,后面可以自己实现sg模式的dma,一般在图像开窗的时候可以使用,理论上也是比较简单的。


大家有问题可以相互讨论,我也是小白,微信 yucaohua001

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Zynq SoC 上,AXI DMA(Direct Memory Access)是一种能够在外设和存储器之间进行高速数据传输的IP核。Cyclic DMA 模式允许通过循环传输数据,从而实现连续的数据流。下面是一些关于在 Zynq SoC 上编程 AXI DMA 的基本步骤: 1. 配置 AXI DMA IP:首先,在 Vivado 中配置和实例化 AXI DMA IP 核,并连接到 Zynq SoC 的 PS(Processing System)部分。确保正确连接 AXI DMA 的信号和端口,包括数据输入/输出端口、中断线和控制寄存器。 2. 设置 DMA 控制寄存器:使用 AXI DMA 的控制寄存器来配置 DMA 的工作模式和参数。在 Cyclic DMA 模式下,你需要设置循环传输模式,并指定传输的数据长度和起始地址。 3. 配置 DMA 缓冲区:为 DMA 设置输入和输出缓冲区。这些缓冲区将用于在外设和存储器之间传输数据。 4. 启动 DMA 传输:通过设置 AXI DMA 控制寄存器中的位来启动数据传输。在 Cyclic DMA 模式下,你可以选择是否在每次传输完成后自动重启传输。 5. 处理中断:如果需要,在 AXI DMA 完成传输时,你可以使用中断机制来通知处理器。在中断处理程序中,你可以执行必要的操作,如处理传输的数据或触发下一次传输。 需要注意的是,以上步骤只是一个基本的框架,具体的实现可能因应用需求而有所差异。你可以参考 Xilinx 提供的文档和示例代码来详细了解 AXI DMA 的编程和配置方法。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值