Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4241991
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: LINUX

2012-01-01 18:54:23

《linux内核设计与实现2》章节中p80

tasklet结构体
  1. linux-2.6.35 src/include/linux/interrupt.h

  2. 450  struct tasklet_struct
  3.  451 {
  4.  452   struct tasklet_struct *next;//链表中的下一个tasklet
  5.  453   unsigned long state; //tasklet的状态
  6.  454   atomic_t count;     // 引用计数器
  7.  455   void (*func)(unsigned long);//tasklet处理函数 
  8.  456   unsigned long data;//给tasklet处理函数的参数
  9.  457 };
state参数:0、TASKLET_STATE_SCHED、TASKLET_STATE_RUN之间一个
在src/linux/interrupt.h 定义了上述
  1. 466  enum
  2.  467 {
  3.  468   TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution tasklet已被调度,正准备投入运行
  4.  469   TASKLET_STATE_RUN /* Tasklet is running (SMP only) */tasklet正在运行
  5.  470 };
  6.  471
count参数:是tasklet的引用参数。如果它不为0,则tasklet被禁止,不允许执行;只有当它为0时,tasklet才被激活,并且在被设置为挂起状态时,该tasklet才能够执行。 N_NONBLOCK 非阻塞

    大多数情况下,为了控制一个寻常的硬件设备,tasklet机制都是实现你自己的下半部的最佳选择。

1. 声明自己的tasklet
我们可以静态或动态分别创建它。

静态创建:
DECLARE_TASKLET(name,func,data);//引用计数器count=0,激活状态
DECLARE_TASKLET_DISABLE(name,func,data);//引用计数器count=1,禁止状态
这里的data是unsigned long类型,传入 void func(unsigned long p)函数中

这里声明
DECLARE_TASKLET(mytasklet,myhandler,dev)等同于
struct tasklet_struct mytasklet={NULL,0,ATOMIC_INIT(0),myhandler,dev};

动态创建
src/kernel/softirq.c
  1. void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long),unisgned long data);
初始化 tasklet_struct 结构体,将引用计数器count=0,和状态state=0。

struct tasklet_struct my_tasklet;
tasklet_init(&my_tasklet,myfunc,data);//动态创建

2. 编写自己的tasklet处理程序
void tasklet_handler(unsigned long data);
y因为是靠软中断实现,所以在tasklet不能睡眠。那么不能再tasklet中使用 信号量或者其他睡眠阻塞式的函数。


3. 调度自己的tasklet
tasklet_schedule(&my_tasklet);//把my_tasklet标记为挂起

4.开启、关闭指定的tasklet
tasklet_disable(&my_tasklet);
.......
tasklet_enable(&my_tasklet);


========================================================================
附件代码: interrupt_tasklet.rar   将rar修改为tar.bz2 在“5 第一个中断程序”修改增加tasklet内容 键盘中断 IRQ1

增加的内容:

  1. static struct tasklet_struct mytasklet;
  2. ...

  3. ////tasklet底半部机制 处理函数
  4. static void mytasklet_handler(unsigned long data);
  5. ...

  6. static irqreturn_t myirq_handler(int irq, void *dev)
  7. {  
  8.         static int count = 0;
  9.         if(count<10)
  10.         {
  11.                 printk("<0>--%d start--\n",count+1);
  12.                 tasklet_init(&mytasklet,mytasklet_handler,0);////动态申请 tasklet
  13.                 tasklet_schedule(&mytasklet);
  14.                 printk("<0>the top hafl has beed done and bottme will be process..\n");
  15.         }
  16.         else
  17.         {
  18.                 printk("count=%d\n",count);
  19.         }
  20.         count++;

  21.         return IRQ_HANDLED;
  22. }
  23. static void mytasklet_handler(unsigned long data)
  24. {
  25.         printk("<0>this is tasklet handler..\n");
  26. }

使用方法:
  1. root@ywx:/home/ywx/desktop/module/edi/interrupt/interrupt_tasklet# cat /proc/interrupts | grep ywx  //查看没有 ywx这个中断
  2. root@ywx:/home/ywx/desktop/module/edi/interrupt/interrupt_tasklet# insmod ./interrupt.ko irq=1 devname=ywxdevname 
  3. root@ywx:/home/ywx/desktop/module/edi/interrupt/interrupt_tasklet# cat /proc/interrupts | grep ywx
  4.   1: 33785 IO-APIC-edge i8042, ywxdevname 中断号名称
  5. root@ywx:/home/ywx/desktop/module/edi/interrupt/interrupt_tasklet# dmesg | tail -100 | more
  6. [31967.389901] Module is working...
  7. [31967.389987] ywxdevname request IRQ:1 success..
  8. [31967.467587] --1 start--
  9. [31967.467692] the top hafl has beed done and bottme will be process..
  10. [31967.467759] this is tasklet handler..
  11. [31968.315207] --2 start--
  12. [31968.315237] the top hafl has beed done and bottme will be process..
  13. [31968.315247] this is tasklet handler..
  14. 。。。。
  15. [31970.429523] --10 start--
  16. [31970.429542] the top hafl has beed done and bottme will be process..
  17. [31970.429552] this is tasklet handler.. 当操作10次键盘中断后,只显示中断次数了
  18. [31970.514558] count=10
  19. [31971.157066] count=11
  20. [31971.157987] count=12
  21. [31971.264544] count=13
=============================================================

资料:
1.edsionte's Linuxworld|新手区  中断下半部-tasklet


阅读(1682) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~