中断分层技术

当Linux系统在处理中断响应时,若有新的中断产生,Linux系统对新中断的处理方法与正在处理的中断类型有关,分为慢速中断和快速中断两种情况。

慢速中断:当处理慢速中断时,中断总开关是不关闭的,允许别的中断产生。例如正在处理串口慢速中断,此时网卡产生中断,则cpu会转去执行网卡中断,执行完网卡中断后才继续执行串口中断;若正在处理串口慢速中断,此时串口产生新的中断,则cpu会忽略这次新的中断。
快速中断:在处理快速中断的过程中,系统不会接收新的中断,即会忽略所有新中断。

从以上可以看出,Linux系统有时会忽略产生的中断,这会导致一些中断无法得到应有的处理。采用中断分层技术能减少中断丢失的概率。

一般来说,中断处理函数要完成的工作有与硬件密切相关的,也有与硬件关联不大的操作。中断分层技术将与硬件密切相关的操作作为上部分,与硬件关联不大的操作作为下半部。上半部依然由中断处理函数来完成,下半部不设置在中断处理函数中执行,从而减少了中断处理函数的工作,进而缩短中断处理的时间。

上半部:当中断发生时,它进行相应地硬件读写,并“登记”该中断。通常由中断处理程序充当上半部。
下半部:在系统空闲的时候对上半部“登记”的中断进行后续处理。


中断分层方式:软中断、tasklet、工作队列(主流)
工作队列是一种将任务推后执行的形式,他把推后的任务交由一个内核线程去执行。这样如果在中断函数中使用中断分层(工作队列方式),中断函数的第二部分会在进程上下文执行,它允许重新调度甚至睡眠。每个被推后的任务叫做“工作”,由这些工作组成的队列称为工作队列。工作队列的本质就是将工作交给内核线程处理,因此其可以用内核线程替换。但是内核线程的创建和销毁对编程者的要求较高,而工作队列实现了内核线程的封装,不易出错,所以推荐使用工作队列。


这里写图片描述

当工作队列中的工作执行完后,该工作就会被删除。
内核使用struct workqueue_struct来描述一个工作队列;

struct workqueue_struct
{
    struct cpu_workqueue_struct *cpu_wq;
    struct list_head list;
    const char *name; /*workqueue name*/
    int singlethread;
    int freezeable; /* Freeze threads during suspend */
    int rt;
};

内核使用struct work_struct来描述一个工作项;

struct work_struct 
{
    atomic_long_t data;
    struct list_head entry;
    work_func_t func;
};

work_struct 结构中最重要的成员是func,该成员是该工作项要执行的函数。


使用工作队列:
①创建工作队列:create_workqueue;创建工作队列首先要遵守“GPL”协议,不然会报错
②创建工作:INIT_WORK;
③提交工作:queue_work,提交工作后并不是马上运行,由内核空闲时内核线程会运行创建的工作队列

在大多数情况下,驱动并不需要自己创建工作队列,只需要定义工作,然后将工作提交到内核已经定义好的工作队列Keventd_wq中。
提交工作到默认队列:schedule_work

#include <linux/init.h>
#include <linux/module.h>

struct work_struct *work1;

MODULE_LICENSE("GPL");

void work1_func(struct work_struct *work)
{
    printk("this is work1->\n");    
}

int init_que(void)
{   
    //创建工作
    work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);
    INIT_WORK(work1, work1_func);

    //挂载(提交)工作
    schedule_work(work1);

    return 0;
}

void clean_que()
{

}

module_init(init_que);
module_exit(clean_que);

在中断处理程序中,一般工作队列的创建工作在内核模块的安装部分完成,提交工作在中断处理函数中完成,则发生中断后内核线程就能找到工作项并执行。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值