日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux设备驱动归纳总结(六):3.中断下半部之tasklet

發(fā)布時(shí)間:2024/3/7 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux设备驱动归纳总结(六):3.中断下半部之tasklet 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
CU首頁(yè)?┊?fh265>>博客?微博?相冊(cè)?個(gè)人中心?好友?消息?[退出]?┊?隨便看看 公告:緬懷Dennis Ritchie活動(dòng)開(kāi)賽啦! 小白的博客——提升自已,分享別人

xiaobai.blog.chinaunix.net

好的女人可以不共享。好的技術(shù)絕對(duì)要共享!??? 首頁(yè)?|?博文目錄?|?相冊(cè)?|?博客圈?|?關(guān)于我?|?留言 個(gè)人資料 diytvgy 微博論壇 發(fā)紙條打招呼加關(guān)注加好友
  • 博客訪(fǎng)問(wèn):74424
  • 博文數(shù)量:42
  • 博客積分:687
  • 博客等級(jí):中校
  • 關(guān)注人氣: 4
  • 注冊(cè)時(shí)間:2010-12-01 18:55:26
文章分類(lèi) 全部博文(42) linux內(nèi)核相關(guān)知識(shí)(1) 閑話(huà)(3) linux內(nèi)核與設(shè)備驅(qū)動(dòng)(34) ubuntu(2) 未分類(lèi)博文(2) 訂閱我的博客
好友
  • tekkama

  • 小雅貝貝

  • luozhiy

  • Knivo

  • embedtek

  • sillybo

  • wang2kk

  • 嵌入小凱

  • send_li

  • CU官方博

  • songtao

  • lxhhust

最近來(lái)訪(fǎng)
  • fh265
    1小時(shí)前

  • shenhai
    10月30日

  • a275532
    10月14日

  • Knivo
    10月13日


  • 10月13日

  • lxr215
    10月10日

  • luozhiy
    10月9日

  • chafe
    10月8日

  • mournju
    10月7日

  • zotozo
    10月7日

  • high_way
    10月7日

  • wangxin
    10月4日

字體大小:大?中?小博文 linux設(shè)備驅(qū)動(dòng)歸納總結(jié)(六):3.中斷下半部之tasklet?(2011-01-23 15:03)轉(zhuǎn)載 標(biāo)簽:??linux??設(shè)備驅(qū)動(dòng)??下半部??軟中斷??tasklet? 分類(lèi):?6中斷

linux設(shè)備驅(qū)動(dòng)歸納總結(jié)(六):3.中斷的上半部和下半部——tasklet


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


一、什么是下半部


中斷是一個(gè)很霸道的東西,處理器一旦接收到中斷,就會(huì)打斷正在執(zhí)行的代碼,調(diào)用中斷處理函數(shù)。如果在中斷處理函數(shù)中沒(méi)有禁止中斷,該中斷處理函數(shù)執(zhí)行過(guò)程中仍有可能被其他中斷打斷。出于這樣的原因,大家都希望中斷處理函數(shù)執(zhí)行得越快越好

另外,中斷上下文中不能阻塞,這也限制了中斷上下文中能干的事。

基于上面的原因,內(nèi)核將整個(gè)的中斷處理流程分為了上半部和下半部。上半部就是之前所說(shuō)的中斷處理函數(shù),它能最快的響應(yīng)中斷,并且做一些必須在中斷響應(yīng)之后馬上要做的事情。而一些需要在中斷處理函數(shù)后繼續(xù)執(zhí)行的操作,內(nèi)核建議把它放在下半部執(zhí)行。

拿網(wǎng)卡來(lái)舉例,在linux內(nèi)核中,當(dāng)網(wǎng)卡一旦接受到數(shù)據(jù),網(wǎng)卡會(huì)通過(guò)中斷告訴內(nèi)核處理數(shù)據(jù),內(nèi)核會(huì)在網(wǎng)卡中斷處理函數(shù)(上半部)執(zhí)行一些網(wǎng)卡硬件的必要設(shè)置,因?yàn)檫@是在中斷響應(yīng)后急切要干的事情。接著,內(nèi)核調(diào)用對(duì)應(yīng)的下半部函數(shù)來(lái)處理網(wǎng)卡接收到的數(shù)據(jù),因?yàn)閿?shù)據(jù)處理沒(méi)必要在中斷處理函數(shù)里面馬上執(zhí)行,可以將中斷讓出來(lái)做更緊迫的事情。


