Linux设备驱动之tasklet----中断底半部机制

文章为本人学习笔记和总结,如有错误,请多多指教;

引言:

linux实现中断底半部的机制主要有tasklet、工作队列、软中断和线程化;

本文先介绍下tasklet

1、tasklet

tasklet是一个可以由系统决定的安全时刻的软中断上下文被调度的特殊函数;简言之就是tasklet的执行实在中断上下文中,执行时机通常是顶半部返回时;由于tasklet是在中断上下文中执行,因此tasklet的执行必须原子模式的;

为什么有软中断还需要tasklet,原因如下:

由于软中断必须使用可重入函数,这就导致设计上的复杂度变高,作为设备驱动程序的开发者来说,增加了负担。而如果某种应用并不需要在多个CPU上并行执行,那么软中断其实是没有必要的。因此诞生了弥补以上两个要求的tasklet。它具有以下特性: 
a)一种特定类型的tasklet只能运行在一个CPU上,不能并行,只能串行执行。 
b)多个不同类型的tasklet可以并行在多个CPU上。 
c)软中断是静态分配的,在内核编译好之后,就不能改变。但tasklet就灵活许多,可以在运行时改变(比如添加模块时)。 
tasklet是在两种软中断类型的基础上实现的,因此如果不需要软中断的并行特性,tasklet就是最好的选择。也就是说tasklet是软中断的一种特殊用法,即延迟情况下的串行执行;

tasklet的使用也非常简单:

  • tasklet的数据结构:
#include <linux/interrupt.h>

struct tasklet_struct{
    /*...*/
    void (*func)(unsigned long);
    unsigned long data;
}

void tasklet_init(struct tasklet_struct *t, 
    void (*func)(unsigned long),unsigned long data);
DECLARE_TASKLET(my_tasklet, my_tasklet_func, data);
DECLARE_TASKLET_DISABLED(my_tasklet, my_tasklet_func, data);

代码DECLARE_TASKLET(my_tasklet, my_tasklet_func, data)实现了定义名称为my_tasklet的tasklet,并与my_tasklet_func()这个函数绑定,而传入函数的参数为data。

  • 如何调度自己定义的tasklet呢?

在需要调度tasklet的时,可以引入一个tasklet_schedule(struct tasklet_struct *t)函数就能使系统在适当的时候进行调度:如

扫描二维码关注公众号,回复: 9190216 查看本文章
tasklet_schedule(&my_tasklet);   //调度执行指定的tasklet--mytasklet 
  • 使用tasklet作为中断底半部的处理机制的设备驱动程序模板如下:
void xxx_do_tasklet(unsigned long data);
DECLARE_TASKLET(xxx_tasklet, xxx_do_tasklet, data);

/*中断处理的底半部*/
void xxx_do_tasklet(unsigned long data)
{
    ...
}

irqreturn_t xxx_interrupt(int irq, void *dev_id)
{
    ...
    tasklet_schedule(&xxx_tasklet);
    ...
}

/*设备驱动模块初始化函数*/
int __init xxx_init(void)
{
    ...
    /*申请中断*/
    result = request_irq(xxx_irq, xxx_interrupt, 0, "xxx_name", NULL);
    ...
    return IRQ_HANDLED;
}

/*设备驱动模块卸载*/
void __init xxx_exit(void)
{
    ...
    /*释放中断*/
    free_irq(xxx_irq, xxx_interrupt);
    ...
}

上述程序在模块加载函数中申请中断,在模块卸载函数中释放它。对应于xxx_irq的中断处理程序被设置为xxx_interrupt()函数,在这个函数中,执行tasklet_schedule(&xxx_tasklet)调度被定义的tasklet函数xxx_do_tasklet(),该函数将在适当的时候执行;

发布了14 篇原创文章 · 获赞 15 · 访问量 4004

猜你喜欢

转载自blog.csdn.net/wsq_zqfl/article/details/84076028
今日推荐