ZYNQ7000 petalinux AXI_DMA传输数据

1.vivado工程:DMA_LOOP

ZYNQ7000 petalinux AXI_DMA传输数据

2,添加约束,生成bit,导入SDK,,新建dma测试工程测试功能

main.c:
#include "dma_intr.h"
#include "sys_intr.h"
static XScuGic Intc;
static  XAxiDma AxiDma;
volatile u32 success;
char oled_str[16]="";
int Tries = NUMBER_OF_TRANSFERS;
int i,Index;
u8 *TxBufferPtr= (u8 *)TX_BUFFER_BASE;
u8 *RxBufferPtr=(u8 *)RX_BUFFER_BASE;
u8 Value;
int axi_dma_test()
{
    int Status;
    TxDone = 0;
    RxDone = 0;
    Error = 0;
    xil_printf("\r\n----DMA Test----\r\n");
    for(i = 0; i < Tries; i ++)
    {
        Value = TEST_START_VALUE + (i & 0xFF);
        for(Index = 0; Index < MAX_PKT_LEN; Index ++)
        {
                TxBufferPtr[Index] = Value;
                Value = (Value + 1) & 0xFF;
        }
        Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);
        Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
        if (Status != XST_SUCCESS)
        {
            return XST_FAILURE;
        }
        Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
        if (Status != XST_SUCCESS)
        {
            return XST_FAILURE;
        }
        success++;
        TxDone = 0;
        RxDone = 0;
        if (Error)
        {
            xil_printf("Failed test transmit%s done, ""receive%s done\r\n", TxDone? "":" not",RxDone? "":" not");
            goto Done;
        }
        Status = DMA_CheckData(MAX_PKT_LEN, (TEST_START_VALUE + (i & 0xFF)));
        if (Status != XST_SUCCESS)
        {
            xil_printf("Data check failed\r\n");
            goto Done;
        }
    }
    xil_printf("AXI DMA interrupt example test passed\r\n");
    xil_printf("success=%d\r\n",success);
    DMA_DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);
Done:
    xil_printf("--- Exiting Test --- \r\n");
    return XST_SUCCESS;
}
int init_intr_sys(void)
{
    DMA_Intr_Init(&AxiDma,0);//initial interrupt system
    Init_Intr_System(&Intc); // initial DMA interrupt system
    Setup_Intr_Exception(&Intc);
    DMA_Setup_Intr_System(&Intc,&AxiDma,TX_INTR_ID,RX_INTR_ID);//setup dma interrpt system
    DMA_Intr_Enable(&Intc,&AxiDma);
}
int main(void)
{
    init_intr_sys();
    axi_dma_test();
}

dma_intr.h:

ZYNQ7000 petalinux AXI_DMA传输数据

dma_intr.c:

