<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > s3c2440的dma操作的一般步驟

          s3c2440的dma操作的一般步驟

          作者: 時間:2016-11-19 來源:網絡 收藏
          s3c2440dma操作的一般步驟

          一般的,在s3c2440中,要想進行dma傳輸,需要一下七個步驟:

          本文引用地址:http://www.ex-cimer.com/article/201611/318126.htm

          一:
          int s3c2410_dma_request(unsigned int channel,
          struct s3c2410_dma_client *client,
          void *dev)

          s3c2410_dma_client的定義為:
          struct s3c2410_dma_client {
          char *name;
          };
          以uda1314的驅動為例,驅動中定義了兩個s3c2410_dma_client
          static struct s3c2410_dma_client s3c2410iis_dma_out= {
          .name = "I2SSDO",
          };

          static struct s3c2410_dma_client s3c2410iis_dma_in = {
          .name = "I2SSDI",
          };


          二:
          s3c2410_dma_config(dmach_t channel,int xferunit,int dcon)

          s3c2410_dma_config(dmach_t channel,int xferunit,int dcon)
          根據xferunit以及dcon設置通道的控制寄存器DCONx
          xferunit為每次傳輸?shù)臄?shù)據大?。?:byte 1:half word 2:word


          三:

          int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)

          設置相應的dma通道完成一次dma傳輸后的回調函數(shù),也即是s3c2410_dma_enqueue完成后會調用的函數(shù)
          回調函數(shù)應具有一下格式:
          typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
          void *buf, int size,
          enum s3c2410_dma_buffresult result);
          buf可以傳遞一些有用的數(shù)據,在uda1314的驅動中,傳遞的是audio_buf_t結構體


          四:
          int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)

          在1314驅動中,
          flags = S3C2410_DMAF_AUTOSTART;
          s3c2410_dma_setflags(channel, flags);


          五:

          int s3c2410_dma_devconfig(int channel,
          enum s3c2410_dmasrc source,
          int hwcfg,
          unsigned long devaddr)

          參數(shù)意義:
          * source: S3C2410_DMASRC_HW: source is hardware
          * S3C2410_DMASRC_MEM: source is memory
          *
          * hwcfg: the value for xxxSTCn register,
          * bit 0: 0=increment pointer, 1=leave pointer
          * bit 1: 0=soucre is AHB, 1=soucre is APB
          *
          * devaddr: physical address of the source

          如果source為S3C2410_DMASRC_HW(外設), 配置它的S3C2410_DMA_DISRCC,S3C2410_DMA_DISRC,S3C2410_DMA_DIDSTC
          如果source為S3C2410_DMASRC_MEM(內存),配置它的S3C2410_DMA_DISRCC,S3C2410_DMA_DIDST,S3C2410_DMA_DIDSTC
          由此可見,地址方面,只配置涉及外設的地址
          以uda1341的驅動為例,這幾個值為
          source = S3C2410_DMASRC_MEM;
          hwcfg = 3;
          devaddr = 0x55000010;

          六:
          void *dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *dma_handle,int flag)

          利用此函數(shù),申請dmabuf,建立一致性映射
          以uda1314的驅動為例,調應的實例為:
          dmabuf = dma_alloc_coherent(NULL, dmasize, &dmaphys, GFP_KERNEL);(在audio_setup_buf函數(shù)中)
          dmabuf為虛擬地址,dmaphys是總線地址,虛擬地址用來讓驅動寫buf用,dmaphys用來傳給dma。
          dma關心的是總線地址。
          關于總線地址與物理地址的區(qū)別,這里有很好的說明http://hi.baidu.com/zengzhaonong/blog/item/eeb8003083276e9ba9018ee3.html,感謝儒雅,現(xiàn)摘錄如下:
          1) 物理地址是與CPU相關的。在CPU的地址信號線上產生的就是物理地址。在程序指令中的虛擬地址經過段映射和頁面映射后,就生成了物理地址,這個物理地址被放到CPU的地址線上。
          2) 總線地址,顧名思義,是與總線相關的,就是總線的地址線或在地址周期上產生的信號。外設使用的是總線地址。
          3) 物理地址與總線地址之間的關系由系統(tǒng)的設計決定的。在x86平臺上,物理地址與PCI總線地址是相同的。在其他平臺上,也許會有某種轉換,通常是線性的轉換。

          比如:CPU需要訪問物理地址是0xfa000的單元,那么在x86平臺上,會產生一個PCI總線上對0xfa000地址的訪問。這個單元或者是內存中,或者是某個卡上的存儲單元,甚至可能這個地址上沒有對應的存儲器。而在另外一個平臺上,或許在PCI總線上產生的訪問是針對地址為0x1fa000的單元。
          上述函數(shù)是建立一致性映射。使用dma_map_single函數(shù)可以建立一致性映射:
          2.當只有一個緩沖區(qū)要被傳輸?shù)臅r候,使用dma_map_single函數(shù)來映射它
          dma_addr_t dma_map_single(struct device *dev,void *buffer,size_t size, enum dma_data_direction direction)
          3.為page結構指針指向的緩沖區(qū)建立映射,單頁流式映射:
          dma_addr_t dma_map_page(struct device *dev,struct page *page ,unsigned long offset ,size_t size,enum dma_data_direction direction);
          4.分散/聚集映射
          int dma_map_sg(struct device *dev,struct scatterlist *sg,int nents,enum dma_alloc_coherent direction);
          還不知道哪種情況下用流式映射,哪種用一致映射。對于s3c2440,其mmc驅動中用到了分散聚集(流式)映射,聲卡驅動中又用到了一致映射。


          七:
          int s3c2410_dma_enqueue(unsigned int channel, void *id,
          dma_addr_t data, int size)

          發(fā)起一次dma傳輸
          參數(shù)意義:
          * id the device drivers id information for this buffer
          * data the physical address of the buffer data
          * size the size of the buffer in bytes
          將dma_alloc_coherent中得到的dmaphys傳遞給s3c2410_dma_enqueue. s3c2410_dma_enqueue提交一次dma請求,當dma通道可用的時候通過s3c2410_dma_loadbuffer開始一次傳輸,傳輸完成后會產生irq中斷。其dma的中斷服務函數(shù)中會繼續(xù)啟動dma請求隊列中的請求,傳輸剩下的數(shù)據。



          關鍵詞: s3c2440dma操

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();