DMA330 内存到内存搬运代码

时间: 2024-03-23 19:19:01 浏览: 13
下面是一个简单的DMA330内存到内存搬运代码示例,假设源地址为src_addr,目标地址为dst_addr,搬运大小为size: ``` #include <linux/dmaengine.h> #include <linux/dma-mapping.h> #define DMA_BUF_SIZE 4096 void dma_memcpy(void *dst_addr, void *src_addr, size_t size) { struct dma_chan *chan; struct scatterlist sg_src, sg_dst; dma_addr_t src_dma_addr, dst_dma_addr; void *dma_buf; int ret; dma_buf = dma_alloc_coherent(NULL, DMA_BUF_SIZE, &src_dma_addr, GFP_KERNEL); if (!dma_buf) { pr_err("Failed to allocate DMA buffer\n"); return; } chan = dma_request_chan(NULL, "dma0"); if (IS_ERR(chan)) { pr_err("Failed to request DMA channel\n"); dma_free_coherent(NULL, DMA_BUF_SIZE, dma_buf, src_dma_addr); return; } sg_init_table(&sg_src, 1); sg_set_buf(&sg_src, src_addr, size); sg_init_table(&sg_dst, 1); sg_set_buf(&sg_dst, dma_buf, size); ret = dma_map_sg(chan->device->dev, &sg_src, 1, DMA_TO_DEVICE); if (ret != 1) { pr_err("Failed to map SG list for source\n"); dma_release_channel(chan); dma_free_coherent(NULL, DMA_BUF_SIZE, dma_buf, src_dma_addr); return; } ret = dma_map_sg(chan->device->dev, &sg_dst, 1, DMA_FROM_DEVICE); if (ret != 1) { pr_err("Failed to map SG list for destination\n"); dma_unmap_sg(chan->device->dev, &sg_src, 1, DMA_TO_DEVICE); dma_release_channel(chan); dma_free_coherent(NULL, DMA_BUF_SIZE, dma_buf, src_dma_addr); return; } ret = dmaengine_prep_dma_memcpy(chan, dst_dma_addr, src_dma_addr, size, DMA_PREP_INTERRUPT); if (ret) { pr_err("Failed to prepare DMA transfer\n"); dma_unmap_sg(chan->device->dev, &sg_src, 1, DMA_TO_DEVICE); dma_unmap_sg(chan->device->dev, &sg_dst, 1, DMA_FROM_DEVICE); dma_release_channel(chan); dma_free_coherent(NULL, DMA_BUF_SIZE, dma_buf, src_dma_addr); return; } ret = dmaengine_submit(chan); if (ret) { pr_err("Failed to submit DMA transfer\n"); dma_unmap_sg(chan->device->dev, &sg_src, 1, DMA_TO_DEVICE); dma_unmap_sg(chan->device->dev, &sg_dst, 1, DMA_FROM_DEVICE); dma_release_channel(chan); dma_free_coherent(NULL, DMA_BUF_SIZE, dma_buf, src_dma_addr); return; } dma_async_issue_pending(chan); ret = dma_sync_sg_for_device(chan->device->dev, &sg_src, 1, DMA_TO_DEVICE); if (ret != 1) { pr_err("Failed to sync SG list for source\n"); } ret = dma_sync_sg_for_cpu(chan->device->dev, &sg_dst, 1, DMA_FROM_DEVICE); if (ret != 1) { pr_err("Failed to sync SG list for destination\n"); } memcpy(dst_addr, dma_buf, size); dma_unmap_sg(chan->device->dev, &sg_src, 1, DMA_TO_DEVICE); dma_unmap_sg(chan->device->dev, &sg_dst, 1, DMA_FROM_DEVICE); dma_release_channel(chan); dma_free_coherent(NULL, DMA_BUF_SIZE, dma_buf, src_dma_addr); } ``` 该示例中,首先通过dma_alloc_coherent()函数分配DMA缓冲区,然后通过dma_request_chan()函数请求DMA通道,接着通过sg_init_table()和sg_set_buf()函数初始化源和目标scatterlist。然后通过dma_map_sg()函数将scatterlist映射到DMA地址空间中。接下来,通过dmaengine_prep_dma_memcpy()函数准备DMA传输,并通过dmaengine_submit()函数提交传输。最后,通过dma_async_issue_pending()函数发出异步传输请求,并通过dma_sync_sg_for_device()和dma_sync_sg_for_cpu()函数同步scatterlist。最终,通过memcpy()函数将DMA缓冲区中的数据复制到目标地址中,最后释放DMA资源。

相关推荐

最新推荐

recommend-type

Linux内存管理MMAP與DMA

MMAP與DMA主要是描述用於控管記憶體的各種資料結構,相當冗長.有了必要的基礎知識後,我們就可以開始使用這些結構.
recommend-type

STM32 DMA使用详解

DMA部分我用到的相对简单,当然,可能这是新东西,我暂时还用不到它的复杂功能吧。下面用问答的形式表达我的思路。
recommend-type

调试SPI+DMA的一点心得

由于项目需要,STM32F303跟STM32F405之间要用到DMA+SPI口来估大量数据传输,实现两边的数据收发。
recommend-type

STM32的使用之SPI通信DMA模式

MCU:STM32F303VC,在SPI通信中,可以同时开启发送和接收DMA请求,自动数据的发送和接收,完成数据的交换。
recommend-type

STM32定时器触发ADC +DMA

2、把ADC设置成连续转换模式,同时对应的DMA通道开启循环模式,这样ADC就一直在进行数据采集然后通过DMA把数据搬运至内存。但是这样做的话还得加一个定时中断,用来定时读取内存中的数据! 3、使用ADC的定时器触发...
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

list根据id查询pid 然后依次获取到所有的子节点数据

可以使用递归的方式来实现根据id查询pid并获取所有子节点数据。具体实现可以参考以下代码: ``` def get_children_nodes(nodes, parent_id): children = [] for node in nodes: if node['pid'] == parent_id: node['children'] = get_children_nodes(nodes, node['id']) children.append(node) return children # 测试数
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。