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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值