生活随笔
收集整理的這篇文章主要介紹了
中断处理程序与中断服务例程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
目錄(?)[-]
1 什么是中斷2中斷處理程序3中斷服務例程4request_irq函數分析
1. 什么是中斷
簡單來說中斷就是硬件設備與處理器的一種交流方式,比如當我按下一個鍵時,只有當處理器知道我按下了這個鍵并且做出相應的處理時,按鍵這個操作才是有效的。我們知道處理器的速度遠遠高于外圍設備的速度,處理器與外設選擇合適的交流方式就格外重要。輪詢是一種方式,這種方式是內核周期性地對設備狀態進行查詢并作出相應的的動作,但這種方式會讓內核做大量的無用功,這顯然是不明智的。更好的方式是讓外設在其需要的時候向內核發送信號,這就是中斷機制。
2.中斷處理程序
當一個中斷發生時,內核應該有相應的處理方法,這個方法就是中斷處理程序,一個中斷處理程序對應一個中斷號。中斷處理程序是管理硬件的驅動程序的一部分,如果設備需要中斷,相應的設備驅動程序就需注冊中斷處理程序。注冊方式:使用request_irq()函數
intrequest_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long irqflags, const char * devname, void *dev_id) 函數參數:?
irq:表示要分配的中斷號?
handler:函數指針,指向中斷的實際中斷處理函數?
irqflags:中斷處理程序的標志,舉例來說: IRQF_DISABLED被設置后內核在處理中斷處理程序本身期間要禁止所有的其他中斷。?
devname:與中斷相關的設備的ASCII文本表示?
dev_id:用于共享中斷線,當一個中斷處理程序需要釋放時,dev_id提供唯一的標志信息。
3.中斷服務例程
一條中斷線對應一個中斷一個中斷處理程序,而多個設備可能共享一條中斷線,那么如何讓中斷處理程序為不同的設備提供不同的處理方法。這就引出了中斷服務例程。一個中斷處理程序對應若干個中斷服務例程。
中斷處理程序就相當于某個中斷向量的總的處理程序,比如IRQ0x09_interrupt()是中斷號為9的總處理程序,假如這個9號中斷由5個設備共享,那么這5個設備都分別有其對應的中斷服務例程。也就是說當有多個設備需要共享某個中斷線時,中斷處理程序必須要調用ISR,此時會調用handle_IRQ_event()
4.request_irq函數分析
intrequest_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id){ int retval; struct irqaction * action; if (irq >= ACTUAL_NR_IRQS) //中斷號是否超過最大值 return -EINVAL; if (!handler) //函數指針是否為空 return -EINVAL;#if 1 /* * Sanity-check: shared interrupts should REALLY pass in * a real dev-ID, otherwise we'll have trouble later trying * to figure out which interrupt is which (messes up the * interrupt freeing logic etc). */ if ((irqflags & SA_SHIRQ) && !dev_id) { //若中斷共享但dev_id為NULL則出錯 printk(KERN_ERR "Bad boy: %s (at %p) called us without a dev_id!\n", devname, __builtin_return_address(0)); }#endif action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); //創建irqaction結構體 if (!action) return -ENOMEM; action->handler = handler; //將函數參數傳給結構體 action->flags = irqflags; cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id;#ifdef CONFIG_SMP select_smp_affinity(irq);#endif retval = setup_irq(irq, action); //注冊中斷irqaction結構體 if (retval) kfree(action); return retval;} struct irqaction { irqreturn_t (*handler)(int, void *, struct pt_regs *);//具體的中斷服務例程 unsigned long flags;//一組中斷標志 cpumask_t mask; const char *name;//中斷設備名稱 void *dev_id;指定設備的主設備號和次設備號 struct irqaction *next;//指向共享中斷線的下一個 irqaction結構體 int irq;//申請的中斷號 struct proc_dir_entry *dir;};
總結
以上是生活随笔為你收集整理的中断处理程序与中断服务例程的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。