linux中,中断的处理方法 tasklet软中断

1、在linux中,对中断的处理有原则

对中断的处理原则有两个:
1)、中断不能嵌套中断(即使发生了更高优先级的中断)–》防止栈空间不够用。
因为每个中断被执行,都要先保存现场。如果中断1在执行的过程中,嵌套了中断2;那么在中断2在被执行之前,中断1的现场应该先被保存(保存在栈中)。同样,如果还嵌套了其他中断,还要将现场保存在栈中。这样,就会发生一个问题,如果嵌套的中断很多,那么可能会导致栈空间不够用。为了避免这个问题,不允许中断嵌套。
2)、对中断的处理应当越快越好。
假设系统只有一个CPU,一个进程在执行过程中,发生了一个中断,这个中断将要执行1分钟。那么,这个进程在1分钟之内,将不能执行其他任何操作。这中情况,是不能被允许的。

2、耗时中断的处理方式

前言

在上节分析中,我们知道,中断的处理应该越快越好。但是,在实际的应用中,总会有一些耗时的中断。为了处理耗时的中断,为了实现中断的快进快出,我们将中断分为上半部/下半部 。中断下半部的实现,主要有软件中断,tasklet和任务队列。其中,tasklet是基于软中断来实现的,实际应用中,多用tasklet,而不用软件中断。

2.1软中断

在这里插入图片描述
那么,下半部是如何实现的呢?
答案是软件中断

2.1.1为了更好的理解软件中断,我们将软件中断和硬件中断一起来分析:

在这里插入图片描述
在这里插入图片描述

2.1.2软件中断的实现流程:

在这里插入图片描述

2.2 tasklet

软件中断有很多,那么我们的中断下半部属于哪种软件中断呢?

enum
{
    
      HI_SOFTIRQ=0,
    TIMER_SOFTIRQ,
    NET_TX_SOFTIRQ,
    NET_RX_SOFTIRQ,
    BLOCK_SOFTIRQ,
    TASKLET_SOFTIRQ,
    SCHED_SOFTIRQ,
    HRTIMER_SOFTIRQ,};
再这份枚举表,记录了所有软件

中断的类型。其中, TASKLET_SOFTIRQ,也叫做tasklet软件中断,是用来处理中断下半部。

2.2.1 tasklet的实现原理图

在这里插入图片描述

2.2.2 tasklet的使用

中断下半部使用结构体 tasklet_struct 来表示,以下简称tasklet。
先定义/初始化 tasklet(一般在probe()函数里面),可以使用函数tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);也可以直接定义tasklet结构体:
struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data };
需要使用时调用 tasklet_schedule,驱动卸载前调用 tasklet_kill。
tasklet_schedule 只是把 tasklet 放入内核队列,它的 func 函数会在软件中断的执行过程中被调用。
注:
tasklet具有如下特性:
1)、 tasklet可以被多次调度,但是调度不会累积。即实际只会运行一次。
2)、 tasklet运行在中断上下文,tasklet处理函数中不能睡眠。

猜你喜欢

转载自blog.csdn.net/cainiaofu/article/details/115371821