**
linux的中斷分爲上半部和下半部兩部分
**
上半部中斷不能嵌套,中斷被禁止,代碼要儘量短,處理一些重要的事情,通常是改變一些標誌狀態
下半部的中斷可以嵌套,有三種處理的方式:
- SOFTIRQ
- TASKLET
- workqueue工作隊列
中斷頂半部函數,禁止中斷,不可嵌套(通過request_irq()申請)
中斷處理函數是被硬件請求執行的內核代碼,所以它屬於中斷上下文。
在中斷上下文中絕對不允許出現睡眠或者可能睡眠的代碼,否則會死機。
睡眠代碼:ssleep(), msleep()。
可能造成睡眠的代碼:
kmalloc(2048, GFP_KERNEL); //內存不足時可能睡眠,不能用於中斷中。
kmalloc(2048, GFP_ATOMIC); //內存不足時不睡眠,直接返回錯誤碼,可以用在中斷中。
copy_to_user(),copy_from_user(); //可能睡眠,不允許用在中斷中。
使能中斷只能enable_irq().
禁止中斷disable_irq(), 中斷內調用disbale_irq_nosync()。
tasklet在linux/interrupt.h中定義,屬中斷上下文,不能訪問0-3G空間,不能用copy_to_user()函數。
工作隊列屬進程上下文,其執行晚於中斷處理函數和tasklet,可休眠。
工作隊列workqueue被進程[events/0] PID=5調用。 0爲CPU編號