• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > ISA總線的DMA技術

    ISA總線的DMA技術

    作者: 時間:2011-05-20 來源:網絡 收藏
    5.1 通道資源的申請與釋放

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

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

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

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

      使用DMA的設備驅動程序的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物理內存,因此:設備驅動程序在申請DMA緩沖區時,一定要以GFP_DMA標志來調用kmalloc()函數或get_free_pages()函數,以便在系統內存的DMA區中分配物理內存。

      5.3 編程DMAC

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

      用戶通過I/O請求觸發設備進行DMA傳輸的步驟如下:

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

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

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

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

      1.外設觸發一個中斷通知系統有新數據到達。

      2.ISR申請一個DMA緩沖區,并對DMAC進行編程,以準備啟動一個DMA傳輸事務,最后正確地設置好外設。

      3.硬件將外部數據寫到DMA緩沖區中,DMA傳輸事務結束后,觸發一個中斷。

      4. ISR檢查DMA傳輸事務是否成功地結束,然后將DMA緩沖區中的數據拷貝驅動程序的其他內核緩沖區中,最后喚醒相關的等待進程。

      網卡就是上述過程的一個典型例子。

      為準備一個DMA傳輸事務而對DMAC進行編程的典型代碼段如下:

      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);

      檢查一個DMA傳輸事務是否成功地結束的代碼段如下:

      int residue;

      unsigned long flags = claim_dma_lock();

      residue = get_dma_residue(dmanr);

      release_dma_lock(flags);

      ASSERT(residue == 0);


    上一頁 1 2 3 4 下一頁

    關鍵詞: 技術 DMA 總線 ISA

    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 济阳县| 濉溪县| 东兰县| 和顺县| 文水县| 淮滨县| 花莲县| 延津县| 旅游| 澎湖县| 搜索| 乳源| 恩平市| 祁东县| 孝义市| 罗城| 太仓市| 海原县| 利辛县| 云阳县| 西宁市| 繁昌县| 西峡县| 焉耆| 九台市| 宝应县| 黄冈市| 新余市| 普洱| 东安县| 扬中市| 威宁| 夏津县| 霸州市| 平塘县| 九江市| 灌云县| 南通市| 张家港市| 安仁县| 浦城县|