Zynq到底有多深坑

来源:互联网 发布:楼宇广告发布软件 编辑:程序博客网 时间:2024/05/17 07:13

最近,又要调PS和PL接口的,先从DMA开始,各种VDMA,CDMA,DMA,Datamover...先说CDMA,底层框架已经搭好,地址配置OK,



地址分配如下:




没有问题吧,然后,生成bit文件,导入SDK,创建应用程序:


/* * Copyright (c) 2015 Xilinx, Inc.  All rights reserved. * * Xilinx, Inc. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. * *//* * helloworld.c: simple test application */#include <stdio.h>//#include "platform.h"#include "xaxicdma.h"#include "xdebug.h"#include "xil_exception.h"#include "xil_cache.h"#include "xparameters.h"#include "xscugic.h"#define NUMBER_OF_TRANSFERS2/* Number of simple transfers to do */#define DMA_CTRL_DEVICE_ID XPAR_AXICDMA_0_DEVICE_ID#define INTC_DEVICE_IDXPAR_SCUGIC_SINGLE_DEVICE_ID#define DMA_CTRL_IRPT_INTRXPAR_FABRIC_AXI_CDMA_0_CDMA_INTROUT_INTRvolatile static int Done = 0;/* Dma transfer is done */volatile static int Error = 0;/* Dma Bus Error occurs */static u32 SourceAddr = 0x20000000;static u32 DestAddr = 0x30000000;static XAxiCdma AxiCdmaInstance;/* Instance of the XAxiCdma */static XScuGic IntcController;/* Instance of the Interrupt Controller */static int Array_3[32][16];static int Array_4[32][16];static int Array_1[32][16];static int Array_2[32][16];int const input[16] = {0xb504f33, 0xabeb4a0, 0xa267994, 0x987fbfc, 0x8e39d9c, 0x839c3cc, 0x78ad74c, 0x6d743f4, 0x61f78a8, 0x563e6a8, 0x4a5018c, 0x3e33f2c, 0x31f1704, 0x259020c, 0x1917a64, 0xc8fb2c};/* Length of the buffers for DMA transfer */static u32 BUFFER_BYTESIZE= (XPAR_AXI_CDMA_0_M_AXI_DATA_WIDTH * XPAR_AXI_CDMA_0_M_AXI_MAX_BURST_LEN);static int CDMATransfer(XAxiCdma *InstancePtr, int Length, int Retries);static void DisableIntrSystem(XScuGic *IntcInstancePtr , u32 IntrId){XScuGic_Disable(IntcInstancePtr ,IntrId );XScuGic_Disconnect(IntcInstancePtr ,IntrId );}//Multiply and Shiftint MUL_SHIFT_30(int x, int y){  return ((int) (((long long) (x) * (y)) >> 30));}void MULT_SHIFT_LOOP(int Value ){   int i, j;   for (i = 0; i < 32; i++) {      for (j = 0; j < 16; j++) {      Array_3[i][j] = (int)((MUL_SHIFT_30(input[j],Array_1[j][i])) + Value);      Array_4[i][j] = (int)((MUL_SHIFT_30(input[j],Array_2[j][i])) + Value);      }   }}void TestPattern_Initialization(void){ int i, j;   for (i = 0; i < 32; i++)   {      for (j = 0; j < 16; j++)      {      Array_1[i][j] =  (int ) ((0xA5A5A5A5 >> 1) * i );      Array_2[i][j] =  (int ) ((0xA5A5A5A5 << 1) * i );      }   }}/*****************************************************************************//** Callback function for the simple transfer. It is called by the driver's* interrupt handler.** @paramCallBackRef is the reference pointer registered through*transfer submission. In this case, it is the pointer to the* driver instance* @paramIrqMask is the interrupt mask the driver interrupt handler*passes to the callback function.* @paramIgnorePtr is a pointer that is ignored by simple callback* function** @returnNone** @noteNone*******************************************************************************/static void Cdma_CallBack(void *CallBackRef, u32 IrqMask, int *IgnorePtr){if (IrqMask & XAXICDMA_XR_IRQ_ERROR_MASK) {Error = TRUE;printf("\r\n--- Transfer Error --- \r\n");}if (IrqMask & XAXICDMA_XR_IRQ_IOC_MASK) {printf("\r\n--- Transfer Done --- \r\n");Done = TRUE;}}static int SetupIntrSystem(XScuGic *IntcInstancePtr, XAxiCdma *InstancePtr,u32 IntrId){int Status;/* * Initialize the interrupt controller driver */XScuGic_Config *IntcConfig;/* * Initialize the interrupt controller driver so that it is ready to * use. */IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);if (NULL == IntcConfig) {return XST_FAILURE;}Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}XScuGic_SetPriorityTriggerType(IntcInstancePtr, IntrId, 0xA0, 0x3);/* * Connect the device driver handler that will be called when an * interrupt for the device occurs, the handler defined above performs * the specific interrupt processing for the device. */Status = XScuGic_Connect(IntcInstancePtr, IntrId,(Xil_InterruptHandler)XAxiCdma_IntrHandler,InstancePtr);if (Status != XST_SUCCESS) {return Status;}/* * Enable the interrupt for the DMA device. */XScuGic_Enable(IntcInstancePtr, IntrId);Xil_ExceptionInit();/* * 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,IntcInstancePtr);/* * Enable interrupts in the Processor. */Xil_ExceptionEnable();return XST_SUCCESS;}int XAxiCdma_Interrupt(XScuGic *IntcInstancePtr, XAxiCdma *InstancePtr,u16 DeviceId, u32 IntrId){{XAxiCdma_Config *CfgPtr;int Status;int SubmitTries = 1;/* Retry to submit */int Tries = NUMBER_OF_TRANSFERS;int Index;/* Initialize the XAxiCdma device. */CfgPtr = XAxiCdma_LookupConfig(DeviceId);if (!CfgPtr) {return XST_FAILURE;}Status = XAxiCdma_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}/* Setup the interrupt system */Status = SetupIntrSystem(IntcInstancePtr, InstancePtr, IntrId);if (Status != XST_SUCCESS) {return XST_FAILURE;}/* Enable all (completion/error/delay) interrupts */XAxiCdma_IntrEnable(InstancePtr, XAXICDMA_XR_IRQ_ALL_MASK);for (Index = 0; Index < Tries; Index++) {Status = CDMATransfer(InstancePtr,   BUFFER_BYTESIZE, SubmitTries);if(Status != XST_SUCCESS) {DisableIntrSystem(IntcInstancePtr, IntrId);return XST_FAILURE;}}/* Test finishes successfully, clean up and return */DisableIntrSystem(IntcInstancePtr, IntrId);return XST_SUCCESS;}}/*****************************************************************************//*** This function does  CDMA transfer** @paramInstancePtr is a pointer to the XAxiCdma instance* @paramLength is the transfer length* @paramRetries is how many times to retry on submission** @return*- XST_SUCCESS if transfer is successful*- XST_FAILURE if either the transfer fails or the data has*  error** @noteNone*******************************************************************************/static int CDMATransfer(XAxiCdma *InstancePtr, int Length, int Retries){int Status;Done = 0;Error = 0;printf("Start Transfer \n\r");/* Try to start the DMA transfer */Done = 0;Error = 0;/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache * is enabled */Xil_DCacheFlushRange((u32)SourceAddr, Length);Status = XAxiCdma_SimpleTransfer(InstancePtr,(u32)(u8 *) (SourceAddr ),(u32)(DestAddr),Length,Cdma_CallBack,(void *)InstancePtr);if (Status == XST_FAILURE) {printf("Error in Transfer  \n\r");return 1;}/* Wait until the DMA transfer is done */while (!Done && !Error) {/* Wait */}if (Error) {return XST_FAILURE;return 1;}/* Invalidate the DestBuffer before receiving the data, in case the * Data Cache is enabled */Xil_DCacheInvalidateRange((u32)DestAddr, Length);return XST_SUCCESS;}int main(){int Status;u32  *SrcPtr;u32  *DestPtr;unsigned int  Index;int i, j;    printf("\r\n--- Entering main() --- \r\n");/*********************************************************************************Step : 1 : Intialization of the SOurce Memory with the Specified test pattern      Clear Destination memory**********************************************************************************/    TestPattern_Initialization();    /* Initialize the source buffer bytes with a pattern and the     * the destination buffer bytes to zero    */   SrcPtr = (u32*)SourceAddr;   DestPtr = (u32 *)DestAddr;   for (Index = 0; Index < (BUFFER_BYTESIZE/1024); Index++)   {   MULT_SHIFT_LOOP((Index*100));   for (i = 0; i < 32; i++)   {   for (j = 0; j < 16; j++)   {   SrcPtr[((i+j))*(Index+1)] = Array_3[i][j];   SrcPtr[((i+j)*(Index+1)) + 1] = Array_4[i][j];   DestPtr[(i+j)*(Index+1)] = 0;   DestPtr[((i+j)*(Index+1)) + 1] = 0;   }   }   }/*********************************************************************************Step : 2 : AXI CDMA Intialization   Association of the CDMA ISR with the Interrupt   Enable the CDMA Interrupt      Provide Source and destination location to CDMA      Specified Number of byte to be transfer to CDMA register       Start the CDMA      Wait for the Interrupt and return the status**********************************************************************************/    Status = XAxiCdma_Interrupt( &IntcController,    &AxiCdmaInstance,    DMA_CTRL_DEVICE_ID,   DMA_CTRL_IRPT_INTR   );   if (Status != XST_SUCCESS) {    printf("XAxiCdma_Interrupt: Failed\r\n");    return XST_FAILURE;    }    xil_printf("XAxiCdma_Interrupt: Passed\r\n");    /*********************************************************************************Step : 3 : Compare Source memory with Destination memory   Return the Status**********************************************************************************/    for (Index = 0; Index < (BUFFER_BYTESIZE/4); Index++)    {    if ( DestPtr[Index] != SrcPtr[Index])    {    printf("Error in Comparison : Index : %x \n\r", Index);    return XST_FAILURE;    }    }    printf("DMA Transfer is Successful \n\r");    return XST_SUCCESS;    return 0;}

进入调试模式,显示arm running,但是,完全进入不了调试模式,没有任何反应...


接下来创建Hello World,连Hello World都调试不了。


通过调试发现,首先问题不是代码问题,底层设计也没有问题,问题应该是出现这种机制上,到底ACP这种接口使用有什么BUG。。


上述,参考官方资料,ACP竟然Standalone模式下无法使用。。。。





0 0