linux 中斷處理

Linux設備驅動中中斷處理相關的首先是申請與釋放IRQ的API request_irq()和free_irq()函數

int request_irq(unsigned int irq,  //irq是要申請的硬件中斷號
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname,  //設備名 中斷屬於哪一個設備的
void *dev_id);

handler是向系統登記的中斷處理函數,是一個回調函數,中斷髮生時,系統調用這個函數
spa

irqflags是中斷處理的屬性,若設置IRQF_DISABLED,標明中斷處理程序是快速處理程序,快速處理程序被調用時屏蔽全部中斷,慢速處理程序不屏蔽;若設置IRQF_SHARED,則多個設備共享中斷,操作系統

dev_id在中斷共享時會用到,通常設置爲這個設備的device結構自己或者NULL。code

快速/慢速中斷區別orm

快速中斷保證中斷處理的原子性(不被打斷),而慢速中斷則不保證。換句話說,也就是「開啓中斷」標誌位(處理器IF)在運行快速中斷處理程序時是關閉的,所以在服務該中斷時,不會被其餘類型的中斷打斷;而調用慢速中斷處理時,其它類型的中斷仍能夠獲得服務,默認狀況是慢速中斷。進程

共享中斷ci

共享中斷就是將不一樣的設備掛到同一個中斷信號線上。Linux對共享的支持主要是爲PCI設備服務。共享中斷也是經過request_irq函數來註冊的,但有三個特別之處:回調函數

1)申請共享中斷時,必須在flags參數中指定 IRQF_SHARED位it

2)dev_id參數必須是惟一的。 //由於共享中斷 中斷號相同,因此須要dev_id來區別是哪一個設備中斷class

3)共享中斷的處理程序中,不能使用disable_irq(unsigned int irq) ,由於這個會關閉該中斷的全部設備

中斷處理程序void (*handler)

中斷處理程序。特別之處在於中斷處理程序是在中斷上下文中運行的,它的行爲受到某些限制:

1) 不能向用戶空間發送或接受數據 由於用戶空間和進程對應,進程變了用戶空間會變,中斷不對應任何進程,不屬於                進程

2) 不能使用可能引發阻塞的函數  

3) 不能使用可能引發調度的函數  。防止用戶空間發生變化

五、 中斷處理函數流程

操做系統還有一個進程上下文,如驅動中的讀寫函數就是進程上下文

用戶的應用程序,fread 經過內核 調用 驅動中的.read操做。read是進程主動調用的,屬於進程上下文。中斷上下文是硬件發出的,不是進程主動調用的。

中斷處理函數的流程

void short_sh_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    /* 判斷是不是本設備產生了中斷 由於共享中斷產生中斷會調用該中斷號的全部設備 因此每一個設備須要判斷是否本身產生    中斷,不然處理會出錯*/
    value = inb(short_base);
    if (!(value & 0x80)) return; //不是自己設備產生的中斷 返回
    
    /* 清除中斷位(若是設備支持自動清除,則不須要這步) */
    outb(value & 0x7F, short_base);
    
    /* 中斷處理,一般是數據接收 */
    。。。。。。。。。
    
    /* 喚醒等待數據的進程 */
    ake_up_interruptible(&short_queue); //接收數據 可能會阻塞別的進程,因此須要喚醒
}

卸載中斷
當設備再也不須要使用中斷時(一般在驅動卸載時), 應當把它們返還給系

void free_irq(unsigned int irq, void *dev_id)

相關文章
相關標籤/搜索