Linux驱动开发-中断分层机制笔记 6

中断分层机制—tasklet

中断上下文

  • 因为中断产生时会打断当前占用CPU的进程,为尽量提高进程的运行效率,不会卡顿,从而使中断服务程序分为顶半部和底半部两个部分

  • 顶部分是用来处理应急事件,特别是硬件相关;之后将CPU使用权交个当前进程

  • 底部分(不着急处理的,任务繁琐的)则等待CPU空闲时,既内核线程觉得有能力运行时才去执行。

注意事项

  • i. 中断上下文代码绝对不可以停止运行

  • 中断处理程序不能调用schedule_timeout()等随眠函数放弃CPU

  • 在中断处理函数中调用一个内核API之前,应该仔细分析,确保内部不会触发阻塞等待.

  • 为了中断处理函数中保存临界区,不能使用互斥体,应该使用自旋锁代替互斥体,只有在不得不用的时候采用

  • 中断处理函数不能与用户空间直接交互数据,应为它们经由进程上下文与用户空间建立连接

  • 中断函数不必是可重用的

  • 中断函数可以被更高优先级IRQ的中断打断

a) 快速中断不可被打断:既执行快速中断时,处理器所有中断都会被屏蔽

b) 同步中断:有处理器本身执行某些指令产生;如:

  • 异常:用于报告严重的运行时错误

    软中断:

2、中断分层实现,底半部处理方法

a) 任务:struct tasklet

b) 工作队列: struct work_struct

c) 软中断:

3、tasklet 编程实现相关函数

a) 数据结构:

struct tasklet_struct
{

    struct tasklet_struct *next;

    unsigned long state;

    atomic_t count;

    void (*func)(unsigned long); /*需要驱动完成的函数*/

    unsigned long data; /*传递给func函数?*/

};

b) 主要特征

   Main feature differing them of generic softirqs: tasklet

   is running only on one CPU simultaneously.

   Main feature differing them of BHs: different tasklets

   may be run simultaneously on different CPUs.

c) 定义tasklet:struct tasklet my_tasklet

d) 定义处理函数:void my_tasklet_func(unsigned long)

e) 关联tasklet 和处理函数:

 DECLARE_TASKLET(my_tasklet,my_tasklet_func,data);

解释:将my_tasklet 与处理函数绑定,并将data作为参数传递给my_task_func

f) 调度(交给系统自行处理):tasklet_schedule(&my_tasklet)

4、使用tasklet作为中断底半部的设备驱动程序模板

/*1.定义结构体*/

struct tasklet_struct my_tasklet;

/*2.编写底半部函数*/

void xxx_do_tasklet(unsigned long x)

{

...

}

/*3.关联函数*/

DECLARE_TASKLET(my_tasklet,xxx_do_tasklet,0);

/*4.中断处理顶半部*/

static irqreturn_t xxx_interrupt(int irq, void *dev_id)

{

...

/*提交takslet并启动调度*/

  tasklet_schedule(&my_tasklet);

...

}

/*5.模块加载*/

module_init(xxxx)

{

  .....

/*申请中断*/

       ......

}

/*6.模块卸载*/

module_exit(yyyy)

{

/*释放中断*/

}

Takslet驱动测试–【无中断测试】

/**********************************

作者:hntea

时间:2016/3/14

驱动功能:tasklet 模板功能测试

**********************************/



#include<linux/init.h>

#include<linux/module.h>

#include<linux/interrupt.h>

#include<linux/time.h>

/*定义 tasklet */

struct tasklet_struct my_tasklet;



/*定义服务函数,任务提交后只执行一次*/

static void my_taskfunc(unsigned int x)

{

    printk("I am taskfunc\n");

    printk("My argument is:%d\n",x);

}



/*关联结构体和服务函数*/

DECLARE_TASKLET(my_tasklet,my_taskfunc,1);

static int irqTask_init(void)

{

     tasklet_schedule(&my_tasklet); /*一般提交任务在中断处理函数中提交,实现分层*/

    return 0;

}

static void irqTask_exit(void)

{

}


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Hntea");
module_init(irqTask_init);
module_exit(irqTask_exit);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值