Linux中断的实现(二)

        内核将整个的中断处理流程分为了上半部和下半部。上半部就是之前所说的中断处理函数,它能最快的响应中断,并且做一些必须在中断响应后马上要做的事,而一些需要在处理函数后继续执行的操作,内核建议把它放在下半部执行。

三种方法可以实现下半部:软中断、tasklet和工作队列。

 

一、软中断

软中断即软件实现的异步中断,它的优先级比硬件中断低,但比普通进程优先级高,它和硬中断一样不能休眠。软中断很少用于实现下半部,但tasklet是通过软中断实现的。

软中断是在编译的时候静态分配的,要使用软中断必须修改内核代码。软中断实现下半部的方法很麻烦,而且很少使用,在此就不进行分析了。

 

二、tasklet

1、内核通过tasklet_struct来维护一个tasklet

struct tasklet_struct                                                                                

{

    struct tasklet_struct *next;

    unsigned long state;

    atomic_t count;

    void (*func)(unsigned long); //tasklet处理函数

    unsigned long data; //传给处理函数的参数

};

在初始化tasklet_struct之前,需要先定义好tasklet处理函数,如果需要传参,也需要指定参数,可以直接传数据,也可以传地址。如:

void heql_func(unsigned long data)

{

......

}

 

2、可以通过两种方式定义和初始化tasklet_struct

(1)静态初定义并初始化

#define DECLARE_TASKLET(name, func, data) \

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

 

#define DECLARE_TASKLET_DISABLED(name, func, data) \

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

这两个函数都是定义一个名字为nametasklet_struct,并指定它的处理函数和传参分别为funcdata。区别是:DECLARE_TASKLET_DISABLED初始化后的处于禁止状态,暂时不能被调用。

(2)动态初始化

先定义结构体,然后把结构体指针传给tasklet_init来初始化

/*kernel/softirq.c*/

void tasklet_init(struct tasklet_struct *t,                                                          

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

如:

struct tasklet_struct heql_tasklet; //定义结构体

tasklet_init(&heql_tasklet, heql_func, (unsigned long)666);

效果相当于静态初始化:

DECLEAR_TASKLET(heql_tasklet, heql_func, (unsigned long)666);

 

3、在中断返回前调度tasklet

调度使用函数tasklet_schedule或者tasklet_hi_schedule,区别是:一个使用TASKLET_SOFTIRQ,另一个使用HI_SOFTIRQ

static inline void tasklet_schedule(struct tasklet_struct *t)

static inline void tasklet_hi_schedule(struct tasklet_struct *t)

如:

tasklet_schedule(&heql_tasklet);

 

4、模块卸载时,将tasklet_struct结构体移除

void tasklet_kill(struct tasklet_struct *t)

当一个设备正被关闭或者模块卸载时被调用,如果tasklet正在运行,程序会休眠,知道它执行完毕。

 

5、禁止与激活tasklet

被禁止的tasklet不能被调用,直到被激活。

static inline void tasklet_disable(struct tasklet_struct *t)

static inline void tasklet_enable(struct tasklet_struct *t)

 

以上介绍了tasklet机制来实现中断上下半部。

优点:运行在软中断上下文,优先级比普通进程高,调度速度快。

缺点:由于处于中断上下文,所以不能睡眠。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值