可以有三種方法來(lái)實(shí)現(xiàn)下半部:軟中斷、tasklet和等待隊(duì)列。


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


二、軟中斷


軟中斷一般很少用于實(shí)現(xiàn)下半部,但tasklet是通過(guò)軟中斷實(shí)現(xiàn)的,所以先介紹軟中斷。字面理解,軟中斷就是軟件實(shí)現(xiàn)的異步中斷,它的優(yōu)先級(jí)比硬中斷低,但比普通進(jìn)程優(yōu)先級(jí)高,同時(shí),它和硬中斷一樣不能休眠


軟中斷是在編譯時(shí)候靜態(tài)分配的,要用軟中斷必須修改內(nèi)核代碼。


kernel/softirq.c中有這樣的一個(gè)數(shù)組:

51?static struct softirq_action softirq_vec[NR_SOFTIRQS]?__cacheline_aligned_in_smp;

內(nèi)核通過(guò)一個(gè)softirq_action數(shù)組來(lái)維護(hù)的軟中斷NR_SOFTIRQS是當(dāng)前軟中斷的個(gè)數(shù),待會(huì)再看他在哪里定義。


先看一下softirq_action結(jié)構(gòu)體:

/*include/linux/interrupt.h*/

265 struct softirq_action

266 {

267 void (*action)(struct softirq_action *); //軟中斷處理函數(shù)

268 };

一看發(fā)現(xiàn),結(jié)構(gòu)體里面就一個(gè)軟中斷函數(shù),他的參數(shù)就是本身結(jié)構(gòu)體的指針。之所以這樣設(shè)計(jì),是為了以后的拓展,如果在結(jié)構(gòu)體中添加了新成員,也不需要修改函數(shù)接口。在以前的內(nèi)核,該結(jié)構(gòu)體里面還有一個(gè)data的成員,用于傳參,不過(guò)現(xiàn)在沒(méi)有了。


接下來(lái)看一下如何使用軟中斷實(shí)現(xiàn)下半部

一、要使用軟中斷,首先就要靜態(tài)聲明軟中斷:

/*include/linux/interrupt.h*/

246 enum

247 {

248 HI_SOFTIRQ=0, //用于tasklet的軟中斷,優(yōu)先級(jí)最高,為0

249 TIMER_SOFTIRQ, //定時(shí)器的下半部

250 NET_TX_SOFTIRQ, //發(fā)送網(wǎng)絡(luò)數(shù)據(jù)的軟中斷

251 NET_RX_SOFTIRQ, //接受網(wǎng)絡(luò)數(shù)據(jù)的軟中斷

252 BLOCK_SOFTIRQ,

253 TASKLET_SOFTIRQ, //也是用于實(shí)現(xiàn)tasklet

254 SCHED_SOFTIRQ,

255 HRTIMER_SOFTIRQ,

256 RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */

257 //add by xiaobai 2011.1.18

258 XIAOBAI_SOFTIRQ, //這是我添加的,優(yōu)先級(jí)最低

259

260 NR_SOFTIRQS, //這個(gè)就是上面所說(shuō)的軟中斷結(jié)構(gòu)體數(shù)組成員個(gè)數(shù)

261 };

上面通過(guò)枚舉定義了NR_SOFTIRQS(10)個(gè)軟中斷的索引號(hào),優(yōu)先級(jí)最高是0HI_SOFTIRQ),最低是我剛添加上去的XIAOBAI_SOFTIRQ,優(yōu)先級(jí)為9


二、定義了索引號(hào)后,還要注冊(cè)處理程序。

通過(guò)函數(shù)open_sofuirq來(lái)注冊(cè)軟中斷處理函數(shù),使軟中斷索引號(hào)與中斷處理函數(shù)對(duì)應(yīng)。該函數(shù)在kernel/softirq.c中定義:

/*kernel/softirq.c */

321 void open_softirq(int nr, void (*action)(struct softirq_action *))

322 {

323 softirq_vec[nr].action = action;

324 }

其實(shí)該函數(shù)就是把軟中斷處理函數(shù)的函數(shù)指針存放到對(duì)應(yīng)的結(jié)構(gòu)體中,一般的,我們自己寫(xiě)的模塊是不能調(diào)用這個(gè)函數(shù)的,為了使用這個(gè)函數(shù),我修改了內(nèi)核:

322 void open_softirq(int nr, void (*action)(struct softirq_action *))

323 {

324 softirq_vec[nr].action = action;

325 }

326 EXPORT_SYMBOL(open_softirq); //這是我添加的,導(dǎo)出符號(hào),這樣我編寫(xiě)的程序就能調(diào)用

