linux内核 sin头文件,Linux内核中中断request_irq详解--中断共享问题解决
。函數原型如下:
2.4 內核
int request_irq (unsignedintirq,void (*handler)(int,void*,structpt_regs*),unsignedlongfrags,constchar*device,void*dev_id);
2.6 內核
request_irq(unsignedintirq,irq_handler_thandler,unsignedlongflags,constchar*name,void*dev);
參數說明:
在發生對應于第 1個參數 irq 的中斷時,則調用第 2 個參數handler 為要注冊的中斷服務函數(也就是把 handler() 中斷服務函數注冊到內核中 )。
第 3 個參數 flags 指定了快速中斷或中斷共享等中斷處理屬性。在 2.6 教新的內核里(我的是 2.6.27 ~ 2.6.31 ),在 linux/interrupt.h 中定義操作這個參數的宏如下:
引用
/*
* These correspond to the IORESOURCE_IRQ_* defines in
* linux/ioport.h to select the interrupt line behaviour. ?When
* requesting an interrupt without specifying a IRQF_TRIGGER, the
* setting should be assumed to be "as already configured", which
* may be as per machine or firmware initialisation.
#define IRQF_TRIGGER_NONE0x00000000
#define IRQF_TRIGGER_RISING0x00000001
#define IRQF_TRIGGER_FALLING0x00000002
#define IRQF_TRIGGER_HIGH0x00000004指定中斷觸發類型:高電平有效。新增加的標志#define IRQF_TRIGGER_LOW0x00000008
#define IRQF_TRIGGER_MASK(IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
#define IRQF_TRIGGER_PROBE0x00000010
/*
* These flags used only by the kernel as part of the?irq handling routines.
*registered first in an shared interrupt is considered for
*??????????????? performance reasons)
*/#define IRQF_DISABLED?????????? 0x00000020* IRQF_DISABLED - keep irqs disabled when calling the action handler
#define IRQF_SAMPLE_RANDOM????? 0x00000040* IRQF_SAMPLE_RANDOM - irq is used to feed the random generator
#define IRQF_SHARED???????????? 0x00000080* IRQF_SHARED - allow sharing the irq among several devices
#define IRQF_PROBE_SHARED?????? 0x00000100* IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur#define IRQF_TIMER????????????? 0x00000200* IRQF_TIMER - Flag to mark this interrupt as timer interrupt
#define IRQF_PERCPU???????????? 0x00000400* IRQF_PERCPU - Interrupt is per cpu#define IRQF_NOBALANCING??????? 0x00000800* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing#define IRQF_IRQPOLL??????????? 0x00001000* IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
早期一點的 2.6 內核這里一般以 SA_ 前綴開頭,如:
SA_INTERRUPT?? 表示禁止其他中斷;(對應于 IRQF_DISABLED )
SA_SHIRQ???????????? 表示共享相同的中斷號 (對應于 IRQF_SHARED )
SA_SAMPLE_RANDOM?? 此宏會影響到 RANDOM 的處理( 對應于 IRQF_SAMPLE_RANDOM )。
第 4 個參數 name,通常是設備驅動程序的名稱。改值用在 /proc/interrupt 系統 (虛擬) 文件上,或內核發生中斷錯誤時使用。
第 5 個參數 dev_id 中斷名稱 可作為共享中斷時的中斷區別參數,也可以用來指定中斷服務函數需要參考的數據地址。建議將設備結構指針作為dev_id參數
int request_irq(unsigned int irq, irq_handler_t handler,IRQF_SHARED, const char *devname, void *dev_id)
中斷共享注冊時的注冊函數中的dev_id參數
什么是中斷共享?
有時候會有這樣的情況,如果開發板上中斷已經被另外的驅動程序注冊中斷了,而我現在又想再注冊一次這個中斷,這就出現了一個中斷號不止對應一個中斷函數的情況。注意,這里與硬件上的共享中斷不一樣,這里是指,當一個中斷信號來了,基于操作系統,一個中斷的到來可以調用多個中斷處理程序,與硬件無關。這就需要中斷共享。就是一個中斷設置成共享,在多個驅動中均設置成共享,中斷觸發后可以調用到多個中斷處理程序。
很多權威資料中都提到,中斷共享注冊時的注冊函數中的dev_id參數是必不可少的,并且dev_id的值必須唯一。那么這里提供唯一的dev_id值的究竟是做什么用的?
根據我們前面中斷模型的知識,可以看出發生中斷時,內核并不判斷究竟是共享中斷線上的哪個設備產生了中斷,它會循環
執行所有該中斷線上注冊的中斷處理函數(即irqaction->handler函數)。因此irqaction->handler函數有責
任識別出是否是自己的硬件設備產生了中斷,然后再執行該中斷處理函數。通常是通過讀取該硬件設備提供的中斷flag標志位進行判斷。那既然kernel循
環執行該中斷線上注冊的所有irqaction->handler函數,把識別究竟是哪個硬件設備產生了中斷這件事交給中斷處理函數本身去做,那
request_irq的dev_id參數究竟是做什么用的?
很多資料中都建議將設備結構指針作為dev_id參數。在中斷到來時,迅速地根據硬件寄存器中的信息比照傳入的dev_id參數判斷是否是本設備的中斷,若不是,應迅速返回。這樣的說法沒有問題,也是我們編程時都遵循的方法。但事實上并不能夠說明為什么中斷共享必須要設置dev_id。
下面解釋一下dev_id參數為什么必須的,而且是必須唯一的。
當調用free_irq注銷中斷處理函數時(通常卸載驅動時其中斷處理函數也會被注銷掉),因為dev_id是唯一
的,所以可以通過它來判斷從共享中斷線上的多個中斷處理程序中刪除指定的一個。如果沒有這個參數,那么kernel不可能知道給定的中斷線上到底要刪除哪
一個處理程序。
注銷函數定義在Kernel/irq/manage.c中定義:?void free_irq(unsigned int irq, void *dev_id)
返回值:
函數運行正常時返回 0 ,否則返回對應錯誤的負值。
示例代碼片段:
引用
irqreturn_t xxx_interrupt (intirq,void*dev_id)
{
...
return (IRQ_HANDLED);
}
int xxx_open (struct inode *inode,structfile*filp)
{
if (!request_irq (XXX_IRQ,xxx_interruppt,IRQF_DISABLED,"xxx",NULL)){
/*正常注冊*/
}
return (0);
}
總結
以上是生活随笔為你收集整理的linux内核 sin头文件,Linux内核中中断request_irq详解--中断共享问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dsagent是什么进程 dsagent
- 下一篇: linux系统如何拨号上网连接,教你在L