zoukankan      html  css  js  c++  java
  • dma example源码阅读

    /******************************************************************************
    *
    * Copyright (C) 2009 - 2015 Xilinx, Inc.  All rights reserved.
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal 
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in
    * all copies or substantial portions of the Software.
    *
    * Use of the Software is limited solely to applications:
    * (a) running on a Xilinx device, or
    * (b) that interact with a Xilinx device through a bus or interconnect.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 
    * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    * SOFTWARE.
    *
    * Except as contained in this notice, the name of the Xilinx shall not be used
    * in advertising or otherwise to promote the sale, use or other dealings in
    * this Software without prior written authorization from Xilinx.
    *
    ******************************************************************************/
    /****************************************************************************/
    /**
    *
    * @file xdmaps_example_w_intr.c
    *
    *
    * <pre>
    * MODIFICATION HISTORY:
    *
    * Ver   Who      Date     Changes
    * ----- ------ -------- ----------------------------------------------
    * 1.00    hbm    08/19/2010 First Release
    * 1.01a nm     03/05/2012 Initializing DmaCmd structure compatible to armcc.
    *                         Modified base address to secure register base
    *                         address.
    * 1.02a sg     05/16/2012 Some code cleanup and reorganisation of the
    *              functions within the example.
    * 1.06a kpc    04/24/2012 Modified the APIs to make this file compatible with 
    *                         peripheral test suite.                             
    * 2.1   kpc    08/23/2014 Fixed IAR compiler reported error.
    * 2.3   ms     01/23/17  Modified xil_printf statement in main function to
    *                        ensure that "Successfully ran" and "Failed" strings are
    *                        available in all examples. This is a fix for CR-965028.
    * </pre>
    *
    *****************************************************************************/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "sleep.h"
    #include "xparameters.h"
    #include "xil_types.h"
    #include "xil_assert.h"
    #include "xil_io.h"
    #include "xil_exception.h"
    #include "xil_cache.h"
    #include "xil_printf.h"
    #include "xscugic.h"
    #include "xdmaps.h"
    
    /************************** Constant Definitions *****************************/
    /*
     * The following constants map to the XPAR parameters created in the
     * xparameters.h file. They are defined here such that a user can easily
     * change all the needed parameters in one place.
     */
    
    //改常量,从flatform看地址映射。但还没找到dma的?
    #define DMA_DEVICE_ID             XPAR_XDMAPS_1_DEVICE_ID
    #define INTC_DEVICE_ID            XPAR_SCUGIC_SINGLE_DEVICE_ID//gic
    
    #define DMA_DONE_INTR_0            XPAR_XDMAPS_0_DONE_INTR_0//0通道isr(中断服务程序?
    #define DMA_DONE_INTR_1            XPAR_XDMAPS_0_DONE_INTR_1
    #define DMA_DONE_INTR_2            XPAR_XDMAPS_0_DONE_INTR_2
    #define DMA_DONE_INTR_3            XPAR_XDMAPS_0_DONE_INTR_3
    #define DMA_DONE_INTR_4            XPAR_XDMAPS_0_DONE_INTR_4
    #define DMA_DONE_INTR_5            XPAR_XDMAPS_0_DONE_INTR_5
    #define DMA_DONE_INTR_6            XPAR_XDMAPS_0_DONE_INTR_6
    #define DMA_DONE_INTR_7            XPAR_XDMAPS_0_DONE_INTR_7
    #define DMA_FAULT_INTR            XPAR_XDMAPS_0_FAULT_INTR
    
    
    
    #define TEST_ROUNDS    1    /* Number of loops that the Dma transfers run.测试轮数*/
    #define DMA_LENGTH    1024    /* Length of the Dma Transfers数据长度 */
    #define TIMEOUT_LIMIT     0x2000    /* Loop count for timeout 计数,超时?*/
    
    /**************************** Type Definitions *******************************/
    
    
    /***************** Macros (Inline Functions) Definitions *********************/
    
    
    /************************** Function Prototypes ******************************/
    
    int XDmaPs_Example_W_Intr(XScuGic *GicPtr, u16 DeviceId);
    int SetupInterruptSystem(XScuGic *GicPtr, XDmaPs *DmaPtr);
    void DmaDoneHandler(unsigned int Channel, XDmaPs_Cmd *DmaCmd,
                void *CallbackRef);
    
    /************************** Macro Definitions *****************************/
    
    
    /************************** Variable Definitions *****************************/
    #ifdef __ICCARM__
    #pragma data_alignment=32
    static int Src[DMA_LENGTH];
    static int Dst[DMA_LENGTH];
    #pragma data_alignment=4
    #else
    static int Src[DMA_LENGTH] __attribute__ ((aligned (32)));
    //static int * Src = (int*)XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR;//助教的修改:把src弄成板上的地址?
    已经是虚拟地址了,直接用就行
    static int Dst[DMA_LENGTH] __attribute__ ((aligned (32))); #endif XDmaPs DmaInstance; #ifndef TESTAPP_GEN XScuGic GicInstance; #endif /****************************************************************************/ /** * * This is the main function for the DmaPs interrupt example. * * @param None. * * @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. * * @note None. * ****************************************************************************/ #ifndef TESTAPP_GEN int main(void) { int Status; Status = XDmaPs_Example_W_Intr(&GicInstance,DMA_DEVICE_ID);//调用 if (Status != XST_SUCCESS) { xil_printf("Error: XDMaPs_Example_W_Intr failed "); return XST_FAILURE; } xil_printf("Successfully ran XDMaPs_Example_W_Intr "); return XST_SUCCESS; } #endif /*****************************************************************************/ /** * * Interrupt Example to test the DMA.//这里只有写入,调用DmaDoneHandler负责回读检查 *ID是不是需要按具体的实现改? * @param DeviceId is the Device ID of the DMA controller. * * @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. * * @note None. * ****************************************************************************/ int XDmaPs_Example_W_Intr(XScuGic *GicPtr, u16 DeviceId) { int Index;//循环变量 unsigned int Channel = 0; int Status; int TestStatus; int TestRound; int TimeOutCnt; volatile int Checked[XDMAPS_CHANNELS_PER_DEV];//这是啥? XDmaPs_Config *DmaCfg; XDmaPs *DmaInst = &DmaInstance; XDmaPs_Cmd DmaCmd; memset(&DmaCmd, 0, sizeof(XDmaPs_Cmd));//给DmaCmd结构体分空间。dma直接使,不用经过axi。给 //用cmd控制dma读写 DmaCmd.ChanCtrl.SrcBurstSize = 4;//设置cmd参数 DmaCmd.ChanCtrl.SrcBurstLen = 4; DmaCmd.ChanCtrl.SrcInc = 1; DmaCmd.ChanCtrl.DstBurstSize = 4; DmaCmd.ChanCtrl.DstBurstLen = 4; DmaCmd.ChanCtrl.DstInc = 1; DmaCmd.BD.SrcAddr = (u32) Src;// DmaCmd.BD.DstAddr = (u32) Dst; DmaCmd.BD.Length = DMA_LENGTH * sizeof(int); /* * Initialize the DMA Driver */ DmaCfg = XDmaPs_LookupConfig(DeviceId);//由id找设备? if (DmaCfg == NULL) { return XST_FAILURE; } Status = XDmaPs_CfgInitialize(DmaInst,//初始化dma DmaCfg, DmaCfg->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the interrupt system.设置中断 */ Status = SetupInterruptSystem(GicPtr, DmaInst);//子函数,不是库函数 if (Status != XST_SUCCESS) { return XST_FAILURE; } TestStatus = XST_SUCCESS;//开始测试,初始化为成功,不成功段的代码改为fail for (TestRound = 0; TestRound < TEST_ROUNDS; TestRound++) { xil_printf("Test round %d ", TestRound); for (Channel = 0; Channel < XDMAPS_CHANNELS_PER_DEV; Channel++) { //一层循环channel XDMAPS_CHANNELS_PER_DEV是怎么来的?干什么的? //每个通道都测 /* Initialize source 给源数据赋值*/ for (Index = 0; Index < DMA_LENGTH; Index++) Src[Index] = DMA_LENGTH - Index;//已经在访存板上地址 /* Clear destination 清空结果数组*/ for (Index = 0; Index < DMA_LENGTH; Index++) Dst[Index] = 0; Checked[Channel] = 0;//每个channel检查结果初始化为0 /* Set the Done interrupt handler 设置完成中断?因为dma不经cpu控制,所以需要中断*/ XDmaPs_SetDoneHandler(DmaInst,//中断待???channel是什么??怎么和设备映射的?? Channel, DmaDoneHandler, //DmaDoneHandler是子函数,如果有中断跳到这里 (void *)Checked); Status = XDmaPs_Start(DmaInst, Channel, &DmaCmd, 0);//开始,之前cmd的参数已经设置好了 //cmd包括写什么,怎么写 if (Status != XST_SUCCESS) { return XST_FAILURE; }//返回的是开始成功 TimeOutCnt = 0; /* Now the DMA is done 计时等待完成,忙等中断,回写部分可参考*/ while (!Checked[Channel] //checked数组和中断连,不是和dma,dma给中断,中断给 && TimeOutCnt < TIMEOUT_LIMIT) { TimeOutCnt++; } if (TimeOutCnt >= TIMEOUT_LIMIT) {//超时 TestStatus = XST_FAILURE; } if (Checked[Channel] < 0) { /* DMA controller failed 失败的中断*/ TestStatus = XST_FAILURE; } } } return TestStatus; } /******************************************************************************/ /** *把系统连上中断,可以直接抄,但要改啥?? * This function connects the interrupt handler of the interrupt controller to * the processor. This function is seperate to allow it to be customized for * each application. Each processor or RTOS may require unique processing to * connect the interrupt handler. * * @param GicPtr is the GIC instance pointer. GIC是ARM公司提供的一个通用的中断控制器=驱动? * @param DmaPtr is the DMA instance pointer. dma硬件? * * @return None. * * @note None. * ****************************************************************************/ int SetupInterruptSystem(XScuGic *GicPtr, XDmaPs *DmaPtr) { int Status; #ifndef TESTAPP_GEN //这是干什么的?没见过这个宏 XScuGic_Config *GicConfig; Xil_ExceptionInit();//初始化溢出 /* * Initialize the interrupt controller driver so that it is ready to * use.初始化dma控制器 */ GicConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);//找设备,把设备赋给地址,待?? if (NULL == GicConfig) {//没找着 return XST_FAILURE; } Status = XScuGic_CfgInitialize(GicPtr, GicConfig,//初始化fic,什么时候使什么?? GicConfig->CpuBaseAddress);//config是板子上数据(设备设置,ptr是本地指针 if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the interrupt controller interrupt handler to the hardware * interrupt handling logic in the processor. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler,//这都啥,填异常处理表? GicPtr); #endif /* * Connect the device driver handlers that will be called when an interrupt * for the device occurs, the device driver handler performs the specific * interrupt processing for the device */ /* * Connect the Fault ISR 啥?错误中断处理程序?是中断都要连吗? */ Status = XScuGic_Connect(GicPtr, DMA_FAULT_INTR, (Xil_InterruptHandler)XDmaPs_FaultISR, (void *)DmaPtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the Done ISR for all 8 channels of DMA 0 DMA都是8通道?连这个干什么的? */ Status = XScuGic_Connect(GicPtr, DMA_DONE_INTR_0, (Xil_InterruptHandler)XDmaPs_DoneISR_0,//这是一个xdmaps.c函数。没看懂干嘛的?? (void *)DmaPtr); Status |= XScuGic_Connect(GicPtr, DMA_DONE_INTR_1, (Xil_InterruptHandler)XDmaPs_DoneISR_1, (void *)DmaPtr); Status |= XScuGic_Connect(GicPtr, DMA_DONE_INTR_2, (Xil_InterruptHandler)XDmaPs_DoneISR_2, (void *)DmaPtr); Status |= XScuGic_Connect(GicPtr, DMA_DONE_INTR_3, (Xil_InterruptHandler)XDmaPs_DoneISR_3, (void *)DmaPtr); Status |= XScuGic_Connect(GicPtr, DMA_DONE_INTR_4, (Xil_InterruptHandler)XDmaPs_DoneISR_4, (void *)DmaPtr); Status |= XScuGic_Connect(GicPtr, DMA_DONE_INTR_5, (Xil_InterruptHandler)XDmaPs_DoneISR_5, (void *)DmaPtr); Status |= XScuGic_Connect(GicPtr, DMA_DONE_INTR_6, (Xil_InterruptHandler)XDmaPs_DoneISR_6, (void *)DmaPtr); Status |= XScuGic_Connect(GicPtr, DMA_DONE_INTR_7, (Xil_InterruptHandler)XDmaPs_DoneISR_7, (void *)DmaPtr); if (Status != XST_SUCCESS) return XST_FAILURE; /*使能所有通道的gic * Enable the interrupts for the device */ XScuGic_Enable(GicPtr, DMA_DONE_INTR_0); XScuGic_Enable(GicPtr, DMA_DONE_INTR_1); XScuGic_Enable(GicPtr, DMA_DONE_INTR_2); XScuGic_Enable(GicPtr, DMA_DONE_INTR_3); XScuGic_Enable(GicPtr, DMA_DONE_INTR_4); XScuGic_Enable(GicPtr, DMA_DONE_INTR_5); XScuGic_Enable(GicPtr, DMA_DONE_INTR_6); XScuGic_Enable(GicPtr, DMA_DONE_INTR_7); XScuGic_Enable(GicPtr, DMA_FAULT_INTR); Xil_ExceptionEnable();//使能异常,看来异常包括了中断 return XST_SUCCESS; } /*****************************************************************************/ /** * * DmaDoneHandler. * * @param Channel is the Channel number. * @param DmaCmd is the Dma Command. * @param CallbackRef is the callback reference data. * * @return None. * * @note None. * ******************************************************************************/ void DmaDoneHandler(unsigned int Channel, XDmaPs_Cmd *DmaCmd, void *CallbackRef) { /* done handler */ volatile int *Checked = (volatile int *)CallbackRef; int Index; int Status = 1; int *Src;//局部变量 int *Dst; Src = (int *)DmaCmd->BD.SrcAddr;//重新赋值? Dst = (int *)DmaCmd->BD.DstAddr; /* DMA successful 不用手动存,dma自己存在了dst,把外存存到了内存(数组)*/ //怎么映射的?需要显示指明什么? //怎么交互的?怎么指挥外存地址?src和dst存的什么? /* compare the src and dst buffer */ for (Index = 0; Index < DMA_LENGTH; Index++) { if ((Src[Index] != Dst[Index]) || (Dst[Index] != DMA_LENGTH - Index)) { Status = -XST_FAILURE; } } Checked[Channel] = Status; }
  • 相关阅读:
    抖音圈圈乐 系统搭建H5微信小游戏圈圈乐系统介绍
    GPS NMEA-0183标准详解
    GPS定位的偏移校正(WGS84与火星坐标互转)
    Complete_NGINX_Cookbook
    GBT32960-2016电动汽车远程服务与管理系统技术规范 第3部分:通信协议及数据格式
    Redis 到底是怎么实现“附近的人”这个功能的呢?
    NETGEAR R7800路由器TFTP刷回原厂固件方法
    JT/T 808-2013 道路运输车辆卫星定位系统北斗兼容车载终端通讯协议技术规范
    如何正确地使用设计模式?
    各常用分类算法的优缺点总结:DT/ANN/KNN/SVM/GA/Bayes/Adaboosting/Rocchio
  • 原文地址:https://www.cnblogs.com/iwanna/p/10011943.html
Copyright © 2011-2022 走看看