字元裝置驅動之筆記-中斷上下部
中斷下半部
在中斷處理函式執行的過程中:
1. 它可以被其他中斷打斷
2. 它不會再次響應同一個中斷(同一個中斷不會巢狀處理)
3. 如果中斷處理函式執行的時間很長,系統性能會受影響
舉例:
net_irq()
{
1. 從網絡卡晶片讀資料到記憶體裡 (比較快)
2. 處理資料 (比較耗時)
}
如果在net_irq執行期間,網絡卡不斷收到資料,
由於上面第2點原因,導致net_irq不能立刻執行,
資料會堆積最終可能丟失
所以: net_irq要儘快執行完, 它只做最緊急的事: "1. 從網絡卡晶片讀資料到記憶體裡"
把"2. 處理資料" 留到合適的時間再做: 在處理完中斷(呼叫中斷處理函式)後,返回(恢復現場)之前執行
把中斷處理分為上半部、下半部:
xxxx_irq()
{
執行上半部做緊急的事
把下半部告訴核心
}
怎麼寫程式碼?
1. 定義一個結構體tasklet_struct: 裡面有"下半部的函式"
void button_tasklet_function(unsigned long data)
{
}
static DECLARE_TASKLET(buttons_tasklet, button_tasklet_function, 0);
2. 在中斷服務程式裡: 把下半部告訴核心
tasklet_schedule(&buttons_tasklet);
下半部特點:
1. 執行下半部過程中,可以響應中斷
2. 下半部執行時間有保證
3. 如果下半部執行時間太長的話,會影響系統性能
4. 運行於中斷上下文,不能休眠
如果資料處理執行的時間非常長,那麼就不適合使用下半部, 用工作佇列
1. 寫處理函式,定義一個結構體
static void buttons_work_func(struct work_struct *work)
{
}
static struct work_struct buttons_work;
INIT_WORK(&buttons_work, buttons_work_func);
2. 把這個結構體告訴核心
schedule_work(&buttons_work);
下半部 工作佇列
1. 運行於中斷上下文 運行於核心執行緒上下文
2. 時間有保證 核心執行緒優先順序比較高,時間也有保證
3. 不能休眠 可以休眠
4. 耗時不應太大 應該沒有影響(可以設定APP的優先順序讓APP不受影響)
5. 不影響中斷 不影響中斷