简单DMA介绍

最早接触DMA的时候是大三的微机原理,当时不是很理解,什么DMA模式啊,只知道是传输速度快,不经过CPU,但是到底是怎么样的不经过CPU呢?还是不理解。这次I2C控制器里面带了DMA的模式,所以有机会去接触下了。

       而具体的DMA的意思是什么http://baike.baidu.com/view/32471.htm,百度百科里还是不错的。

 

DMA的工作过程:

 

       对于嵌入式中的DMA,其实是在写数据寄存器的时候用dma的传输来代替。就像i2c设备,在发送和接收数据的时候都是要往数据寄存器中写数据的。比如那个寄存器是I2C_DATA,如果用cpu来传输的话就是writel(data, I2C_DATA);而用dma传输就是配置好要传输的buf长度,然后源地址就是buf的地址,目标地址就是I2C_DATA。

       这里还要注意经过cpu的是虚拟地址,而dma传输的是物理地址。

       其实dma传输就是dma控制在两个物理地址之间传输数据。

 

Linux下用dma传输主要调用下面这些函数就可以实现外部的dma了。

 

具体的就可以看下面简单的解释,以下主要是dma发送的,其实接收也一样的。配置反一下就可以了。

1、初始化DMA

 

 
  1. dma_cap_zero(mask);

  2. dma_cap_set(DMA_SLAVE,mask);

  3.  
  4. /*1. Init rx channel */

  5. dws->rxchan= dma_request_channel(mask, dma_chan_filter, params);

  6. 主要就是申请DMA通道。

  7.  
  8. dma_chan_filter这个函数主要是查找你的dma传输的设备的请求信号线,其具体是在注册时填写的。

  9. 这里会根据这个函数返回的真假来判断已经注册在总线上的dma slave的。

  10.  
  11.  
  12. buf =kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL);

  13. //申请一块地址,用来DMA传输的数据就放在这里

  14. sg_init_one(&dma_dev->dmatx.sg, buf, DMA_BUFFER_SIZE);

  15. //初始化,其主要为了发送时虚拟地址和物理地址的映射。

 

 

 

2、启动DMA

 

 
  1. struct dma_async_tx_descriptor *txdesc = NULL;

  2. struct dma_chan *txchan,;

  3. struct dma_slave_config txconf;

  4.  
  5. txchan= dws->txchan;

  6.  
  7. /*2. Prepare the TX dma transfer */

  8. txconf.direction= DMA_TO_DEVICE; //表示dma传输方向为发送

  9. txconf.dst_addr= dws->dma_addr; //目标地址,物理地址

  10. txconf.dst_maxburst= LNW_DMA_MSIZE_16; //最大传输的字节数

  11. txconf.dst_addr_width= DMA_SLAVE_BUSWIDTH_2_BYTES; //数据的位宽

  12.  
  13. txchan->device->device_control(txchan,DMA_SLAVE_CONFIG,

  14. (unsigned long) &txconf);

  15.  
  16. dws->tx_sgl.length= dws->len; //要传输的数据的长度

  17.  
  18. dma_map_sg(dma_dev->dev,&dmatx->sg, 1, DMA_TO_DEVICE);

  19. //通过这个函数来实现虚拟地址和物理地址的映射。

  20.  
  21. txdesc= txchan->device->device_prep_slave_sg(txchan,

  22. &dws->tx_sgl,

  23. 1,

  24. DMA_TO_DEVICE,

  25. DMA_PREP_INTERRUPT| DMA_COMPL_SKIP_DEST_UNMAP);

  26. txdesc->callback= dw_spi_dma_done; //传输完成后的回调函数

  27. txdesc->callback_param= params; //回调函数中的参数

  28.  
  29. dmaengine_submit(txdesc);

  30. dma_dev->device_issue_pending(txchan); // 启动dma传输了

 

 

配置好后,这样DMA就会开始传输了,然后传输完了以后就会有调用callback函数。

 

转自:https://blog.youkuaiyun.com/eastmoon502136/article/details/8502087

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值