《Linux驱动基础篇》- Linux的中断系统

中断意义:

        中断本质上是一个电信号,它的出现时为了高效管理计算机外设。

        轮询:早期并没有中断的概念,CPU要管理外围设备需要采用轮询的方式,来探测外围设备是否有数据要处理。这样效率太低,CPU要花大量时间来检测设备,而无法做更多的事情。

        中断:后来出现了中断,将CPU从检测任务中解救出来,CPU与外设的处理变为异步。CPU可以干着其他事情,等设备主动上报。(本文主要讨论异步中断)

        而事实上外设并不直接发送中断信号给CPU,为了管理系统中的众多中断,采用了中断控制器。外设将中断信号发送给中断控制器,中断控制器处理信号并向CPU发送中断请求。CPU停止当前运行的进程,转而执行中断服务程序,最后返回到被中断的进程。这里的描述比价模糊,有必要梳理清楚“停止、转而执行、返回”的具体过程。

中断分类:

        同步中断:当指令执行时由CPU控制单元产生,它是在执行一条指令后产生的中断,而不是执行指令期间。

        异步中断:由其他硬件设备依照CPU时钟信号随机产生,它是在CPU执行指令期间发生。

        根据Intel资料,同步中断被称为异常,异步中断被称为中断。

        异常可以分为:故障、陷阱、终止;中断可以分为:可屏蔽中断、不可屏蔽中断。

        系统为每一个中断都定义了一个标识号叫做中断号、或者中断向量号。

中断原理:

        

        为了不陷入具体的硬件细节,这里画出了中断硬件系统的抽象结构,由CPU、中断控制器、中断信号输入三部分组成。硬件设计者在设计中断控制器时,已经将相应的硬件输入信号编号,分别对应图中的输入信号1、2、3、4、...、n。

         流程:中断 -> IDT中的interrupt[x] -> common_interrupt -> do_IRQ -> handle_IRQ_event -> 中断程序(开发者定义) -> ret_from_intr


         1.当1号输入信号产生时,会将电信号送入中断控制器。中断控制器先判断是否屏蔽了该中断,屏蔽了则不会处理该信号;否则中断控制器会设置该中断输入线对应的寄存器的标记位,并通过INTR向CPU发送中断请求。

         2.CPU接受到中断请求后,立即停止当前正在运行的进程。CPU通过INT信号线获得中断控制寄存器的状态、得到当前中断的中断号.

         3.控制单元根据中断号,从中断描述符表(基地址存放于idt中)中读出相应的中断入口地址,并跳转到该位置执行。该位置的代码形式如下,不同中断号对应其中不同的n:

                  

         4.common_interrupt,保存被中断进程的状态,并执行do_IRQ和ret_from_intr

              

      5.do_IRQ中的SAVE_ALL保存了被中断进程的状态,handle_IRQ_event调用了中断服务例程,ret_from_intr执行返回操作

        中断处理程序与其他内核函数的区别在于,中断处理程序是被内核调用来响应中断的,而它们运行于在我们称之为中断上下文的特殊上下文中,同时中断上下文也叫做原子上下文,在该上下文中执行的代码不可阻塞。 

中断结构:

        Linux中断被分为上半部和下半部。

        上半部:有外设产生的中断,主要是用来通知操作系统外设的变化。比如网卡收到数据包时,会产生一个中断。

        下半部:CPU收到中断通知后,用来处理耗费时间较长的工作。为了满足快速响应各类中断特点,对的中断处理越快越好。为了实现这个特点,硬中断处理短时间可以完成的工作,而软中断处理长时间才能完成的工作。

        为什么要分为上半部和下半部呢?

        中断对时限要求高,要求越快完成越好

        中断是主动上报的,它打断了CPU正在执行的代码。如果打断时间过长,CPU被占用而无法处理其他事件(其他活动),无法保证CPU在较短时间内对其他事件做出响应。因此中断过程必须尽可能的快,这样就要求中断任务体积小。而现实当中中断又有可能要做的工作很多。为了取得快速执行和大量工作之间的平衡,中断分为上半部和下半部。上半部主要用来响应中断、登记任务,下半部用来处理耗时工作并且推迟执行来实现。

         

下半部机制:

        软中断

        http://blog.csdn.net/linux_xiaomugua/article/details/7004063

        硬中断过程的模拟,模拟之处在于硬中断在硬件上查询中断号并映射到相应的中断服务程序;而软中断则是采用标记软中断状态位 ,等将来合适的机会在软中断向量表中查询处理程序来执行。过去一直认为软中断的过程,是硬件中断的过程,罪过!软中断

        工作队列

        内核当中有工作队列守护线程,工作会被注册到守护进程维护的队列中,当产生中断后,下半部可以将工作提交到守护进程,并调度守护进程。


        tasklet

        通过软中断来实现的,与软中断不同,它可以动态的增加或减少,而软中断只有32个。不同类型的tashlet不能并发执行,而软中断可以。

关键问题:

        中断的重入问题

        Linux中断上半部是可以嵌套的,但是没有优先级的概念。任何一个中断都可以打断另外一个正在执行的中断,但是同种中断不会打断中通中断的执行。但是并不是所有中断都可以被打断,如果中断申请时设置了标记为IRQF_DISABLED,那么中断时是不可以被打断的;否则中断可以被打断。

      在“中断电信号->handle_IRQ_event之前”,有与CPU自动屏蔽了中断,所以此时是不会产生嵌套的。而在handle_IRQ_evnet中可能会重新开启中断,也就是说在handler中是可以嵌套的。

      可以为什么中断不可重入呢? 即同种中断不可嵌套? 参考《为什么要将这个中断屏蔽掉》

        中断的睡眠问题

        中断上下文中不能睡眠,因为不能调度,否则内核会陷入僵死状态

       

        问题:下半部还是耗时的,怎么体现出实时性呢?  (下半部还是要很多时间处理呀)

        这个问题太二了,Linux本身就不是实时的系统,它是分时的,怎么变出来的实时呢!这里的实时是相对的,是指系统有较高的响应能力,对所有的中断都能快速响应,而不让CPU被其中某一个独占太久。实时系统的中断是有优先级的,更较高优先级的中断产生时,可以打断较低优先级的中断。也就是说实时系统中CPU往往是先运行优先级较高的中断。


参考资料:

 Linux中断实现浅析  A​R​M​中​断​程​序​的​原​理​和​实​现 Linux内核分析方法谈 中断处理源码情景分析《Linux内核设计与实现》

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值