PS用SDK编译环境下调用DMA

背景:我们之前通过linux编译模式下调用DMA,testBench中运用的指令为fd = open("/dev/axi-dma1", O_RDWR);  但是在SDK的编译环境下,系统搭建完成后就会出现Open axi-dma1 failed!

目的:查找SDK中的例程找到调用DMA的方法。

vivado中系统为:

地址信息如下:

SDK中外设程序运行结果:

一、用调试程序编写

虽然程序运行到一半卡住了,但是万幸的是DMA是通的,所以我们直接查找DMA的程序。

      int Status;
      
      print("\r\n Running XDmaPs_Example_W_Intr() for ps7_dma_s...\r\n");
      
      Status = XDmaPs_Example_W_Intr(&intc,XPAR_PS7_DMA_S_DEVICE_ID);
      
      if (Status == 0) {
         print("XDmaPs_Example_W_Intr PASSED\r\n");
      }
      else {
         print("XDmaPs_Example_W_Intr FAILED\r\n");
      }

查找后发现此例程以及涉及的程序没有调用DMA的相关例子,只能从其他方向找相关的DMA调用的程序。

最终发现在文档UG871中有相关运用DMA实现FFT相关的调用。

	// Declare a XAxiDma object instance
   XAxiDma axiDma;

   // Local variables
   int i, j;
   int status;
   static short realdata[4*REAL_FFT_LEN];
   volatile static complex16 realspectrum[REAL_FFT_LEN/2];

   // Initialize the platform
   init_platform();
   print("---------------------------------------\n\r");
   print("- RealFFT PL accelerator test program -\n\r");
   print("---------------------------------------\n\r");

   // Initialize the (simple) DMA engine
   status = init_dma(&axiDma);
   if (status != XST_SUCCESS) {
      exit(-1);
   }
   // Generate a waveform to be input to FFT
   for (i = 0; i < 4; i++)
	   generate_waveform(realdata + i * REAL_FFT_LEN, REAL_FFT_LEN);
   // *IMPORTANT* - flush contents of 'realdata' from data cache to memory
   // before DMA. Otherwise DMA is likely to get stale or uninitialized data
   Xil_DCacheFlushRange((unsigned)realdata, 4 * REAL_FFT_LEN * sizeof(short));
   // DMA enough data to push out first result data set completely
   status = XAxiDma_SimpleTransfer(&axiDma, (u32)realdata,
		   4 * REAL_FFT_LEN * sizeof(short), XAXIDMA_DMA_TO_DEVICE);
   status = XAxiDma_SimpleTransfer(&axiDma, (u32)realdata,
		   4 * REAL_FFT_LEN * sizeof(short), XAXIDMA_DMA_TO_DEVICE);

   // Do multiple DMA xfers from the RealFFT core's output stream and
   // display data for bins with significant energy. After the first frame,
   // there should only be energy in bins around the frequencies specified
   // in the generate_waveform() function - currently bins 191~193 only
   for (i = 0; i < 8; i++) {
	   // Setup DMA from PL to PS memory using AXI DMA's 'simple' transfer mode
	   status = XAxiDma_SimpleTransfer(&axiDma, (u32)realspectrum,
			   REAL_FFT_LEN / 2 * sizeof(complex16), XAXIDMA_DEVICE_TO_DMA);
      // Poll the AXI DMA core
	   do {
		   status = XAxiDma_Busy(&axiDma, XAXIDMA_DEVICE_TO_DMA);
	   } while(status);
	   // Data cache must be invalidated for 'realspectrum' buffer after DMA
	   Xil_DCacheInvalidateRange((unsigned)realspectrum,
	   		REAL_FFT_LEN / 2 * sizeof(complex16));
	   // DMA another frame of data to PL
	   if (!XAxiDma_Busy(&axiDma, XAXIDMA_DMA_TO_DEVICE))
		   status = XAxiDma_SimpleTransfer(&axiDma, (u32)realdata,
				   REAL_FFT_LEN * sizeof(short), XAXIDMA_DMA_TO_DEVICE);

此程序运用XAxiDma_SimpleTransfer实现对DMA的调用,我们参考此程序编写相应的ARM testBench

但是在运行时总是缺少xaxidma.h这个头文件。两个目录不太一样,

xaxidma.h和SDK的目录分别为:D:\xilinx\SDx\2016.4\SDK\data\embeddedsw\XilinxProcessorIPLib\drivers\axidma_v9_3\src

可能与编译的系统有关,SDK的example与编写的程序之间存在一定的差别。

文档UG871中的xaxidma.h与example中不太一样,必须按照文档中的方法才能调用。

并且调用为none-eabi可能也有影响。

ABI:二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)。在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。

EABI:嵌入式ABI。嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用 EABI 作为与兼容的编译器生成的汇编语言的接口。

两者主要区别是,ABI是计算机上的,EABI是嵌入式平台上(如ARM,MIPS等)。

只能先想办法用其他范例如AXI-lite调用DDR,尽快实现DDR的调用,DMA后续再调通。

未完

猜你喜欢

转载自blog.csdn.net/weixin_36474809/article/details/81028275