<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > ISA總線(xiàn)的DMA技術(shù)

ISA總線(xiàn)的DMA技術(shù)

作者: 時(shí)間:2011-05-20 來(lái)源:網(wǎng)絡(luò ) 收藏
5.1 通道資源的申請與釋放

本文引用地址:http://dyxdggzs.com/article/150725.htm

  同I/O端口資源類(lèi)似,設備驅動(dòng)程序必須在一開(kāi)始就調用request_dma()函數來(lái)向內核申請通道資源的使用權。而且,最好在設備驅動(dòng)程序的open()方法中完成這個(gè)操作,而不是在模塊的初始化例程中調用這個(gè)函數。因為這在一定程度上可以讓多個(gè)設備共享通道資源(只要多個(gè)設備不同時(shí)使用一個(gè)DMA通道)。這種共享有點(diǎn)類(lèi)似于進(jìn)程對CPU的分時(shí)共享。

  設備使用完DMA通道后,其驅動(dòng)程序應該記得調用free_dma()函數來(lái)釋放所占用的DMA通道資源。通常,最好再驅動(dòng)程序的release()方法中調用該函數,而不是在模塊的卸載例程中進(jìn)行調用。

  還需要注意的一個(gè)問(wèn)題是:資源的申請順序。為了避免死鎖(deadlock),驅動(dòng)程序一定要在申請了中斷號資源后才申請DMA通道資源。釋放時(shí)則要先釋放DMA通道,然后再釋放中斷號資源。

  使用DMA的設備驅動(dòng)程序的open()方法的如下:

  int xxx_open(struct inode * inode, struct file * filp)

  {

  ┆

  if((err = request_irq(irq,xxx_ISR,SA_INTERRUPT,”YourDeviceName”,NULL))

  return err;

  if((err = request_dma(dmanr, “YourDeviceName”)){

  free_irq(irq, NULL);

  return err;

  }

  ┆

  return 0;

  }

  release()方法的范例代碼如下:

  void xxx_release(struct inode * inode, struct file * filp)

  {

  ┆

  free_dma(dmanr);

  free_irq(irq,NULL);

  ┆

  }

  5.2 申請DMA緩沖區

  由于8237 DMAC只能尋址系統RAM中低16MB物理內存,因此:設備驅動(dòng)程序在申請DMA緩沖區時(shí),一定要以GFP_DMA標志來(lái)調用kmalloc()函數或get_free_pages()函數,以便在系統內存的DMA區中分配物理內存。

  5.3 編程DMAC

  設備驅動(dòng)程序可以在他的read()方法、write()方法或ISR中對DMAC進(jìn)行編程,以便準備啟動(dòng)一個(gè)DMA傳輸事務(wù)。一個(gè)DMA傳輸事務(wù)有兩種典型的過(guò)程:(1)用戶(hù)請求設備進(jìn)行DMA傳輸;(2)硬件異步地將外部數據寫(xiě)道系統中。

  用戶(hù)通過(guò)I/O請求觸發(fā)設備進(jìn)行DMA傳輸的步驟如下:

  1.用戶(hù)進(jìn)程通過(guò)系統調用read()/write()來(lái)調用設備驅動(dòng)程序的read()方法或write()方法,然后由設備驅動(dòng)程序read/write方法負責申請DMA緩沖區,對DMAC進(jìn)行編程,以準備啟動(dòng)一個(gè)DMA傳輸事務(wù),最后正確地設置設備(setup device),并將用戶(hù)進(jìn)程投入睡眠。

  2.DMAC負責在DMA緩沖區和I/O外設之間進(jìn)行數據傳輸,并在結束后觸發(fā)一個(gè)中斷。

  3.設備的ISR檢查DMA傳輸事務(wù)是否成功地結束,并將數據從DMA緩沖區中拷貝到驅動(dòng)程序的其他內核緩沖區中(對于I/O device to memory的情況)。然后喚醒睡眠的用戶(hù)進(jìn)程。

  硬件異步地將外部數據寫(xiě)到系統中的步驟如下:

  1.外設觸發(fā)一個(gè)中斷通知系統有新數據到達。

  2.ISR申請一個(gè)DMA緩沖區,并對DMAC進(jìn)行編程,以準備啟動(dòng)一個(gè)DMA傳輸事務(wù),最后正確地設置好外設。

  3.硬件將外部數據寫(xiě)到DMA緩沖區中,DMA傳輸事務(wù)結束后,觸發(fā)一個(gè)中斷。

  4. ISR檢查DMA傳輸事務(wù)是否成功地結束,然后將DMA緩沖區中的數據拷貝驅動(dòng)程序的其他內核緩沖區中,最后喚醒相關(guān)的等待進(jìn)程。

  網(wǎng)卡就是上述過(guò)程的一個(gè)典型例子。

  為準備一個(gè)DMA傳輸事務(wù)而對DMAC進(jìn)行編程的典型代碼段如下:

  unsigned long flags;

  flags = claim_dma_lock();

  disable_dma(dmanr);

  clear_dma_ff(dmanr);

  set_dma_mode(dmanr,mode);

  set_dma_addr(dmanr, virt_to_bus(buf));

  set_dma_count(dmanr, count);

  enable_dma(dmanr);

  release_dma_lock(flags);

  檢查一個(gè)DMA傳輸事務(wù)是否成功地結束的代碼段如下:

  int residue;

  unsigned long flags = claim_dma_lock();

  residue = get_dma_residue(dmanr);

  release_dma_lock(flags);

  ASSERT(residue == 0);


上一頁(yè) 1 2 3 4 下一頁(yè)

關(guān)鍵詞: 技術(shù) DMA 總線(xiàn) ISA

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>