歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 一種Linux下共享中斷的處理方法

一種Linux下共享中斷的處理方法

日期:2017/2/28 13:58:13   编辑:Linux教程

前段時間調試一款芯片的時候,碰到一個奇怪的問題:只要在板卡上插入一個PS2鍵盤,啟動內核時系統就可能會進入串口中斷函數去執行,過一會系統就panic不往下繼續執行。後來經過分析出現問題時的panic的堆棧,借助EJTAG工具,讀到這個時候的串口的中斷狀態位,竟然發現串口並沒有真正產生中斷。那麼,串口本身沒有中斷,內核怎麼又會跑到串口的中斷服務函數去執行呢?

我們知道Linux的中斷可以分為I/O 中斷 、時鐘中斷和處理器核間中斷。其中I/O中斷是Linux 系統響應外部IO事件的重要方式。盡管不同的平台和體系結構實現的方法不一樣,但是都支持不同的設備共享同一個中斷向量 。例如在PCI的總線結構中,幾個設備可以共享同一個IRQ線,也即它們共享一個中斷號,各自的中斷服務例程掛在這個中斷號上。當CPU響應這個IRQ時,會逐一檢查掛在這個中斷向量上的例程,並且執行那些真正有中斷的例程。但是串口明顯不屬於PCI,不可能用到PCI的中斷線和中斷引腳寄存器,那又是什麼原因導致kernel panic呢?

帶著上面的這些問題,和硬件工程師和芯片設計的同事深入討論了各種可能性,最後結合芯片板卡原理圖,發現這個板子上的低速設備都集成在芯片內部,這些低速設備包括串口、LPC只是控制器、SPI控制、I2C控制器、NAND控制器等,其中CPU UART和LPC的中斷信號都路由到同一個CPU的中斷引腳。 具體的連接圖如下所顯:

通過上圖最左側的部分可以看到,CPU UART和CPU LPC控制器的中斷請求信號經過邏輯或後,輸出到了CPU 芯片內Interrupt Pending Bit2。一旦CPU檢測到任何一個Interrupt Pending位被設置起來,它就會根據約定的順序逐一查詢各個Interrupt Pending Bit,並且執行中斷路由到這個bit上的設備驅動的中斷服務例程。

在老版本的板卡設計中,CPU LPC上沒有接任何設備,當時沒有碰到前面提到的問題。後來,由於客戶的需求,板卡上CPU LPC端口上可以連接PS2 鍵盤和鼠標,問題也隨之暴露。因此,我猜測問題的根源是由於沒有對共享IP2的連接到LPC上的設備的中斷進行處理。按照這一思路,檢查了之前的中斷分發處理函數,發現果然在處理IP2時,只調用了do_irq(58)。參考內核中串口驅動的代碼可以知道,第一個CPU UART的中斷號默認是58。因此在這種情況下一旦接入的PS2鍵盤或鼠標發出中斷信號,現有的代碼就會不分青紅皂白地去執行do_irq(58)。顯然,這不是期望的行為,需要查詢各自的中斷狀態位來檢測到底該響應那個設備的中斷。在最新的Linux 4.2內核主干分支裡,我們仍然可以找到這部分有待完善的代碼:arch/mips/loongson64/loongson-3/irq.c:

void mach_irq_dispatch(unsigned int pending)

{

if (pending & CAUSEF_IP7)

do_IRQ(LOONGSON_TIMER_IRQ);

#if defined(CONFIG_SMP)

else if (pending & CAUSEF_IP6)

loongson3_ipi_interrupt(NULL);

#endif

else if (pending & CAUSEF_IP3)

ht_irqdispatch();

else if (pending & CAUSEF_IP2)

do_IRQ(LOONGSON_UART_IRQ);

else {

pr_err("%s : spurious interrupt\n", __func__);

spurious_interrupt();

}

}

另外,該芯片中LPC上的中斷信號是電平觸發,根據LPC配置寄存器的定義,當中斷完成之後,需要清除LPC SIRQ,這就需要添加響應的中斷ack和eoi等函數。與此相反的是,兼容NS16550A的串口上的中斷是邊沿觸發,不需要程序去清除:當傳輸保存寄存器為空時,串口的ISR的bit 1會被設置起來,一旦寫數據到傳輸保存寄存器,這個bit就會被清掉;當接收FIFO中字符的個數達到trigger的水平時,ISR的bit 2會被設置起來,直到程序讀接收FIFO。

根據上面的兩點思路,修改了響應的代碼,重新編譯內核,重新做了大量測試,沒有再復現前文提到的問題。通過這個例子,我們可以看到:除了PCI中斷這種共享中斷向量的機制之外,還有不同物理設備的中斷信號路由到同一個中斷引腳但使用不同中斷號的情況。針對這種情況。工程師需要綜合芯片結構、硬件連接、中斷路由及內核中斷處理流程,全面考慮各種情況,給出完善、健壯的解決方案。但比較這兩者的異同之後,不難發現其實本質還是一樣的:不管中斷號是否一樣,任何路由到CPU內部中斷或者外部中斷控制器上的設備,都應享用被服務的機會,不能遺漏。

Copyright © Linux教程網 All Rights Reserved