2015-11-26 25 views
2

我正在研究一個項目,我正在根據收到的鍵盤中斷進行一些操作。所以我註冊了鍵盤中斷並將中斷標記爲共享。但是我的程序沒有按照它應該的工作。爲了調試這個問題,我編寫了一個小程序,它只註冊鍵盤中斷,並在收到鍵盤中斷時向內核輸出一些消息。但是,當中斷率很高時,我發現很多鍵盤中斷都被漏掉了。例如,在下面的示例代碼中,當'a'被按下時,我註冊中斷並輸出消息給內核。從計數器的值來看,中斷的總數量少於鍵盤產生的實際中斷數量。我通過將按鍵回顯到終端並計算迴應給終端的a的數量來發現這一點。例如,如果在終端上有350個回聲a,則計數只會在300-320左右。更高數量的中斷也是如此。中斷數越多,錯過的中斷越多,但錯過的中斷百分比在所有情況下似乎幾乎相等。有人可以解釋這種行爲的原因是什麼?提前致謝。以下是源代碼。在內核模塊中沒有鍵盤中斷

#include <linux/kernel.h> 
#include <linux/interrupt.h> 
#include <linux/module.h> 
#include <linux/signal.h> 
#include <asm/io.h> 

/* 
The keyboard ISR 
*/ 
irq_handler_t irq_handler (int irq, void *dev_id, struct pt_regs *regs)  
{ 
    static int count = 0; 
static unsigned char scancode; 

scancode = inb (0x60); 

if (0x1E == scancode) 
{ 
      count++; 
    printk ("\nKeyboard key 'a' pressed !"); 
} 

return (irq_handler_t) IRQ_HANDLED; 
} 

/* 
Register IRQ handler 
*/ 
int init_module() 
{ 
return request_irq (1, (irq_handler_t) irq_handler, IRQF_SHARED, "kbd_irq_handler", (void *)(irq_handler)); 
} 


MODULE_LICENSE ("GPL"); 
+2

也許使用'在中斷處理程序printk'是不是一個好主意... – Olaf

回答

0

here

測井代碼已經嘗試通過檢測 並抑制相同的消息流來減輕這個問題。

使用printk爲相同的消息流 - 壞主意。

+1

你好。問題不在於獲取內核打印,而在於接收和處理鍵盤中斷的次數。即使在刪除所有printk之後,仍然count的值似乎遠遠小於期望值,這是實際按鍵次數。另外我必須提到,只有在字符輸入速度非常快時纔會發生這種情況,例如在一段時間內按住某個鍵。 –

+0

你可以提供沒有'printk'的代碼示例嗎?我知道,按鍵的預期數量=終端中的字母數量。但是,如何在沒有'printk'的情況下學習接收到的按鍵次數? –

+0

@RomanZaytsev - printk不是問題,並且有很多方法可以讀取變量的內容(事後最簡單的printk,從用戶空間映射內存區域以從另一個地方讀取) – crististm

1

你可以嘗試使用工作隊列爲下半區,因爲如果中斷服務例程[置頂]需要時間在這種情況下中斷來完成,可能會錯過。

它更好地使用workqueue做非時間關鍵處理。

您的代碼應該像

static unsigned char scancode; 
    irq_handler_t irq_handler (int irq, void *dev_id, struct pt_regs *regs)  
    { 

     scancode = inb (0x60); 

     schedule_delayed_work(work_struct);//in this function pointer is passed 
     return (irq_handler_t) IRQ_HANDLED; 
    } 

    func() 
    { 
     if (0x1E == scancode) 
     { 
       count++; 
       printk ("\nKeyboard key 'a' pressed !"); 
     } 
    } 

您也可以檢查從硬件的角度來看的中斷之間的最短時間間隔的鍵盤控制器的數據表,然後檢查該中斷執行時間看中斷處理程序執行時間應少比中斷產生時間短。

或者你也可以考慮時間,系統負載之後保持事件緩衝區。

0

我已經看到在不同的驅動程序中錯過中斷的確切問題。 我的驅動程序正在使用一個快速IRQ處理程序,它將作業分派到下半部分工作隊列。

我發現那是什麼時候的IRQ處理程序執行,內核可能不相同的處理程序來註冊新的中斷。然而,我沒有看到一致的行爲。它被擊中和錯過。

我已經通過使IRQ處理需要很長的時間(> = 10秒),並在一個第二時段發出中斷調試此。在執行IRQ處理程序時發出的10個或更多中斷中,只有7個或8個被註冊。

我的權宜的解決方案是一個看門狗添加到設備固件補發中斷,如果它認爲主機沒有服務式緩衝器,但我在尋找一個更好的和決定性的解決方案。

+0

您的情況是類似於「瞭解Linux內核,第3版」一書中的情況,4.6章中斷處理,恢復丟失的中斷: 「爲了應對這種情況,enable_irq()函數由內核用來啓用IRQ線,首先檢查中斷是否丟失,如果是,則強制硬件產生一個新的丟失中斷「 –

+0

@RomanZaytsev我不禁止中斷,所以我不知道這是否適用於我的情況。如果我第一次錯過了某些東西,我正在重新審視那一章。 「強制硬件重新發布中斷」只有當它們指APIC或其他東西時纔有可能,因爲我的硬件在這個問題上不聽主機 – crististm