使用 DMA 内核模块从保留内存复制数据

时间:2021-05-25 12:43:58

标签: module kernel fpga dma

我们正在开发一个自定义模块,它将读取由 FPGA 写入的数据到保留的内存位置。一旦数据准备好,就会触发一个中断来警告模块它可以读取数据(读取部分在一个tasklet中完成)。

目前,我们使用 memremap 将物理地址映射到虚拟地址。之后,我们使用 memcpy 将缓冲区数据复制到内核中的缓冲区中。

主要问题是 memcpy 太慢了(对于每像素 8 位的 1280*480 像素图像,我们无法每秒读取 60 帧)。看来正确的做法应该是使用 DMA 引擎来加速复制。

尽管搜索了很长时间,但我找不到演示如何执行此操作的示例? 我看到如果你保留内存,你可以使用 dma_alloc_coherent 分配其中的一些。但是我想指定保留内存中物理缓冲区的偏移量(就像我在使用 memremap 时所做的那样)。

我目前拥有的是:

    dma_cap_mask_t              _dma_cap_mask;
    struct dma_chan             *_dma_channel;
    struct dma_slave_config     _dma_cfg;

    dma_cap_zero(_dma_cap_mask);
    dma_cap_set(DMA_MEMCPY, _dma_cap_mask);
    _dma_channel = dma_request_channel(_dma_cap_mask, NULL, NULL);
    if (!p3v4l2fg._dma_channel) {
        PRINT_ERROR("Cannot request DMA channel\n");
        ret = -ENODEV;
        goto failure;
    }

    _dma_cfg.direction = DMA_MEM_TO_MEM;
    _dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_32_BYTES;

    dmaengine_slave_config(_dma_channel, &_dma_cfg);

根据我的理解,执行前面的代码可以让我拥有一个 DMA 通道,但是从那里开始,正如我上面所解释的,我有点迷失了 :|

如何替换下面的逻辑

void * data = buf->data;
vaddr = memremap(paddr, singleBufferSize, MEMREMAP_WB);
memcpy(data, vaddr, singleBufferImSize);

使用 DMA 传输? (paddr 是保留内存范围内的物理地址,singleBufferSize 是我必须复制的字节数)。

非常感谢有人能给我的任何帮助!

你的,

Pi-r

0 个答案:

没有答案
相关问题