关于DMA环通实验的SDK部分代码理解

一、定义部分

#include "xaxidma.h"
#include "xparameters.h"
#include "xil_printf.h"
#include "xscugic.h"


#define DMA_DEV_ID          XPAR_AXIDMA_0_DEVICE_ID
#define INT_DEVICE_ID     XPAR_SCUGIC_SINGLE_DEVICE_ID
#define INTR_ID           XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR //中断定义

#define FIFO_DATABYTE   4 //字节数
#define TEST_COUNT      80
#define MAX_PKT_LEN        TEST_COUNT*FIFO_DATABYTE//发送包长度

#define TEST_START_VALUE    0xC //开始值

#define NUMBER_OF_TRANSFERS    2  //传输次数

/*
 * Function declaration //数据检测函数
 */
int XAxiDma_Setup(u16 DeviceId); //
static int CheckData(void);
int SetInterruptInit(XScuGic *InstancePtr, u16 IntrID, XAxiDma *XAxiDmaPtr) ;

XScuGic INST ;

XAxiDma AxiDma;

u8 TxBufferPtr[MAX_PKT_LEN] ;//发送
u8 RxBufferPtr[MAX_PKT_LEN] ;//接收

二、建立中断代码部分

思路:初始化,配置ID和地址--中断处理函数:将ID和中断处理函数连接--启动中断
 中断异常:初始化异常--处理异常函数--返回成功。

代码解释:

int SetInterruptInit(XScuGic *InstancePtr, u16 IntrID, XAxiDma *XAxiDmaPtr)
{

    XScuGic_Config * Config ;  //XAxiDma_Config是一个AXI_DMA配置的信息结构体,它里面包含 需要配置的各种信息,传递给API函数
    int Status ;

    Config = XScuGic_LookupConfig(INT_DEVICE_ID) ;//初始化,XScuGic_Config其中的中断函数,

    Status = XScuGic_CfgInitialize(&INST, Config, Config->CpuBaseAddress) ;//初始化,配置(cfg)地址 ,scugic:系统级中断控制器
    if (Status != XST_SUCCESS)
        return XST_FAILURE ;

    Status = XScuGic_Connect(InstancePtr, IntrID,
            (Xil_ExceptionHandler)CheckData,
            XAxiDmaPtr) ; //中断设置中断处理函数:将中断ID和中断处理函数连接起来,当中断被识  别后执行相应的处理函数
    if (Status != XST_SUCCESS) {
            return Status;
        }

    XScuGic_Enable(InstancePtr, IntrID) ;//启动中断

    Xil_ExceptionInit();//通用API,用于ARM处理器中初始化异常处理程序。
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                    (Xil_ExceptionHandler) XScuGic_InterruptHandler,
                    InstancePtr); //为异常情况注册一个处理器,当处理器遇到指定异常时,调用此处理程序。  XIL_EXCEPTION_ID_INT是xilinx处理器定义的。

    Xil_ExceptionEnable(); //使能中断(用于控制处理器是否响应中断)异常


    return XST_SUCCESS ;

}

三、DMA部分(重要)

思路:初始化DMA-确认sg/simple模式--建立中断系统--启动S2MM中断--赋值--Cache刷新--开始传输接收。

代码:

int XAxiDma_Setup(u16 DeviceId)
{
    XAxiDma_Config *CfgPtr;
    int Status;
    int Tries = NUMBER_OF_TRANSFERS;
    int Index;
    u8 Value;

    /* Initialize the XAxiDma device.
     */
    //初始化DMA设备  cfg配置文件  ptr指针记录

    CfgPtr = XAxiDma_LookupConfig(DeviceId);//将DMA设备ID赋值给XAxiDma_Config结构体;
    if (!CfgPtr) {
        xil_printf("No config found for %d\r\n", DeviceId);
        return XST_FAILURE;
    }

    /*初始化DMA引擎,将DMA设备ID赋值给XAxiDma_Config结构体;
     * 根据PL端对DMA core的配置参数,PS对DMA进行真正的配置初始化过程,
     axidma还存储在PS端的AXI——DMA配置表,根据对PL参数的读取,
     PS运行对PL侧的DMA配置,这个配置过程是通过GP0接口对AXI_Lite4总线的控制完成的*/

    Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
    if (Status != XST_SUCCESS) {
        xil_printf("Initialization failed %d\r\n", Status);
        return XST_FAILURE;
    }
 
    /*sg/simple mode?,如果是SG,则配置失败。
    * 配置的是使用PL侧DMA的直接寄存器访问模式,所以数据传递也是通过该方式运行的,
               为了以防万一,在这里运行一下SG查询函数看看是不是配置成了SG模式*/
    if(XAxiDma_HasSg(&AxiDma)){
        xil_printf("Device configured as SG mode \r\n");
        return XST_FAILURE;
    }

    // 建立中断系统
    Status = SetInterruptInit(&INST,INTR_ID, &AxiDma) ;
    if (Status != XST_SUCCESS)
                 return XST_FAILURE ;

    /* 使能DMA中断, 启动S2MM中断*/
    XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_IOC_MASK,
                        XAXIDMA_DEVICE_TO_DMA);
    XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
                        XAXIDMA_DMA_TO_DEVICE);

    //对写入数据进行赋值
    Value = TEST_START_VALUE;

    for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
            TxBufferPtr[Index] = Value;

            Value = (Value + 1) & 0xFF;
    }
    /*在DMA传输前刷新SrcBuffer,以防数据缓存。
           将要写入fifo的数据刷入Cache */
    Xil_DCacheFlushRange((UINTPTR)TxBufferPtr, MAX_PKT_LEN);    //刷新Data Cache
    Xil_DCacheFlushRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN);    //刷新到ddr,Cache关联地址的数据写入到DDR中,并把Cache里的数据清空,将CACHE数据更新到MEMORY


    for(Index = 0; Index < Tries; Index ++) {
        //开始传输
            Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) TxBufferPtr,
                                MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);

            if (Status != XST_SUCCESS) {
                return XST_FAILURE;
            }
       //开始接收
            Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) RxBufferPtr,
                                MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);


            if (Status != XST_SUCCESS) {
                return XST_FAILURE;
            }


            while ((XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA)) ||
                (XAxiDma_Busy(&AxiDma,XAXIDMA_DMA_TO_DEVICE)))
                    {
                    /* Wait */
            }


        }

        /* Test finishes successfully
         */
        return XST_SUCCESS;
    }

四、数据检测

思路:请求待处理的中断--刷新Cache---检查数据缓冲区--数据验证

  • 44
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值