中斷下半部分機制--tasklet和工作隊列



中斷下半部分機制--tasklet和工作隊列

1.tasklet
 
 tasklet機制是內核定義的幾種softirq之一(常用)
 
 根據優先級不同內核將tasklet分成兩種:TASKLET_SOFTIRQ 和 HI_SOFTIRQ (後者優先級高)
 
 執行時機通常是上半部分返回的時候。
 
1.1 tasklet機制初始化

 在linux系統內核初始化的時候,通過調用softirq_init( )爲TASKLET_SOFTIRQ 和 HI_SOFTIRQ
 安裝了執行函數。


 
1.2 相關的操作

 struct tasklet_struct
 {
  struct tasklet_struct *next; //用來將系統中tasklet鏈接成鏈表
  unsigned long state;   //記錄在系統中tasklet的狀態
  atomic_t count;     //如果爲0,則不可被調度執行
  void (*func)(unsigned long); //在tasklet上執行函數或者延遲函數
  unsigned long data;    //將data傳遞給fun指向的函數
 };
 
1.2.1 初始化tasklet

 聲明並初始化一個靜態的tasklet對象;
 
 //struct tasklet_struct name;
 
 //void func(unsigned long);
 
 //unsingned long data;
 
 DECLARE_TASKLET(name, func, data);
 
 動態初始化tasklet對象

 void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data)
 
 -->tasklet_init(&name, fun, data);
 
1.2.2 提交一個tasklet

 在聲明和初始化一個tasklet對象之後,
 驅動程序需要調用tasklet_schedule來向系統提交tasklet(一般在中斷處理程序中提交)
 
 void tasklet_schedule(struct tasklet_struct *t)
 
 tasklet_schedule(name);
 
 
 
 驅動模型:
 
 

2. 工作隊列
 
 2.1 使用內核自己帶的工作隊列
 
 工作隊列和tasklet相似,工作隊列執行的上下文是內核線程,因此可以調度和睡眠
 
 在Workqueue機制中,Linux系統在初始化的時候通過init_workqueues(void)函數創建了一個workqueue隊列——events,
 
 用戶可以直接初始化一個work_struct對象,然後在該隊列中進行調度,使用更加方便。
 
 struct work_sturct my_wrok;//定義一個工作節點
 
 void my_wq_func(struct work_struct *work);//定一個處理函數
 
 INIT_WORK(&my_work, my_wq_func) /*初始化工作節點,並和處理函數綁定*/
 
 schedule_work(&my_wq)   /*使用內核自己創建的工作隊列-events和處理線程, 提交工作節點(一般在中斷處理函數中)*/
  ---> queue_work(system_wq, work);
 
 
 2.2 使用自己創建工作隊列
 
 首先創建工作隊列:
 #define create_workqueue(name)    
       alloc_workqueue((name), WQ_MEM_RECLAIM, 1)
 
 
  --->struct workqueue_struct* myworkqueue = create_workqueue("mywq"); /*創建工作隊列和處理線程*/
   
 提交工作:
 int queue_work(struct workqueue_struct *wq, struct work_struct *work)
 
  -->queue_work(myworkqueue, &my_work);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章