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

    EEPW首頁 > 模擬技術(shù) > 設(shè)計應用 > Linux下PCI設(shè)備驅(qū)動程序開發(fā)

    Linux下PCI設(shè)備驅(qū)動程序開發(fā)

    作者:肖文鵬 碩士研究生, 北京理工大學計算機系 時間:2008-08-25 來源:21IC 中國電子網(wǎng) 收藏
      4. 打開設(shè)備模塊

      在這個模塊里主要實現(xiàn)申請中斷、檢查讀寫模式以及申請對設(shè)備的控制權(quán)等。在申請控制權(quán)的時候,非阻塞方式遇忙返回,否則進程主動接受調(diào)度,進入睡眠狀態(tài),等待其它進程釋放對設(shè)備的控制權(quán)。 

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

      static int demo_open(struct inode *inode, struct file *file)
      {
        /* 申請中斷,注冊中斷處理程序 */
        request_irq(card->irq, &demo_interrupt, SA_SHIRQ,
            card_names[pci_id->driver_data], card)) {
        /* 檢查讀寫模式 */
        if(file->f_mode & FMODE_READ) {
            /* ... */
        }
        if(file->f_mode & FMODE_WRITE) {
           /* ... */
        }
        
        /* 申請對設(shè)備的控制權(quán) */
        down(&card->open_sem);
        while(card->open_mode & file->f_mode) {
            if (file->f_flags & O_NONBLOCK) {
                /* NONBLOCK模式,返回-EBUSY */
                up(&card->open_sem);
                return -EBUSY;
            } else {
                /* 等待調(diào)度,獲得控制權(quán) */
                card->open_mode |= f_mode & (FMODE_READ | FMODE_WRITE);
                up(&card->open_sem);
                /* 設(shè)備打開計數(shù)增1 */
                MOD_INC_USE_COUNT;
                /* ... */
            }
        }
      } 
     
      5. 數(shù)據(jù)讀寫和控制信息模塊

      設(shè)備驅(qū)動程序可以通過demo_fops 結(jié)構(gòu)中的函數(shù)demo_ioctl( ),向應用程序提供對硬件進行控制的接口。例如,通過它可以從I/O寄存器里讀取一個數(shù)據(jù),并傳送到用戶空間里: 

      static int demo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
      {
        /* ... */
        
        switch(cmd) {
            case DEMO_RDATA:
                /* 從I/O端口讀取4字節(jié)的數(shù)據(jù) */
                val = inl(card->iobae + 0x10);
                
      /* 將讀取的數(shù)據(jù)傳輸?shù)接脩艨臻g */
                return 0;
        }
        
        /* ... */
      } 
     
      事實上,在demo_fops里還可以實現(xiàn)諸如demo_read( )、demo_mmap( )等操作,內(nèi)核源碼中的driver目錄里提供了許多設(shè)備驅(qū)動程序的源代碼,找那里可以找到類似的例子。在對資源的訪問方式上,除了有I/O指令以外,還有對外設(shè)I/O內(nèi)存的訪問。對這些內(nèi)存的操作一方面可以通過把I/O內(nèi)存重新映射后作為普通內(nèi)存進行操作,另一方面也可以通過主DMA(Bus Master DMA)的方式讓設(shè)備把數(shù)據(jù)通過DMA傳送到系統(tǒng)內(nèi)存中。 

      6. 中斷處理模塊

      PC的中斷資源比較有限,只有0~15的中斷號,因此大部分外部設(shè)備都是以共享的形式申請中斷號的。當中斷發(fā)生的時候,中斷處理程序首先負責對中斷進行識別,然后再做進一步的處理。 

      static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
      {
        struct demo_card *card = (struct demo_card *)dev_id;
        u32 status;
        spin_lock(&card->lock);
        /* 識別中斷 */
        status = inl(card->iobase + GLOB_STA);
        if(!(status & INT_MASK)) 
        {
            spin_unlock(&card->lock);
            return;  /* not for us */
        }
        /* 告訴設(shè)備已經(jīng)收到中斷 */
        outl(status & INT_MASK, card->iobase + GLOB_STA);
        spin_unlock(&card->lock);
        
        /* 其它進一步的處理,如更新DMA緩沖區(qū)指針等 */
      } 
     

      7. 釋放設(shè)備模塊

      釋放設(shè)備模塊主要負責釋放對設(shè)備的控制權(quán),釋放占用的內(nèi)存和中斷等,所做的事情正好與打開設(shè)備模塊相反:

      static int demo_release(struct inode *inode, struct file *file)
      {
        /* ... */
        
        /* 釋放對設(shè)備的控制權(quán) */
        card->open_mode &= (FMODE_READ | FMODE_WRITE);
        
        /* 喚醒其它等待獲取控制權(quán)的進程 */
        wake_up(&card->open_wait);
        up(&card->open_sem);
        
        /* 釋放中斷 */
        free_irq(card->irq, card);
        
        /* 設(shè)備打開計數(shù)增1 */
        MOD_DEC_USE_COUNT;
        
        /* ... */  
      } 
     
      8. 卸載設(shè)備模塊

      卸載設(shè)備模塊與初始化設(shè)備模塊是相對應的,實現(xiàn)起來相對比較簡單,主要是調(diào)用函數(shù)pci_unregister_driver( )從內(nèi)核中注銷設(shè)備驅(qū)動程序: 

      static void __exit demo_cleanup_module (void)
      {
        pci_unregister_driver(&demo_pci_driver);
      }
     
      四、小結(jié)

      不僅是目前應用廣泛的計算機標準,而且是一種兼容性最強、功能最全的計算機總線。而作為一種新的操作系統(tǒng),其發(fā)展前景是無法估量的,同時也為總線與各種新型設(shè)備互連成為可能。由于Linux源碼開放,因此給連接到PCI總線上的任何設(shè)備編寫驅(qū)動程序變得相對容易。本文介紹如何編譯Linux下的PCI驅(qū)動程序,針對的內(nèi)核版本是2.4。 

    linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

    c++相關(guān)文章:c++教程



    上一頁 1 2 3 下一頁

    關(guān)鍵詞: PCI 總線 Linux Alpha

    評論


    相關(guān)推薦

    技術(shù)專區(qū)

    關(guān)閉
    主站蜘蛛池模板: 凭祥市| 南木林县| 宁远县| 巴彦淖尔市| 商水县| 崇文区| 那曲县| 札达县| 伊川县| 伊春市| 潜山县| 拜泉县| 长汀县| 偏关县| 虞城县| 湖州市| 顺义区| 博野县| 崇仁县| 平塘县| 宁德市| 虎林市| 常德市| 新营市| 宁阳县| 济阳县| 双城市| 青浦区| 沂水县| 莒南县| 依安县| 台东市| 淳化县| 衡东县| 南通市| 富宁县| 福州市| 开封市| 易门县| 华蓥市| 水富县|