1、概述

中断分层技术:
(1)中断嵌套
(2)中断分层方式
(3)使用工作队列实现分层

2、中断嵌套概念

(1)慢速中断概念

(2)快速中断:不接受中断嵌套,其他中断发生会直接丢弃

 

3、中断分层

为什么要中断分层?中断会做两种事情的工作,一种是跟硬件有关的事情,比如说之前的检查中断发生,清除中断。第二种是处理数据的处理。也分为上半部和下半部。

中断分层的方式有以下三种:

(1)软中断
(2)tasklet
(3)工作队列

4、工作队列

工作队列的引入是一种将任务推后的执行方式,在内核线程中通过一个队列的方式把所有中断的下半部工作组成队列。它允许重新调度甚至睡眠。

Linux内核使用struct workqueue_struct来描述一个工作队列:
struct workqueue_struct {
  struct cpu_workqueue_struct *cpu_wq;
  struct list_head list;
  const char *name;
  int singlethread;
  int freezable;
  int rt;
};这个结构体是用来干嘛的????

Linux内核使用struct work_struct来描述一个工作项:
struct work_struct {
  atomic_long_t data;
  struct list_head entry;
  work_func_t func;
};工作队列结构体,创建的结构体需要调用INIT_WORK函数进行初始化。
typdef void (*work_func_t)(struct work_struct *work);

工作过程:
(1)创建工作队列,大多数情况驱动不需要直接建立队列,只需要将工作提交到内核以及定义好的工作队列。
create_workqueue
(2)创建工作
INIT_WORK
(3)提交工作
queue_work

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

struct workqueue_struct *my_wq;
struct work_struct *work1;
struct work_struct *work2;
MODULE_LICENSE("GPL");

void work1_func(struct work_struct *work)
{
    printk("this is work1->\n");    
}
void work2_func(struct work_struct *work)
{
    printk("this is work2->\n");    
}
int init_que(void)
{
    //1. 创建工作队列
    my_wq = create_workqueue("my_que"); 
    //2. 创建工作
    work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);
    INIT_WORK(work1, work1_func);
    //3. 挂载(提交)工作
    queue_work(my_wq,work1);//schedule_work(work1);
    //2. 创建工作
    work2 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);
    INIT_WORK(work2, work2_func);  
    //3. 挂载(提交)工作
    queue_work(my_wq,work2);//schedule_work(work2);
    
    return 0;
}

void clean_que()
{
}

module_init(init_que);
module_exit(clean_que);