menglongcaiying 2016-08-15 03:42 采纳率: 0%
浏览 3758

关于pcie dma传输的问题

小弟最近在做pcie dma传输的程序,现在碰到一个很奇怪的问题。程序要实现对dma传输
12m的数据。程序轮训传输12m数据,但程序传输了几次12m数据后,dma传输函数会返回ApiDmaInProgress dma。
程序:

int Dma(PLX_DEVICE_OBJECT *pDevice, char *pUserBuffer, int UserBufferLen, int wr_addr)
{

U8                DmaChannel;
U16               ChannelInput;
PLX_STATUS        rc;
PLX_DMA_PROP      DmaProp;
PLX_DMA_PARAMS    DmaParams;
PLX_PHYSICAL_MEM  PciBuffer;
int               count = 0;
int               len = 0;

int cpld_idea = 0;
int data_value = 0;
int dma_count = 0; 
int retry_times = 0;
int ret = 0;
char            *buffer = NULL; 
int             j = 0; 
int             offset = 0; 


ChannelInput = 0; 
DmaChannel = (U8)ChannelInput;

buffer = (char *)malloc(4096); 
if(buffer == NULL) 
{
    Cons_printf("xbuffer malloc memory err\n"); 
    return ERR_MALLOC_MEM_ERR; 
}

count = UserBufferLen / 4096; 
offset = UserBufferLen % 4096;
// Get DMA buffer parameters
//ret = Read_Cpld_Idea(pDevice, &cpld_idea);
rc = PlxPci_DeviceReset(pDevice);
if (rc != ApiSuccess)
{
    Cons_printf("*ERROR* - API failed to reset\n");
    ret = ERR_OPEN_DMA_FAIL;
}
//cpld_idea = 0;
//ret = Read_Cpld_Idea(pDevice, &cpld_idea);
rc = PlxPci_CommonBufferProperties(pDevice,&PciBuffer);
if (rc != ApiSuccess)
{
    Cons_printf("*ERROR* - API failed\n");
    ret = ERR_OPEN_DMA_FAIL;
}
// Clear DMA structure
memset(&DmaProp, 0, sizeof(PLX_DMA_PROP));
// Initialize the DMA channel
DmaProp.LocalBusWidth = 3;   // 32-bit
DmaProp.ReadyInput    = 1;
DmaProp.ConstAddrLocal = 1; 

rc =PlxPci_DmaChannelOpen(pDevice,DmaChannel,&DmaProp);
if (rc != ApiSuccess)
{
    Cons_printf("*ERROR* - API failed\n");
    ret = ERR_OPEN_DMA_FAIL;
}

// Clear DMA data
for(j = 0; j < count + 1; j++) 
{
    Delay_Us(50); 
    if(j == count)
    {
        len = offset;
    }
    else
    {
        len = 4096; 
    }

    memset(buffer, 0, 4096);
    memcpy(buffer, pUserBuffer + j * 4096, 4096); 

    memset(&DmaParams, 0, sizeof(PLX_DMA_PARAMS));
    // Clear DMA data
    memset(&DmaParams, 0, sizeof(PLX_DMA_PARAMS));

    DmaParams.UserVa    = (PLX_UINT_PTR)buffer;
    DmaParams.LocalAddr = wr_addr;
    DmaParams.ByteCount = len;
    DmaParams.Direction = PLX_DMA_PCI_TO_LOC;
    // Specify a timeout to let API perform wait
    //ASCIIToHex(buffer, len); 
    rc =PlxPci_DmaTransferUserBuffer(pDevice,DmaChannel,&DmaParams,0);         

    while(1)
    {
        do
        {
            rc = PlxPci_DmaStatus(pDevice, 0); 
            retry_times++;
        }
        while (rc == ApiDmaInProgress && retry_times <= 1000000); 

        switch (rc)
        {
            case ApiDmaDone:
                //Cons_printf("Ok (DMA ApiDmaDone)\n");
                ret = 0;
                break;

            case ApiDmaInProgress:
                Cons_printf("*ERROR* -DMA ApiDmaInProgress\n");
                ret = ERR_DMA_ALWAYS_INPROGESS;
                goto FAIL;

            default:
                Cons_printf("*ERROR* - API failed\n");
                ret = ERR_DMA_OTHER_ERR;
                goto FAIL ;
        }
        break; 
    } 
    ret = Read_Dma_Count(pDevice, &dma_count);
    if(ret)
    { 
        Cons_printf("Read_Dma_Count\n");
        goto FAIL;      
    }
    //cpld_idea = 0;
    //ret = Read_Cpld_Idea(pDevice, &cpld_idea);

    ret = Read_Dma_To_Fpga_Data(pDevice, &data_value);
    if(ret)
    { 
        Cons_printf("Read_Dma_Count\n");
        goto FAIL;      
    }

}

if(UserBufferLen != dma_count)
{ 
    Cons_printf("UserBufferLen = %d, count = %d\n", UserBufferLen, dma_count);
    ret = ERR_DMA_TRANSLATE_ERR;
    goto FAIL;          
}

FAIL:
// Close DMA Channel
//Cons_printf(" Close DMA Channel.............. ");
rc =PlxPci_DmaChannelClose(pDevice,DmaChannel);
if (rc != ApiSuccess)
{
Cons_printf("*ERROR* - API failed\n");
PlxPci_DeviceReset(pDevice);
ret = ERR_CLOSE_DMA_FAIL;
}
PlxPci_DmaChannelClose(pDevice,DmaChannel);
free(buffer);

return ret;

}

  • 写回答

2条回答 默认 最新

报告相同问题?

悬赏问题

  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集