#include "dma_intr.h"
volatile int TxDone;
volatile int RxDone;
volatile int Error;
 int DMA_CheckData(int Length, u8 StartValue)
{
    u8 *RxPacket;
    int Index = 0;
    u8 Value;
    RxPacket = (u8 *) RX_BUFFER_BASE;
    Value = StartValue;
#ifndef __aarch64__
    Xil_DCacheInvalidateRange((u32)RxPacket, Length);
#endif
    for(Index = 0; Index < Length; Index++)
    {
        if (RxPacket[Index] != Value)
        {
            xil_printf("Data error %d: %x/%x\r\n",Index, RxPacket[Index], Value);
            return XST_FAILURE;
        }
        Value = (Value + 1) & 0xFF;
    }
    return XST_SUCCESS;
}
 void DMA_DisableIntrSystem(XScuGic * IntcInstancePtr,u16 TxIntrId, u16 RxIntrId)
{
#ifdef XPAR_INTC_0_DEVICE_ID
    XIntc_Disconnect(IntcInstancePtr, TxIntrId);
    XIntc_Disconnect(IntcInstancePtr, RxIntrId);
#else
    XScuGic_Disconnect(IntcInstancePtr, TxIntrId);
    XScuGic_Disconnect(IntcInstancePtr, RxIntrId);
#endif
}
static void DMA_TxIntrHandler(void *Callback)
{
    u32 IrqStatus;
    int TimeOut;
    XAxiDma *AxiDmaInst = (XAxiDma *)Callback;
    IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DMA_TO_DEVICE);
    XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DMA_TO_DEVICE);
    if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) { return; }
    if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK))
    {
        Error = 1;
        XAxiDma_Reset(AxiDmaInst);
        TimeOut = RESET_TIMEOUT_COUNTER;
        while (TimeOut)
        {
            if (XAxiDma_ResetIsDone(AxiDmaInst)) { break; }
            TimeOut -= 1;
        }
        return;
    }
    if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {TxDone = 1;}
}
static void DMA_RxIntrHandler(void *Callback)
{
    u32 IrqStatus;
    int TimeOut;
    XAxiDma *AxiDmaInst = (XAxiDma *)Callback;
    IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DEVICE_TO_DMA);
    XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DEVICE_TO_DMA);
    if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {return;}
    if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK))
    {
        Error = 1;
        XAxiDma_Reset(AxiDmaInst);
        TimeOut = RESET_TIMEOUT_COUNTER;
        while (TimeOut)
        {
            if(XAxiDma_ResetIsDone(AxiDmaInst))
            {
                break;
            }
            TimeOut -= 1;
        }
        return;
    }
    if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {RxDone = 1;}
}
int DMA_Setup_Intr_System(XScuGic * IntcInstancePtr,XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId)
{
    int Status;
    XScuGic_SetPriorityTriggerType(IntcInstancePtr, TxIntrId, 0xA0, 0x3);
    XScuGic_SetPriorityTriggerType(IntcInstancePtr, RxIntrId, 0xA0, 0x3);
    Status = XScuGic_Connect(IntcInstancePtr, TxIntrId,(Xil_InterruptHandler)DMA_TxIntrHandler,AxiDmaPtr);
    if (Status != XST_SUCCESS) {return Status;}
    Status = XScuGic_Connect(IntcInstancePtr, RxIntrId,(Xil_InterruptHandler)DMA_RxIntrHandler,AxiDmaPtr);
    if (Status != XST_SUCCESS) {return Status;}
    XScuGic_Enable(IntcInstancePtr, TxIntrId);
    XScuGic_Enable(IntcInstancePtr, RxIntrId);
    return XST_SUCCESS;
}
int DMA_Intr_Enable(XScuGic * IntcInstancePtr,XAxiDma *DMAPtr)
{
    XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);
    XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);
    XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);
    XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);
    return XST_SUCCESS;
}
int DMA_Intr_Init(XAxiDma *DMAPtr,u32 DeviceId)
{
    int Status;
    XAxiDma_Config *Config=NULL;
    Config = XAxiDma_LookupConfig(DeviceId);
    if (!Config)
    {
        xil_printf("No config found for %d\r\n", DeviceId);
        return XST_FAILURE;
    }
    Status = XAxiDma_CfgInitialize(DMAPtr, Config);
    if (Status != XST_SUCCESS)
    {
        xil_printf("Initialization failed %d\r\n", Status);
        return XST_FAILURE;
    }
    if(XAxiDma_HasSg(DMAPtr))
    {
        xil_printf("Device configured as SG mode \r\n");
        return XST_FAILURE;
    }
    return XST_SUCCESS;

}

 

3,将导入的.hdf用来做启动文件

petalinux-create --type project --template zynq --name dma_trans

petalinux-config --get-hw-description ../linux_base.sdk

petalinux-config

petalinux-config -c kernel(要把xilinx DMA engine都选中)

petalinux-config -c rootfs

petalinux-build

4,新建input.txt并填入数据,再建一个空的output.txt,代码已上传

ZYNQ7000 petalinux AXI_DMA传输数据