美文网首页Linux驱动
L8. Linux中断下半部实现机制

L8. Linux中断下半部实现机制

作者: 开源519 | 来源:发表于2020-06-29 16:57 被阅读0次

1. 中断上、下半部产生背景

由于内核中中断不允许嵌套,在程序进入中断后,系统会关闭中断接收,这段时间内,其他中断都无法处理导致中断无法响应,因此需要当前进入的中断子服务函数越快越好。但是在一些特殊情况下,中断要处理的事情可能是复杂且冗长的,为解决这种问题,
中断上下半部的概念顺势而生。将中断拆成两部分,上半部用来处理紧急的事情;下半部用来处理不紧急的事情。

2. 运行机制

(1) tasklet方式: 当下半部处理的事情耗时但是可以忍受时,可以使用tasklet。tasklet是以软中断形式实现的,软中断的优先级仅次于硬件中断,在进入软件中断时,硬件中断会被打开,因此软件中断可被硬件中断打断。
使用: 软中断实现服务子函数,优先级高,影响系统执行效率。
a. 初始化:

静态(编译时创建):
DECLARE_TASKLET(kpd_keymap_tasklet, kpd_keymap_handler, 0);
动态(在函数probe或其他入口函数初始化): 
struct tasklet_struct kpd_keymap_tasklet; 
tasklet_init(&kpd_keymap_tasklet, kpd_keymap_handler, 0);

b. 下半部实现:

static void kpd_keymap_handler(unsigned long data)
{
}

c. 在硬件中断服务函数,调度:

tasklet_schedule(&kpd_keymap_tasklet);

d. 在退出函数,销毁:

tasklet_kill(&kpd_keymap_tasklet); 

(2) 工作队列方式: 在tasklet方式中,虽然开中断了,期间可处理系统各种中断,但是软中断的优先级也会导致其他的线程无法运行。如果时间过长,会导致系统卡顿且APP也无法运行的现象。此时选择内核线程来处理下半部:在中断上半部将下半部处理函数放入工作队列,且唤醒工作队列线程,然后退出中断。包含下半部的工作队列与APP都有机会执行,不会造成卡顿。
使用: 一个工作线程处理多个中断服务子函数。
a. 初始化

静态:
DECLARE_WORK(my_work, my_func, &data); 
动态: 
struct work_struct my_work; 
INIT_WORK(&my_work, my_func, &data);

b. 下半部实现

void my_func()
{
}

c. 在硬件中断调度

schedule_work(&my_work); //工作完成后会自动销毁

注意: 也可以自定义工作队列,实现任务调度,这里不作介绍。

(3) 线程中断:由于工作队列每次只能处理一个中断下半部,但是内核支持多线程,因此出现为每一个中断下半部开辟一个线程处理。将多个中断的下半部线程分配给多个CPU上执行,提高效率。
使用: 一个线程对应一个中断服务子函数,效率高,占用资源。
在程序中调用request_threaded_irq

原型: 
/* irq: 中断号
 * handler: 中断服务子函数
 * thread_fn: 中断线程化
 * irqflags: 中断触发标志位
 * devname: 请求中断的设备名称
 * dev_id: 传递给thread_fn参数,通常为设备结构体
*/
int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn,
unsigned long irqflags, const char *devname, void *dev_id);

实例:

int request_threaded_irq(irq, isr, my_func, IRQF_TRIGGER_FALLING, "key_isr", &key_quest[i]);

下半部:

static irqreturn_t my_func (int irq, void *data) 
{
   ……
   return IRQ_HANDLED;
}

中断服务子函数:

static irqreturn_t isr(int irq, void *dev_id)
{
……
    return IRQ_WAKE_THREAD;
}

触发流程:
先进入中断服务子函数handler 返回IRQ_WAKE_THREAD,然后会进入线程化中断my_func。
每个中断都会对应一个线程,互不干扰,效率更高。

相关文章

  • L8. Linux中断下半部实现机制

    1. 中断上、下半部产生背景 由于内核中中断不允许嵌套,在程序进入中断后,系统会关闭中断接收,这段时间内,其他中断...

  • 软中断

    含义 为了解决中断处理程序执行过长和中断丢失的问题,Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部...

  • Linux内核中的软中断、tasklet和工作队列详解

    软中断、tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bott...

  • Linux中断编程

    Linux中断编程视频1-Linux中中断到概念和中断处理机制题目:中断的作用是什么?答案:中断是外设异步通知so...

  • linux 中断机制

    1 中断介绍 1.1 简介 中断控制是计算机发展中一种重要的技术。最初它是为克服对I/O接口控制采用程序查询所带来...

  • Linux中断机制

    1、硬中断 2、软中断 3、软中断信号

  • 计算机操作系统笔记(四)

    2-3中断机制(SHD) 中断 中断定义 指CPU对突发的反应过程或机制 引入中断的目的 实现并发活动实现实时处理...

  • Linux中断的上半部与下半部

    1、什么是下半部   中断是一个很霸道的东西,处理器一旦接收到中断,就会打断正在执行的代码,调用中断处理函数。如果...

  • 系统调用 - syscall

    linux系统调用是通过中断实现的,软中断指令int发起中断信号。linux只占用一个中断向量号,即:0x80。系...

  • 理解Linux中的软中断

    Linux 将中断处理过程分成了2个阶段: 上半部: 下半部: 比如以网卡接收到数据包为例:网卡接收到数据包后,会...

网友评论

    本文标题:L8. Linux中断下半部实现机制

    本文链接:https://www.haomeiwen.com/subject/ngfafktx.html