新聞中心

        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

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 南部县| 康保县| 凤山县| 通江县| 左云县| 若尔盖县| 永吉县| 商河县| 综艺| 新密市| 平凉市| 项城市| 津南区| 仪征市| 南昌县| 仁化县| 武夷山市| 新宁县| 万载县| 望奎县| 新晃| 文昌市| 灌南县| 西宁市| 陆丰市| 垦利县| 比如县| 新野县| 桃园县| 巩义市| 高碑店市| 酒泉市| 临泉县| 屏山县| 莆田市| 永定县| 金山区| 耒阳市| 油尖旺区| 清徐县| 涟水县|