今天在些key的driver的時候。。。寫完了編譯出現一個warmming如下:
warning: passing argument 2 of 'request_irq' from incompatible pointer type
我的request_irq函數調用如下:
if(request_irq(key_info->irq_no, key_eint_handler, IRQF_DISABLED,"Mini2440_Key", &i))
{
return -1;
}
key_eint_handler函數的原型如下:
static void key_eint_handler(int irq, void *dev_id,struct pt_regs *regs)
警示的提示意思是第二個參數指標類型不符。本來覺得不匹配也就是一個warning沒關係,不過後來還是想找到為什麼。。。
於是乎。。。經過網路的一陣搜尋。。。
結果出來了。。。
問題出在
key_eint_handler函數的原型,
應該由:
static void key_eint_handler(int irq, void *dev_id,struct pt_regs *regs)//錯誤的寫法
改為:
static irqreturn_t key_eint_handler(int irq, void *dev_id)//正確寫法
為什麼呢?
按照宋寶華老師書上寫的是3個參數的那種寫法呀。。。
於是從核心源碼入手。。。
在
linux/include/linux/interrupt.h, line 60 左右有這麼一個定義
typedef irqreturn_t (*irq_handler_t)(int, void *);
這個定義是什麼意思呢?
它是指:定義一種函數指標類型irq_handler_t, 這種函數的傳回型別為irqreturn_t,參數列表為int, void*
再來看request_irq的函式宣告部分
kernel/irq/manage.c:
int request_irq(
unsigned int irq,
irq_handler_t handler,
unsigned long irqflags,
const char *devname,
void *dev_id)
request_irq的第二個參數是handler函數,類型是irq_handler_t,
也就是說:我定義的handler函數傳回型別為irq_handler_t,
結合最上面說的
typedef irqreturn_t (*irq_handler_t)(int, void *);
那麼。。。
handler函數應該是寫成:
static irqreturn_t key_eint_handler(int irq, void *dev_id)//正確寫法
2個參數。。。傳回型別為irqreturn_t才是正確的!
request_irq() 函數原型的變化
Linux-2.6.22 中request_irq() 函數原型與之前版本略有改動:
/********************************/
Linux-2.6.22.6
include/linux/irqreturn.h:typedef int irqreturn_t;
include/linux/interrupt.h:typedef irqreturn_t (*irq_handler_t)(int, void *);
kernel/irq/manage.c:int request_irq(
unsigned int irq,
irq_handler_t handler,
unsigned long irqflags,
const char *devname,
void *dev_id)
/********************************/
Linux-2.6.13
include/linux/interrupt.h:typedef int irqreturn_t;
kernel/irq/manage.c:int request_irq(
unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags,
const char * devname,
void *dev_id)
/********************************/