Linux 裝置驅動 中斷處理

2021-06-14 02:13:43 字數 4822 閱讀 5102

為什麼需要中斷:

1,外設的處理速度一般慢於 cpu;

2,cpu 不能一直等待外部事件;

所以裝置必須有一種方法來通知 cpu  它 的工作進度,這種方法就是中斷.

在 linux 驅動程式中,為裝置實現乙個中斷包含兩個步驟:

1,向核心註冊中斷;

2,實現中斷處理函式;

request_irq 用於實現中斷的註冊功能:

函式:

intrequest_irq( unsigned int irq,void (*handler) (int , void *, struct pt_regs *), unsigned long flags,const char * devname, void * dev_id )

引數:

unsigned int irq :申請的硬體中斷號;

void (*handler) (int , void *, struct pt_regs *)  :函式指標 handler ,向系統登記中斷處理函式,是個回掉函式;

const char * devname :指定裝置驅動程式的名稱;

unsigned long flags :(指定了 快速中斷 或者 慢速中斷 或者 中斷共享 等中斷處理屬性,上公升沿,下降沿等;)

在 flags 引數中,可以選擇一些與中斷管理有關的選項,

如:irqf_disabled(sa_interrupt)

如果設定該位,表示是乙個「快速」中斷處理程式,如果沒有設定該位,那麼是乙個「慢速」中斷處理程式;

irqf_shared(sa_shirq)

該位表明中斷可以在裝置間共享.

返回值:

為 0 表示 成功;

區別在於:快速中斷保證中斷處理的原子性(不被打斷),而慢速中斷則不保證;

也就是「 開啟中斷 」標誌位(處理器if)在執行 快速中斷處理程式是關閉的,因此在服務該中斷時,不會被其他型別的中斷打斷,

而呼叫慢速中斷處理時,其他型別的中斷仍可以得到服務;

慢速中斷可以中斷巢狀,快速中斷不可以.

共享中斷 就是將不同的裝置掛到同乙個中斷訊號線上,linux 對共享的支援主要是為 pci 裝置服務;

共享中斷處理程式相同的中斷號, 所以需要來提供乙個唯一的標誌來區分到底是哪個中斷;

也是通過 request_irq 函式來註冊的,但是有三個特別之處:

1,申請共享中斷時候,必須在 flags 引數中指定 irqf_shared 位;

2,dev_id 引數必須是唯一的;

3,共享中斷的處理程式中,不能使用 disable_irq ( unsigned int irq) ,

如果使用了這個函式,共享中斷訊號線的其他裝置將同樣無法使用中斷,也就是無法正常工作.

void (*handler) (int , void *, struct pt_regs *) :

handler 例子:

static irqreturn_t irq_interrupt(int irq, void *dev_id)

return irq_retval(irq_handled);

}

函式中 void *dev_id 引數是從 

request_irq函式裡的第五個引數 void * dev_id ;

err = request_irq(button_irqs[i].irq, irq_interrupt, irq_type_edge_both, button_irqs[i].name, (void *)&button_irqs[i]);

struct button_irq_desc ;

static struct button_irq_desc button_irqs = , /* k1 */

, /* k2 */

, /* k3 */

, /* k4 */

};

中斷處理程式 特點:

中斷處理程式是普通的 c **,特別之處在於中斷處理程式是在中斷上下文執行的,它的行為受到某些限制:

1,不能向使用者空間傳送或接收資料;

2,不能使用可能引起阻塞的函式;

3,不能使用可能引起排程的函式;

(共享中斷判斷具體是哪個中斷)

inb 從i/o埠讀取乙個位元組(byte, half-word) ;

outb 向i/o埠寫入乙個位元組(byte, half-word) ;

inw 從i/o埠讀取乙個字(word,即兩個位元組) ;

outw 向i/o埠寫入乙個字(word,即兩個位元組) ;

當裝置不再需要使用中斷時( 通常在驅動解除安裝時 ),應當把它們返回給系統,

使用:void  free_irq ( unsigned int irq ,void *dev_id )

例項程式:

/*************************************

name:embedsky_hello.c

*************************************/

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define device_name "irq-test"

struct button_irq_desc ;

/*err = request_irq(button_irqs[i].irq, irq_interrupt, irq_type_edge_both,

button_irqs[i].name, (void *)&button_irqs[i]);

*/#if !defined (config_sky2440_irq_test)

static struct button_irq_desc button_irqs = , /* k1 */

, /* k2 */

, /* k3 */

, /* k4 */

};#else

static struct button_irq_desc button_irqs = , /* k1 */

, /* k2 */

, /* k3 */

, /* k4 */

};#endif

static volatile char key_values = ;

static declare_wait_queue_head(button_waitq);

static volatile int ev_press = 0;

static irqreturn_t irq_interrupt(int irq, void *dev_id)

return irq_retval(irq_handled);

}static int tq2440_irq_open(struct inode *inode, struct file *file)

if (err)

return -ebusy;

} ev_press = 1;

return 0;

}static int tq2440_irq_close(struct inode *inode, struct file *file)

return 0;

}static int tq2440_irq_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

ev_press = 0;

err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));

return err ? -efault : min(sizeof(key_values), count);

}static unsigned int tq2440_irq_poll( struct file *file, struct poll_table_struct *wait)

static struct file_operations dev_fops = ;

static struct miscdevice misc = ;

static int __init dev_init(void)

static void __exit dev_exit(void)

module_init(dev_init);

module_exit(dev_exit);

module_license("gpl");

module_author("www.embedsky.net");

module_description("irq test for embedsky sky2440/tq2440 board");

Linux裝置驅動 中斷處理筆記

1 外設的處理速度一般慢於cpu 2 cpu不能一直等外部事件 所以裝置必須有一種方法來通知cpu它的工作進度,這就是中斷。步驟 1 向核心註冊中斷 2 實現中斷處理函式 intrequest irq unsignedintirq,void handler int,void structpt reg...

Linux裝置驅動程式設計之中斷處理

與linux裝置驅動中中斷處理相關的首先是申請與釋放irq的api request irq 和free irq request irq 的原型為 int request irq unsigned int irq,void handler int irq,void dev id,struct pt r...

裝置驅動 中斷

1 關於裝置驅動中的中斷問題 作業系統為了使得快速裝置和慢速裝置合適工作,需要中斷來提高效率,乙個外設要使用乙個中斷就必須註冊中斷號,獲得跟這個中斷號相關的一些資源,並且在中斷發生的時候核心可以進行一些處理,例如 呼叫中斷處理例程來真正的處理裝置中斷。linux處理中斷的方式很大程度上與它在使用者空...