Linux 驅動程式的中斷處理, #1: request_irq 基本觀念
在Linux device driver 中,名為 “interrupt handler” 的 routine 負責處理(回應)實體的硬體中斷。當裝置中斷被觸發時,interrupt handler 便會執行,而 interrupt handler 就工作便是回應該中斷的請求(request)。
Interrupt handler 執行於 interrupt mode,並無 process context 資訊,因此,在 interrupt mode 下執行的執行碼需注意以下 3 點:
1. 由於沒有 process context 的關係,因此無法存取 user space。
2. 無法存取 current 巨集。current 巨集是一個指向自己的 kernel symbol。
3. 不能呼叫 scheduler 做排程,也不能做 sleeping waiting。由於 down/up 的 semaphore API 是 sleeping waiting 的版本,因此在 interrupt mode 必須改用 spinlock,spinlock 是以 busy waiting 的方式做 wait operation。
Linux device driver 安裝 interrupt handler 的方式是呼叫 request_irq() 函數,透過此函數來佔用 IRQ,並且安裝interrupt handler。
Request IRQ
request_irq() 用法如下:
int request_irq( unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *devname, void *dev_id);
irqflags 參數說明:
1. SA_INTERRUPT
2. SA_SHIRQ
3. SA_SAMPLE_RANDOM
在 Linux 驅動程式的 framework 中,呼叫 request_irq() 安裝 interrupt handler 的位置為:
1. init_module()
2. fops->open
若是「共用中斷」(shared IRQ),只能在 fops->open 裡呼叫 request_irq()。在 fops->open 裡請求 IRQ ,相對的也要在 fops->release 裡呼叫 free_irq() 將佔用的 IRQ 釋放。