在我的程序中如下調(diào)用:

/*6th_irq_3/1st/test.c*/

13 void xiaobai_action(struct softirq_action *t) //軟中斷處理函數(shù)

14 {

15 printk("hello xiaobai!\n");

16 }

。。。。。。。。

48 open_softirq(XIAOBAI_SOFTIRQ, xiaobai_action);


三、在中斷處理函數(shù)返回前,觸發(fā)對(duì)應(yīng)的軟中斷。

在中斷處理函數(shù)完成了必要的操作后,就應(yīng)該調(diào)用函數(shù)raise_sotfirq觸發(fā)軟中斷,讓軟中斷執(zhí)行中斷下半部的操作。

/*kernel/softirq.c*/

312 void raise_softirq(unsigned int nr)

313 {

314 unsigned long flags;

315

316 local_irq_save(flags);

317 raise_softirq_irqoff(nr);

318 local_irq_restore(flags);

319 }

所謂的觸發(fā)軟中斷,并不是指馬上執(zhí)行該軟中斷,不然和在中斷上執(zhí)行沒(méi)什么區(qū)別。它的作用只是告訴內(nèi)核:下次執(zhí)行軟中斷的時(shí)候,記得執(zhí)行我這個(gè)軟中斷處理函數(shù)。

當(dāng)然,這個(gè)函數(shù)也得導(dǎo)出符號(hào)后才能調(diào)用:

/*kernel/softirq.c*/

312 void raise_softirq(unsigned int nr)

313 {

314 unsigned long flags;

315

316 local_irq_save(flags);

317 raise_softirq_irqoff(nr);

318 local_irq_restore(flags);

319 }

320 EXPORT_SYMBOL(raise_softirq);

在我的程序中如下調(diào)用:

/*6th_irq_3/1st/test.c*/

18 irqreturn_t irq_handler(int irqno, void *dev_id) //中斷處理函數(shù)

19 {

20 printk("key down\n");

21 raise_softirq(XIAOBAI_SOFTIRQ);

22 return IRQ_HANDLED;

23 }


經(jīng)過(guò)三步,使用軟中斷實(shí)現(xiàn)下半部就成功了,看一下完整的函數(shù):

/*6th_irq_3/1st/test.c*/

1 #include <linux/module.h>

2 #include <linux/init.h>

3

4 #include <linux/interrupt.h>

5

6 #define DEBUG_SWITCH 1

7 #if DEBUG_SWITCH

8 #define P_DEBUG(fmt, args...) printk("<1>" "<kernel>[%s]"fmt, __FUNCTI ON__, ##args)

9 #else

10 #define P_DEBUG(fmt, args...) printk("<7>" "<kernel>[%s]"fmt, __FUNCTI ON__, ##args)

11 #endif

12

13 void xiaobai_action(struct softirq_action *t) //軟中斷處理函數(shù)

14 {

15 printk("hello xiaobai!\n");

16 }

17

18 irqreturn_t irq_handler(int irqno, void *dev_id) //中斷處理函數(shù)

19 {

20 printk("key down\n");

21 raise_softirq(XIAOBAI_SOFTIRQ); //觸發(fā)軟中斷

22 return IRQ_HANDLED;

23 }

24

25 static int __init test_init(void) //模塊初始化函數(shù)

26 {

27 int ret;

28

29 /*注冊(cè)中斷處理函數(shù):

30 * IRQ_EINT1:中斷號(hào),定義在"include/mach/irqs.h"

31 * irq_handler:中斷處理函數(shù)

32 * IRQ_TIRGGER_FALLING:中斷類(lèi)型標(biāo)記,下降沿觸發(fā)中斷

33 * ker_INT_EINT1:中斷的名字,顯示在/proc/interrupts等文件中

34 * NULL;現(xiàn)在我不使用dev_id,所以這里不傳參數(shù)

35 */

36 ret = request_irq(IRQ_EINT1, irq_handler,

37 IRQF_TRIGGER_FALLING, "key INT_EINT1", NULL);

38 if(ret){

39 P_DEBUG("request irq failed!\n");

40 return ret;

41 }

42

43 /*fostirq*/

44 open_softirq(XIAOBAI_SOFTIRQ, xiaobai_action); //注冊(cè)軟中斷處理程序

45

46 printk("hello irq\n");

47 return 0;

48 }

49

50 static void __exit test_exit(void) //模塊卸載函數(shù)

