1. 程式人生 > >字元裝置驅動之筆記-中斷上下部

字元裝置驅動之筆記-中斷上下部

 

中斷下半部
在中斷處理函式執行的過程中:
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.     不影響中斷                 不影響中斷