我正在一个项目中,其中模块A 具有一个具有DMA内容的内存缓冲区,并调用模块B 的功能来执行DMA操作。简单起见,如下所示:
模块A:
void get_info()
{
void *outBuffer = kmalloc(10);
void *inBuffer = kmalloc(10);
perform_dma(outBuffer); // function from module B
read_output(&inBuffer); // function from module B
}
模块B:
void perform_dma(void *outBuffer)
{
void *dma_buffer = dma_alloc_coherent() // <-- allocate a new DMA buffer
memcpy(dma_buffer, outBuffer, 10);
do_dma(); // <-- after this is done, dma_buffer has the content module A needs.
}
void read_output(void **inBuffer)
{
memcpy(*inBuffer, dma_buffer, 10);
}
我知道这可能不太有效,但是我无法更改 B模块,并且只能使用提供的API。在最佳情况下,我可以将 B 的perform_dma(void *outBuffer)
原型更改为perform_dma(void **outBuffer)
。它大部分时间都有效,但是在某种情况下(由于整个项目中涉及的所有中断/队列事件),我将无法显式调用read_output()
并提供inBuffer
来读取内容但只能将outBuffer
地址发送到 B 后访问。
有没有一种方法可以将模块{em> A 中的outBuffer
映射到模块 B 中分配的dma_buffer
,以便能够读取输出从同一outBuffer
返回?
答案 0 :(得分:0)
我发现dma_map_single()/ dma_unmap_single()在我的情况下有效。根本不需要更改功能原型。只需在perform_dma()中使用dma_map_single(outBuffer ....,DMA_BIDIRECTIONAL)来获取总线地址并将其传递给dma控制器,这样在DMA完成后,outBuffer将从dma控制器返回内容。