wugang589 2017-04-24 02:05 采纳率: 0%
浏览 1434

CDMA传输成功但是实际并没有把源内存空间的值传给目的内存空间

本人在用Vivado CDMA IP核做数据传输实验过程中发现,SDK文件夹下的example cdma代码并没有将源区域的数据传输给目的区域,但是从返回给Status的值来看又是成功传输,不是很能理解。目前猜测或许是声明两块内存区域时,
volatile static u8 SrcBuffer[BUFFER_BYTESIZE] attribute ((aligned (64)));
volatile static u8 DestBuffer[BUFFER_BYTESIZE] attribute ((aligned (64)));
这两个声明语句造成的这个问题,有没有大神了解这方面的,烦请为我解答一二。
如下是SDK代码

 #include "xaxicdma.h"
#include "xdebug.h"
#include "xil_exception.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xintc.h"


#define DMA_CTRL_DEVICE_ID  XPAR_AXICDMA_0_DEVICE_ID
#define INTC_DEVICE_ID      XPAR_INTC_0_DEVICE_ID
#define DMA_CTRL_IRPT_INTR  XPAR_INTC_0_AXICDMA_0_VEC_ID

#define BUFFER_BYTESIZE     8 //Length of the buffers for DMA transfer
#define NUMBER_OF_TRANSFERS  1 //Number of simple transfers to do


static int DoSimpleTransfer(XAxiCdma *InstancePtr, int Length, int Retries);
static void Example_CallBack(void *CallBackRef, u32 IrqMask, int *IgnorePtr);
static int SetupIntrSystem(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
            u32 IntrId);

static void DisableIntrSystem(XIntc *IntcInstancePtr, u32 IntrId);
int XAxiCdma_SimpleIntrExample(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
    u16 DeviceId,u32 IntrId);


static XAxiCdma AxiCdmaInstance;  //Instance of the XAxiCdma
static XIntc IntcController;      //Instance of the Interrupt Controller

/* Source and Destination buffer for DMA transfer. */
volatile static u8 SrcBuffer[BUFFER_BYTESIZE] __attribute__ ((aligned (64)));
volatile static u8 DestBuffer[BUFFER_BYTESIZE] __attribute__ ((aligned (64)));

/* Shared variables used to test the callbacks.*/
volatile static int Done = 0;   //Dma transfer is done
volatile static int Error = 0;  // Dma Bus Error occurs


int main()
{

    int Status;

    xil_printf("\r\n--- Entering main() --- \r\n");

    /* Run the interrupt example for simple transfer
     */
    Status = XAxiCdma_SimpleIntrExample(&IntcController, &AxiCdmaInstance,
            DMA_CTRL_DEVICE_ID,DMA_CTRL_IRPT_INTR);

    if (Status != XST_SUCCESS) {

        xil_printf("XAxiCdma_SimpleIntrExample: Failed\r\n");
        return XST_FAILURE;
    }

    xil_printf("XAxiCdma_SimpleIntrExample: Passed\r\n");

    xil_printf("--- Exiting main() --- \r\n");

    return XST_SUCCESS;

}

int XAxiCdma_SimpleIntrExample(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
    u16 DeviceId,u32 IntrId)
{
    XAxiCdma_Config *CfgPtr;
    int Status;
    int SubmitTries = 10;       /* Retry to submit */
    int Tries = NUMBER_OF_TRANSFERS;
    int Index;

    /* Initialize the XAxiCdma device.
     */
    CfgPtr = XAxiCdma_LookupConfig(DeviceId);
    if (!CfgPtr) {
        return XST_FAILURE;
    }
    else
        xil_printf("Config Success\n");

    Status = XAxiCdma_CfgInitialize(InstancePtr, CfgPtr, CfgPtr->BaseAddress);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    else
        xil_printf("Config Initialize Success\n");

    /* Setup the interrupt system
     */
    Status = SetupIntrSystem(IntcInstancePtr, InstancePtr, IntrId);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    else
        xil_printf("Setup IntrSystem Success\n");

    /* Enable all (completion/error/delay) interrupts
     */
    XAxiCdma_IntrEnable(InstancePtr, XAXICDMA_XR_IRQ_ALL_MASK);

    for (Index = 0; Index < Tries; Index++) {
        Status = DoSimpleTransfer(InstancePtr,
               BUFFER_BYTESIZE, SubmitTries);

        if(Status != XST_SUCCESS) {
            DisableIntrSystem(IntcInstancePtr, IntrId);
            return XST_FAILURE;
        }
        else
            xil_printf("DoSimpleTransfer Success\n");
    }

    /* Test finishes successfully, clean up and return
     */
    DisableIntrSystem(IntcInstancePtr, IntrId);

    return XST_SUCCESS;
}