51 {

52 free_irq(IRQ_EINT1, NULL);

53 printk("good bye irq\n");

54 }

55

56 module_init(test_init);

57 module_exit(test_exit);

58

59 MODULE_LICENSE("GPL");

60 MODULE_AUTHOR("xoao bai");

61 MODULE_VERSION("v0.1");

注意。在上面的程序,只是為了說(shuō)明如何實(shí)現(xiàn)上下半步,而我的中斷上下半步里面的操作是毫無(wú)意義的(只是打印)。上下半步的作用我在一開(kāi)始就有介紹。

接下來(lái)驗(yàn)證一下:

[root: 1st]# insmod test.ko

hello irq

[root: 1st]# key down //上半部操作

hello xiaobai! //下半部操作

key down

hello xiaobai!

key down

hello xiaobai!

[root: 1st]# rmmod test

good bye irq


上面介紹,觸發(fā)軟中斷函數(shù)raise_softirq并不會(huì)讓軟中斷處理函數(shù)馬上執(zhí)行,它只是打了個(gè)標(biāo)記,等到適合的時(shí)候再被實(shí)行。如在中斷處理函數(shù)返回后,內(nèi)核就會(huì)檢查軟中斷是否被觸發(fā)并執(zhí)行觸發(fā)的軟中斷。

軟中斷會(huì)在do_softirq中被執(zhí)行,其中核心部分在do_softirq中調(diào)用的__do_softirq中:

/*kernel/softirq.c*/

172 asmlinkage void __do_softirq(void)

173 {

。。。。。。

194 do {

195 if (pending & 1) { //如果被觸發(fā),調(diào)用軟中斷處理函數(shù)

196 int prev_count = preempt_count();

197

198 h->action(h); //調(diào)用軟中斷處理函數(shù)

199

200 if (unlikely(prev_count != preempt_count())) {

201 printk(KERN_ERR "huh, entered softirq %td %p"

202 "with preempt_count %08x,"

203 " exited with %08x?\n", h - softirq_vec,

204 h->action, prev_count, preempt_count());

205 preempt_count() = prev_count;

206 }

207

208 rcu_bh_qsctr_inc(cpu);

209 }

210 h++; //下移,獲取另一個(gè)軟中斷

211 pending >>= 1;

212 } while (pending); //大循環(huán)內(nèi)執(zhí)行,知道所有被觸發(fā)的軟中斷都執(zhí)行完

。。。。。。


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


三、tasklet


上面的介紹看到,軟中斷實(shí)現(xiàn)下半部的方法很麻煩,一般是不會(huì)使用的。一般,我們使用tasklet——利用軟中斷實(shí)現(xiàn)的下半部機(jī)制


在介紹軟中斷索引號(hào)的時(shí)候,有兩個(gè)用于實(shí)現(xiàn)tasklet的軟中斷索引號(hào):HI_SOFTIRQTASKLET_SOFTIRQ。兩個(gè)tasklet唯一的區(qū)別就是優(yōu)先級(jí)的大小,一般使用TAKSLET_SOFTIRQ


先看一下如何使用tasklet,用完之后再看內(nèi)核中是如何實(shí)現(xiàn)的:

步驟一、編寫(xiě)tasklet處理函數(shù),定義并初始化結(jié)構(gòu)體tasklet_struct

內(nèi)核中是通過(guò)tasklet_struct來(lái)維護(hù)一個(gè)tasklet,介紹一下tasklet_struct里面的兩個(gè)成員:

/*linux/interrupt.h*/

319 struct tasklet_struct

320 {

321 struct tasklet_struct *next;

322 unsigned long state;

323 atomic_t count;

324 void (*func)(unsigned long); //tasklet處理函數(shù)

325 unsigned long data; //給處理函數(shù)的傳參

326 };


所以,在初始化tasklet_struct之前,需要先寫(xiě)好tasklet處理函數(shù),如果需要傳參,也需要指定傳參,你可以直接傳數(shù)據(jù),也可以傳地址。我定義的處理函數(shù)如下:

/*6th_irq_3/2nd/test.c*/

15 void xiaobai_func(unsigned long data)

16 {

17 printk("hello xiaobai!, data[%d]\n", (int)data); //也沒(méi)干什么事情,僅僅打印。

18 }


同樣,可以通過(guò)兩種辦法定義和初始化tasklet_struct

1、靜態(tài)定義并初始化

/*linux/interrupt.h*/

328 #define?DECLARE_TASKLET(name, func, data)?\

329 struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }

330

