2013-06-28 57 views
4

我正在將設備驅動程序從QNX移植到Linux。在QNX中,舊驅動程序使用帶有無限循環的pthread來監視中斷的發生,而不是註冊真正的中斷處理程序。爲了演示使用register_irq()而不是專用的輪詢線程的功效,我在Linux中編寫了兩個驅動程序。下面顯示了每個代碼的相關代碼,問題在底部。Linux外部事件處理 - IRQ與輪詢kthread

IRQ

編寫處理

irqreturn_t timing_interrupt_handler(int irq, void *dev_id) { 

    u32 test; 

    /* read device interrupt command/status register */ 
    test = ioread32(timing_card[3].base); 

    /* sanity check that the device reported the interrupt */ 
    if (test & (1 << 2)) { 

    /* clear interrupt status */ 
    iowrite32(0x0d, timing_card[3].base); 

    /* toggle digital output line */ 
    test = ioread32(timing_card[2].base); 
    if (test & 0x01) 
     iowrite32(test & ~0x1, timing_card[2].base); 
    else 
     iowrite32(test | 0x1, timing_card[2].base); 

    } 

    return IRQ_HANDLED; 
} 

註冊的處理程序

rc = request_irq(irq_line, timing_interrupt_handler, 
       IRQF_SHARED, "timing", timing_card); 
if (rc) { 
    printk(KERN_ALERT "Failed to register irq %d\n", irq_line); 
    return rc; 
} 

輪詢線程

編寫線程函數

int poll_irq(void *data) { 

    u32 test; 

    /* until module unload */ 
    while (!kthread_should_stop()) { 

    /* read device interrupt command/status register */ 
    test = ioread32(timing_card[3].base); 

    /* sanity check that the device reported the interrupt */ 
    if (test & (1 << 2)) { 

     /* clear interrupt status */ 
     iowrite32(0x0d, timing_card[3].base); 

     /* toggle digital output line */ 
     test = ioread32(timing_card[2].base); 
     if (test & 0x01) 
     iowrite32(test & ~0x1, timing_card[2].base); 
     else 
     iowrite32(test | 0x1, timing_card[2].base);  
     } 
     else 
     usleep_range(9, 11); 
    } 

    return 0; 
} 

開始線程

kthread = kthread_create(poll_irq, 0x0, "poll_IRQ_test"); 
wake_up_process(kthread); 

問題

當我把兩條曲線在示波器上 - 一個監控卡的數字輸入(這會觸發中斷)和一個監控該卡的數字輸出(這將對中斷做出反應)我可以測量事件的反應時間。

第一個「正確」的方法,註冊一個IRQ,大約需要80微秒。

第二種方法,運行無限線程大約需要15-30微秒。

什麼給?第一個好處是它不會浪費太多的處理能力,但爲什麼響應時間如此劇烈呢?真的有這個輪詢線程有多糟糕?如何才能調查並最終證明輪詢線程對CPU造成的額外損失?

謝謝你的時間!

最佳

斯科特

回答

0

中斷響應時間由時間系統(不管它是什麼)的影響需要傳遞的中斷,並通過您的CPU(不管它是什麼)需要喚醒時間從一些省電的睡眠模式。

輪詢線程同時消耗CPU時間和功耗。 要測量它們,請使用類似toppowertop的東西,或直接在硬件上測量功耗。

+0

是的。請參閱http://lwn.net/images/pdf/LDD3/ch17.pdf「接收中斷緩解」部分,其中討論了網絡驅動程序。 –