/* This function does one simple transfer
InstancePtr is a pointer to the XAxiCdma instance
Length is the transfer length
Retries is how many times to retry on submission
*/
static int DoSimpleTransfer(XAxiCdma *InstancePtr, int Length, int Retries)
{
    u32 Index;
    u8  *SrcPtr;
    u8  *DestPtr;
    int Status;

    Done = 0;
    Error = 0;

    /* Initialize the source buffer bytes with a pattern and the
     * the destination buffer bytes to zero
     */
    SrcPtr = (u8 *)SrcBuffer;
    DestPtr = (u8 *)DestBuffer;
    for (Index = 0; Index < Length; Index++) {
        SrcPtr[Index] = Index & 0xFF;
        DestPtr[Index] = 0;
    }
    xil_printf("Source and Destination Buffer Initialization Success\n");

    /* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
     * is enabled
     */
    Xil_DCacheFlushRange((UINTPTR)&SrcBuffer, Length);
//#ifdef __aarch64__
    Xil_DCacheFlushRange((UINTPTR)&DestBuffer, Length);
//#endif
    xil_printf("Flush Source and Destination Success\n");

    /* Try to start the DMA transfer
     */
    while (Retries) {
        Retries --;

        Status = XAxiCdma_SimpleTransfer(InstancePtr, (u32)SrcBuffer,
            (u32)DestBuffer, Length, Example_CallBack,
            (void *)InstancePtr);

        if (Status == XST_SUCCESS) {
            xil_printf("CDMA Transfer Success\n");
            break;
        }
        else
            xil_printf("CDMA SimpleTransfer Fail\n");
    }

    /*if (Retries) {
        xil_printf("1 Fail\n");
        return XST_FAILURE;
    }*/

    /* Wait until the DMA transfer is done
     */
    while (!Done && !Error) {
        /* Wait */
    }

    if (Error) {
        xil_printf("Error Occur\n");
        return XST_FAILURE;
    }

    /* Invalidate the DestBuffer before receiving the data, in case the
     * Data Cache is enabled
     */
//#ifndef __aarch64__
    Xil_DCacheInvalidateRange((UINTPTR)&DestBuffer, Length);
//#endif

    /* Transfer completes successfully, check data
     *
     * Compare the contents of destination buffer and source buffer
     */
    for (Index = 0; Index < Length; Index++) {
        if ( DestPtr[Index] != SrcPtr[Index]) {
            xil_printf("Source and Destination not Match\n");
            /*for(u32 i = 0;i < Length; i++)
            {
                xil_printf("\nsrc:%x,dest:%x\n",SrcPtr[i],DestPtr[i]);
            }*/
            //return XST_FAILURE;
        }
        else
            xil_printf("Source and Destination Match\n");

    }

    return XST_SUCCESS;
}


static int SetupIntrSystem(XIntc *IntcInstancePtr, XAxiCdma *InstancePtr,
            u32 IntrId)
{
    int Status;


    /*
     * Initialize the interrupt controller driver
     */
    Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }


    /*
     * Connect the driver interrupt handler
     * It will call the example callback upon transfer completion
     */
    Status = XIntc_Connect(IntcInstancePtr, IntrId,
            (XInterruptHandler)XAxiCdma_IntrHandler,
            (void *)InstancePtr);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }


    /*
     * Start the interrupt controller such that interrupts are enabled for
     * all devices that cause interrupts. Specify real mode so that the DMA
     * engine can generate interrupts through the interrupt controller
     */
    Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }


    /*
     * Enable the interrupt for the DMA engine
     */
    XIntc_Enable(IntcInstancePtr, IntrId);



    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler)XIntc_InterruptHandler,
            (void *)IntcInstancePtr);

    Xil_ExceptionEnable();

    return XST_SUCCESS;
}


/*Callback function for the simple transfer. It is called by the driver's
  interrupt handler.
  CallBackRef is the reference pointer registered through
  transfer submission. In this case, it is the pointer to the
  driver instance
  IrqMask is the interrupt mask the driver interrupt handler
  passes to the callback function.
  IgnorePtr is a pointer that is ignored by simple callback
  function*/
static void Example_CallBack(void *CallBackRef, u32 IrqMask, int *IgnorePtr)
{

    if (IrqMask & XAXICDMA_XR_IRQ_ERROR_MASK) {
        Error = FALSE;
        //Error = TRUE;
        //xil_printf("Error 1\n");
    }

    if (IrqMask & XAXICDMA_XR_IRQ_IOC_MASK) {
        Done = TRUE;
        xil_printf("CDMA Transfer Done\n");
    }

}

static void DisableIntrSystem(XIntc *IntcInstancePtr, u32 IntrId)
{

    /* Disconnect the interrupt
     */
    XIntc_Disconnect(IntcInstancePtr, IntrId);

}
  • 写回答

1条回答 默认 最新

  • wugang589 2017-04-24 03:02
    关注

    重新声明了SrcBuffer和DestBuffer后还是一样的问题,难道是我的传输过程中出了问题?因为在_Example_Callback函数的Error返回值测试时为True,我当时以为前面Status值为XST_SUCCESS应该是传输没问题,但是现在问题还是没有解决。在Example_Callback函数中修改成Error上=Ture后,上板测试的结果为
    --- Entering main() ---
    Config Success
    Config Initialize Success
    Setup IntrSystem Success
    Source and Destination Buffer Initialization Success
    Flush Source and Destination Success
    Error 1
    CDMA Transfer Done
    CDMA Transfer Success
    Error Occur
    XAxiCdma_SimpleIntrExample: Failed

    目前真的不知道哪里有问题了,有没有知道这方面的大神,能否为我解答一下?

    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作