331 #define?DECLARE_TASKLET_DISABLED(name, func, data)?\

332 struct tasklet_struct name = { NULL, 0, ATOMIC_INIT

上面兩個(gè)函數(shù)都是定義一個(gè)叫nametasklet_struct,并指定他的處理函數(shù)和傳參分別是funcdata。唯一的區(qū)別是,DCLARE_TASKLET_DISABLED初始化后的處于禁止?fàn)顟B(tài),暫時(shí)不能被使用。

2、動(dòng)態(tài)定義并初始化

跟以往的一樣,需要先定義結(jié)構(gòu)體,然后把結(jié)構(gòu)體指針傳給tasklet_init來(lái)動(dòng)態(tài)初始化:

/*kernel/softirq.c*/

435 void tasklet_init(struct tasklet_struct *t,

436 void (*func)(unsigned long), unsigned long data)


在我的程序中,使用動(dòng)態(tài)定義并初始化:

/*6th_irq_3/2nd/test.c*/

13 struct tasklet_struct xiaobai_tasklet; //定義tasklet結(jié)構(gòu)體

32 tasklet_init(&xiaobai_tasklet, xiaobai_func, (unsigned long)123);

我這里的傳參直接傳一個(gè)數(shù)值123。這操作也相當(dāng)于:

DECLEAR_TASKLET(xiaobai_tasklet, xiaobai_func, (unsigned long)123);


步驟二、在中斷返回前調(diào)度tasklet


跟軟中斷一樣(其實(shí)tasklet就是基于軟中斷實(shí)現(xiàn)),這里說(shuō)的調(diào)度并不是馬上執(zhí)行,只是打個(gè)標(biāo)記,至于什么時(shí)候執(zhí)行就要看內(nèi)核的調(diào)度。

調(diào)度使用函數(shù)tasklet_schedule或者tasklet_hi_schedule,兩個(gè)的區(qū)別是一個(gè)使用TASKLET_SOFTIRQ,另一個(gè)使用HI_SOFTIRQ。這兩個(gè)函數(shù)都是一tasklet_struct指針為參數(shù):

/*linux/interrupt.h*/

365 static inline void tasklet_schedule(struct tasklet_struct *t)

373 static inline void tasklet_hi_schedule(struct tasklet_struct *t)


在我的函數(shù)中,使用tasklet_schedule

/*6th_irq_3/2nd/test.c*/

23 tasklet_schedule(&xiaobai_tasklet);


步驟三、當(dāng)模塊卸載時(shí),將tasklet_struct結(jié)構(gòu)體移除:

/*kernel/softirq.c*/

447 void tasklet_kill(struct tasklet_struct *t)

確保了?tasklet?不會(huì)被再次調(diào)度來(lái)運(yùn)行,通常當(dāng)一個(gè)設(shè)備正被關(guān)閉或者模塊卸載時(shí)被調(diào)用。如果?tasklet?正在運(yùn)行,?程序會(huì)休眠,等待直到它執(zhí)行完畢


另外,還有禁止與激活tasklet的函數(shù)。被禁止的tasklet不能被調(diào)用,直到被激活:

/*linux/interrupt.h*/

386 static inline void tasklet_disable(struct tasklet_struct *t) //禁止

393 static inline void tasklet_enable(struct tasklet_struct *t) //激活


最后附上程序:

/*6th_irq_3/2nd/test.c*/

1 #include <linux/module.h>

2 #include <linux/init.h>

3

4 #include <linux/interrupt.h>

5

。。。。省略。。。。

13 struct tasklet_struct xiaobai_tasklet; //定義tasklet結(jié)構(gòu)體

14

15 void xiaobai_func(unsigned long data)

16 {

17 printk("hello xiaobai!, data[%d]\n", (int)data);

18 }

19

20 irqreturn_t irq_handler(int irqno, void *dev_id) //中斷處理函數(shù)

21 {

22 printk("key down\n");

23 tasklet_schedule(&xiaobai_tasklet);

24 return IRQ_HANDLED;

25 }

26

27 static int __init test_init(void) //模塊初始化函數(shù)

28 {

29 int ret;

30

31 /*tasklet*/

32 tasklet_init(&xiaobai_tasklet, xiaobai_func, (unsigned long)123);

33

41 ret = request_irq(IRQ_EINT1, irq_handler,

42 IRQF_TRIGGER_FALLING, "key INT_EINT1", NULL);

43 if(ret){

44 P_DEBUG("request irq failed!\n");

45 return ret;

46 }

47

48 printk("hello irq\n");

49 return 0;

50 }

