新聞中心

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

        ISA總線的DMA技術

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

        本文引用地址:http://www.104case.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

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 宜都市| 漾濞| 木兰县| 青岛市| 定边县| 滨海县| 龙海市| 吉水县| 溧阳市| 临西县| 马尔康县| 平昌县| 平潭县| 上饶市| 灯塔市| 稻城县| 乐陵市| 时尚| 老河口市| 吐鲁番市| 瑞金市| 都兰县| 扬州市| 淄博市| 濮阳市| 大同县| 临泉县| 珲春市| 湟中县| 太仓市| 古田县| 兴义市| 洪雅县| 错那县| 清镇市| 华阴市| 那坡县| 安庆市| 新乐市| 桂林市| 张家界市|