生活随笔
收集整理的這篇文章主要介紹了
中断处理程序与中断服务例程
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。
目錄(?)[-]
1 什么是中斷2中斷處理程序3中斷服務例程4request_irq函數(shù)分析
1. 什么是中斷
簡單來說中斷就是硬件設(shè)備與處理器的一種交流方式,比如當我按下一個鍵時,只有當處理器知道我按下了這個鍵并且做出相應的處理時,按鍵這個操作才是有效的。我們知道處理器的速度遠遠高于外圍設(shè)備的速度,處理器與外設(shè)選擇合適的交流方式就格外重要。輪詢是一種方式,這種方式是內(nèi)核周期性地對設(shè)備狀態(tài)進行查詢并作出相應的的動作,但這種方式會讓內(nèi)核做大量的無用功,這顯然是不明智的。更好的方式是讓外設(shè)在其需要的時候向內(nèi)核發(fā)送信號,這就是中斷機制。
2.中斷處理程序
當一個中斷發(fā)生時,內(nèi)核應該有相應的處理方法,這個方法就是中斷處理程序,一個中斷處理程序?qū)粋€中斷號。中斷處理程序是管理硬件的驅(qū)動程序的一部分,如果設(shè)備需要中斷,相應的設(shè)備驅(qū)動程序就需注冊中斷處理程序。注冊方式:使用request_irq()函數(shù)
intrequest_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long irqflags, const char * devname, void *dev_id) 函數(shù)參數(shù):?
irq:表示要分配的中斷號?
handler:函數(shù)指針,指向中斷的實際中斷處理函數(shù)?
irqflags:中斷處理程序的標志,舉例來說: IRQF_DISABLED被設(shè)置后內(nèi)核在處理中斷處理程序本身期間要禁止所有的其他中斷。?
devname:與中斷相關(guān)的設(shè)備的ASCII文本表示?
dev_id:用于共享中斷線,當一個中斷處理程序需要釋放時,dev_id提供唯一的標志信息。
3.中斷服務例程
一條中斷線對應一個中斷一個中斷處理程序,而多個設(shè)備可能共享一條中斷線,那么如何讓中斷處理程序為不同的設(shè)備提供不同的處理方法。這就引出了中斷服務例程。一個中斷處理程序?qū)舾蓚€中斷服務例程。
中斷處理程序就相當于某個中斷向量的總的處理程序,比如IRQ0x09_interrupt()是中斷號為9的總處理程序,假如這個9號中斷由5個設(shè)備共享,那么這5個設(shè)備都分別有其對應的中斷服務例程。也就是說當有多個設(shè)備需要共享某個中斷線時,中斷處理程序必須要調(diào)用ISR,此時會調(diào)用handle_IRQ_event()
4.request_irq函數(shù)分析
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) //函數(shù)指針是否為空 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); //創(chuàng)建irqaction結(jié)構(gòu)體 if (!action) return -ENOMEM; action->handler = handler; //將函數(shù)參數(shù)傳給結(jié)構(gòu)體 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結(jié)構(gòu)體 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;//中斷設(shè)備名稱 void *dev_id;指定設(shè)備的主設(shè)備號和次設(shè)備號 struct irqaction *next;//指向共享中斷線的下一個 irqaction結(jié)構(gòu)體 int irq;//申請的中斷號 struct proc_dir_entry *dir;};
總結(jié)
以上是生活随笔為你收集整理的中断处理程序与中断服务例程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。