51

52 static void __exit test_exit(void) //模塊卸載函數(shù)

53 {

54 tasklet_kill(&xiaobai_tasklet);

55 free_irq(IRQ_EINT1, NULL);

56 printk("good bye irq\n");

57 }

58

59 module_init(test_init);

60 module_exit(test_exit);


最后驗(yàn)證一下,還是老樣子,上下半步只是打印一句話(huà),沒(méi)有實(shí)質(zhì)操作:

[root: 2nd]# insmod test.ko

hello irq

[root: 2nd]# key down //上半部操作

hello xiaobai!, data[123] //下半部操作

key down

hello xiaobai!, data[123]

[root: 2nd]# rmmod test

good bye irq


既然知道怎么使用tasklet,接下來(lái)就要看看它是怎么基于軟中斷實(shí)現(xiàn)的

上面說(shuō)明的是單處理器的情況下,如果是多處理器,每個(gè)處理器都會(huì)有一個(gè)tasklet_vectasklet_hi_vec鏈表,這個(gè)情況我就不介紹了。


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


四、總結(jié)


這節(jié)介紹了如何通過(guò)軟中斷(tasklet也是軟中斷的一種實(shí)現(xiàn)形式)機(jī)制來(lái)實(shí)現(xiàn)中斷下半部。使用軟中斷實(shí)現(xiàn)的優(yōu)缺點(diǎn)很明顯:

優(yōu)點(diǎn):運(yùn)行在軟中斷上下文,優(yōu)先級(jí)比普通進(jìn)程高,調(diào)度速度快。

缺點(diǎn):由于處于中斷上下文,所以不能睡眠。


也許有人會(huì)問(wèn),那軟中斷和tasklet有什么區(qū)別?

個(gè)人理解,tasklet是基于軟中斷實(shí)現(xiàn)的,基本上和軟中斷相同。但有一點(diǎn)不一樣,如果在多處理器的情況下,內(nèi)核不能保證軟中斷在哪個(gè)處理器上運(yùn)行(聽(tīng)起來(lái)像廢話(huà)),所以,軟中斷之間需要考慮共享資源的保護(hù)。而tasklet,內(nèi)核可以保證,兩個(gè)同類(lèi)型(TASKLET_SOFTIRQHI_SOFTIRQ)的tasklet不能同時(shí)執(zhí)行,那就說(shuō)明,同類(lèi)型tasklet之間,可以不考慮同類(lèi)型tasklet之間的并發(fā)情況。


一般的,優(yōu)先考慮使用tasklet

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

源代碼:?6th_irq_3(1).rar???

分享到:新浪微博QQ空間開(kāi)心網(wǎng)豆瓣人人網(wǎng)twitterfb 0?
???
閱讀(975)┊?評(píng)論?(1)┊收藏(0)┊舉報(bào)┊打印 前一篇:linux設(shè)備驅(qū)動(dòng)歸納總結(jié)(六):2.分享中斷號(hào) [發(fā)評(píng)論]?評(píng)論?重要提示:警惕虛假中獎(jiǎng)信息!
  • 回復(fù)?舉報(bào) songtao0728?2011-08-09 15:10 請(qǐng)教一個(gè)問(wèn)題:
    我在按你的方面試驗(yàn)軟中斷,編譯通過(guò)后,下載到開(kāi)發(fā)板后,加載出現(xiàn):
    soft: Unknown symbol raise_softirq
    soft: Unknown symbol open_softirq
    insmod: cannot insert 'soft.ko':unknown symbol in module or invalid parameter
    這是不是因?yàn)槲业拈_(kāi)發(fā)板的系統(tǒng)沒(méi)有這兩個(gè)函數(shù)的導(dǎo)出符號(hào)所導(dǎo)致的?
    我如果不重新編譯開(kāi)發(fā)板的內(nèi)核的話(huà),是不是還有別的辦法解決?
發(fā)評(píng)論 關(guān)于我們?|?關(guān)于IT168?|?聯(lián)系方式?|?廣告合作?|?法律聲明?|?免費(fèi)注冊(cè) Copyright ? 2001-2010 ChinaUnix.net All Rights Reserved 北京皓辰網(wǎng)域網(wǎng)絡(luò)信息技術(shù)有限公司. 版權(quán)所有 感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們
京ICP證041476號(hào) 京ICP證060528號(hào)

總結(jié)

以上是生活随笔為你收集整理的linux设备驱动归纳总结(六):3.中断下半部之tasklet的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。