背景:我们之前通过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后续再调通。
可能出现的问题:是否HLS在生成相应的IPcore时,也生成了相应的.c和.h文件,但是相应的文件缺失了。