日期:2014-05-16  浏览次数:21313 次

dma可以替代memcpy吗
我的程序用双缓存绘图(直接操作framebuffer)
每次需要2次memcpy操作, 屏幕数据600k
每次执行memcpy经测试需要15ms, 这样2次就30ms
在考虑执行其他任务的情况下, 速度更低
硬件是OMAPL138 (arm926 ejs)

dma不知道可不可以做到内存之间直接拷贝, 如果可以, 速度会提高多少?

还有最好有示例代码, 网上找的例子和linux内核的例子不是遍不过去就是无法执行

------解决方案--------------------
在内核中调用EDMA的实例代码,平台DM6446
C/C++ code

int edma3_memtomemcpy(struct edma_linux_params *params)
{
    int result = 0;
    int i;
    unsigned int numenabled = 0;
    struct paramentry_descriptor param_set;
    unsigned int dma_ch;
    unsigned int tcc = EDMA_TCC_ANY;
    result = davinci_request_dma(EDMA_DMA_CHANNEL_ANY, "A-SYNC_DMA0",
                     edma_callback, NULL,
                     &dma_ch, &tcc, 0);
    if (0 != result) {
        DMA_PRINTK
            ("\nedma3_memtomemcpytest_dma::davinci_request_dma failed for dma_ch, error:%d\n",
             result);
        return result;
    }

    davinci_set_dma_src_params(dma_ch, (unsigned long)(params->src),
                   INCR, W8BIT);

    davinci_set_dma_dest_params(dma_ch, (unsigned long)(params->dst),
                    INCR, W8BIT);

    davinci_set_dma_src_index(dma_ch, params->srcbidx, params->srccidx);

    davinci_set_dma_dest_index(dma_ch, params->dstbidx, params->dstcidx);

    /* AB Sync Transfer Mode */
    davinci_set_dma_transfer_params(dma_ch, params->acnt, params->bcnt, params->ccnt,
             params->bcnt, ABSYNC);

    /* Enable the Interrupts on Channel 1 */
    davinci_get_dma_params(dma_ch, &param_set);
    param_set.opt |= (1 << ITCINTEN_SHIFT);
    param_set.opt |= (1 << TCINTEN_SHIFT);
    davinci_set_dma_params(dma_ch, &param_set);

    numenabled = params->ccnt;

    for (i = 0; i < numenabled; i++) {
        irqraised1 = 0;

        /* Now enable the transfer as many times as calculated above. */
        result = davinci_start_dma(dma_ch);
        if (result != 0) {
            DMA_PRINTK
                ("edma3_memtomemcpytest_dma: davinci_start_dma failed \n");
            break;
        }

        /* Wait for the Completion ISR. */
        while (irqraised1 == 0u) ;

        /* Check the status of the completed transfer */
        if (irqraised1 < 0) {
            /* Some error occured, break from the FOR loop. */
            DMA_PRINTK("edma3_memtomemcpytest_dma: "
                   "Event Miss Occured!!!\n");
            break;
        }
    }
    davinci_stop_dma(dma_ch);
    davinci_free_dma(dma_ch);
    return result;
}

------解决方案--------------------
1. DMA可以用作M2M.
2. 用DMA进行传输的话,速度会比你之前提高很多,多少的话要视环境而定,你可以测出来。
但单拿CPU拷贝和DMA拷贝的速度进行对比的话,感觉CPU要快点。