DMA simple mode
时间: 2024-01-08 11:19:31 浏览: 146
H7 HAL驱动概要DM00392525_ENV2.pdf
DMA simple mode是一种AXI DMA传输模式,它可以在不使用中断的情况下进行数据传输。在DMA simple mode下,数据传输是通过轮询方式进行的,即DMA引擎会不断地检查传输是否完成,直到传输完成后再返回。这种模式适用于数据传输量较小的情况,因为在大量数据传输时,轮询方式会占用CPU资源,导致系统性能下降。
以下是使用DMA simple mode进行数据传输的示例代码:
```c
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#define SRC_SIZE 1024
#define DST_SIZE 1024
static struct dma_chan *dma_ch;
static dma_addr_t src_phys, dst_phys;
static void *src_buf, *dst_buf;
static int dma_init(void)
{
int ret;
struct scatterlist sg_src, sg_dst;
struct dma_async_tx_descriptor *tx_desc;
// 分配源和目的缓冲区
src_buf = kmalloc(SRC_SIZE, GFP_KERNEL);
dst_buf = kmalloc(DST_SIZE, GFP_KERNEL);
if (!src_buf || !dst_buf) {
ret = -ENOMEM;
goto err_buf;
}
// 映射源和目的缓冲区的物理地址
src_phys = dma_map_single(NULL, src_buf, SRC_SIZE, DMA_TO_DEVICE);
dst_phys = dma_map_single(NULL, dst_buf, DST_SIZE, DMA_FROM_DEVICE);
if (dma_mapping_error(NULL, src_phys) || dma_mapping_error(NULL, dst_phys)) {
ret = -ENOMEM;
goto err_map;
}
// 初始化DMA通道
dma_ch = dma_request_chan(NULL, "dma0");
if (IS_ERR(dma_ch)) {
ret = PTR_ERR(dma_ch);
goto err_ch;
}
// 初始化scatterlist
sg_init_one(&sg_src, src_phys, SRC_SIZE);
sg_init_one(&sg_dst, dst_phys, DST_SIZE);
// 发起DMA传输
tx_desc = dmaengine_prep_dma_memcpy(dma_ch, dst_phys, src_phys, SRC_SIZE, DMA_PREP_INTERRUPT);
if (!tx_desc) {
ret = -ENOMEM;
goto err_prep;
}
dma_async_issue_pending(dma_ch);
ret = dma_sync_wait(dma_ch, tx_desc);
if (ret) {
goto err_prep;
}
// 打印传输结果
printk(KERN_INFO "DMA transfer completed\n");
// 释放DMA通道
dma_release_channel(dma_ch);
// 解除物理地址映射
dma_unmap_single(NULL, src_phys, SRC_SIZE, DMA_TO_DEVICE);
dma_unmap_single(NULL, dst_phys, DST_SIZE, DMA_FROM_DEVICE);
// 释放缓冲区
kfree(src_buf);
kfree(dst_buf);
return 0;
err_prep:
dma_release_channel(dma_ch);
err_ch:
dma_unmap_single(NULL, dst_phys, DST_SIZE, DMA_FROM_DEVICE);
dma_unmap_single(NULL, src_phys, SRC_SIZE, DMA_TO_DEVICE);
err_map:
kfree(dst_buf);
kfree(src_buf);
err_buf:
return ret;
}
```
阅读全文