LINUX 操作系统 第6章 中断和中断处理程序.ppt_第1页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第2页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第3页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第4页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第6章 中断和中断处理程序,2,6.1 中断、陷阱和异常,中断(interrupt):设备发出的中断,此类中断的发生是无法预测的,它是被动的。用户空间和系统空间都可能发生中断。 陷阱(trap):由软件产生的中断,它是由专设的指令,如X86的“int n”在程序中有意设置的,他是主动的。陷阱只发生在用户空间。 异常(exception):由于违规操作产生的,如除法操作DIV的除数为0。多半是不小心, 而不是故意的,也是被动的。 系统调用,通过int 0 x80实现,同“陷阱”。,3,中断、陷阱和异常,共同点:CPU对它们的响应过程基本一致。即:在执行完当前指令后,或者在执行当前指令的中途,就根

2、据中断源所提供的“中断向量”,在内存中找到相应的服务程序的入口地址,并调用该服务程序。 “中断”的向量是由软件或硬件设置好了的;陷阱的向量是在“自陷”指令中发出的(int n中的n);而各种异常的向量则是CPU的硬件结构中预先规定好的。 因此,在实践中常常将它们作为统一的模式加以考虑和实现,而且常常统称为“中断”。,4,中断,中断使硬件得以与处理器进行通信。 中断随时可能发生,因此内核随时可能因为新到来的中断而被打断。 不同的设备对应的中断不同,每个中断都通过一个唯一的数字标识,从而使得操作系统能够对中断进行区分。 这些中断值通常被称为中断请求(IRQ)线,通常IRQ都是一些数值量。,5,6.

3、2 中断处理程序,在响应一个特定中断的时候,内核会执行一个函数中断处理程序(或叫中断服务例程)。 一个设备的中断处理程序是它的设备驱动程序的一部分。 中断处理程序与其他内核函数的真正区别:中断处理程序是被内核调用来响应中断的,它们运行于中断上下文中。,6,中断随时可能发生,因此中断处理程序也就随时可能执行。所以必须保证中断处理程序能够快速执行,这样才能保证尽可能快地恢复中断代码的执行。 因此,尽管对硬件而言,迅速对其中断进行服务非常重要;但对系统的其它部分而言,让中断处理程序在尽可能短的时间内完成运行也同样重要。,7,上半部与下半部,对中断处理程序而言,既想它运行得快,又想它完成的工作量多,鉴

4、于这两个目的之间的矛盾,一般把中断处理分为两个部分: 上半部:中断处理程序,接收到一个中断,它就立即开始执行,但只做有严格时限的工作。这些工作都是在所有中断被禁止的情况下完成的。 下半部:能够被允许稍后执行的工作推迟到下半部执行。下半部在开中断的情况下执行。,8,上半部和下半部分开的例子,例:网卡接收数据包 应在上半部完成的工作:应答硬件,拷贝最新的网络数据包到内存,读取网卡上更多的数据包。 可以在下半部完成的工作:处理和操作数据包。,9,6.3 注册中断处理程序,中断处理程序是驱动程序的组成部分。 驱动程序通过以下函数注册并激活一个中断处理程序。,int request_irq (unsig

5、ned int irq, irqreturn_t (*handler) (int, void *, struct pt_regs *), unsigned long irqflags, const char *devname, void *dev_id),10,request_irq( )的参数,第1个参数irq:要分配的中断号。 第2个参数handler:一个指针,指向处理这个中断的实际中断处理程序。 第3个参数irqflags:可以为0,也可以是SA_INTERRUPT, SA_SAMPLE_ RANDOM, SA_SHIRQ其中的一个或多个标志的位掩码。 第4个参数devname:与中断

6、相关的设备的ASCII文本表示法。 第5个参数dev_id:主要用于共享中断线。,11,request_irq( )的返回值,若成功执行,返回0;如果返回非0值,表示有错误发生,在这种情况下,指定的中断处理程序不会被注册。,注意: request_irq( )函数可能会睡眠,因此,不能在中断上下文或其它不允许阻塞的代码中调用该函数。,12,使用request_irq( )函数,if (request_irq (irqn, my_interrupt, SA_SHIRQ, “my_device”, dev) ) printk(KERN_ERR “my_device: cannot register

7、 IRQ %d, n”, irqn); return EIO; ,13,释放中断处理程序,卸载驱动程序时,需要注销相应的中断处理程序,并释放中断线。 可以调用void free_irq (unsigned int irq, void *dev_id)来释放中断线。 如果指定的中断线不是共享的,那么,该函数删除处理程序的同时将禁用这条中断线。如果中断线是共享的,则仅删除dev_id所对应的处理程序,而这条中断线本身只有在删除了最后一个处理程序时才会被禁用。,14,6.4 编写中断处理程序,典型的中断处理程序声明:,static irqreturn_t intr_handler (int irq,

8、 void *dev_id, struct pt_regs *regs),其返回值为irqreturn_t型,实际上是int型。 中断处理程序可能返回两个特殊的值: IRQ_NONE:当中断处理程序检测到一个中断,但该中断对应的设备并不是在注册处理函数期间指定的产生源时,返回该值; IRQ_HANDLED:当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回该值。,15,在include/linux/interrupt.h中有如下几行,定义了中断处理程序的返回值:,typedef int irqreturn_t; #define IRQ_NONE(0) #define IRQ_H

9、ANDLED(1) #define IRQ_RETVAL(x)(x) != 0),16,典型中断处理程序的参数说明,irq:是这个处理程序要响应的中断的中断线号。现在,该参数已没有太大用处。 dev_id:一个通用指针,它与传递给request_irq( )的参数dev_id必须一致。如果该值有唯一确定性,那么它就相当于一个cookie,可以用来区分共享同一中断处理程序的多个设备。 regs:一个指向结构的指针,该结构包含处理中断之前处理器的寄存器和状态。除了调试,很少用到它。,17,中断处理程序和重入,当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止在同一中

10、断线上接收到另一个新的中断。因此,同一个中断处理程序绝对不会被同时调用以处理嵌套的中断。 所以,Linux的中断处理程序是无需重入的。这极大地简化了中断处理程序的编写。,18,6.4.1 共享的中断处理程序,共享的处理程序与非共享的处理程序在注册和运行方式上比较相似,但差异主要有三点: request_irq( )的参数irqflags必须设置SA_SHIRQ标志。 对每个注册的中断处理程序来说,dev_id参数必须唯一。指向任一设备结构的指针就可以满足这一要求。 中断处理程序必须能够区分它的设备是否真的产生了中断。,19,6.4.2 中断处理程序实例,例:来自RTC (real_time c

11、lock)驱动程序的一个实际的中断处理程序,它在drivers/char/rtc.c中定义。 在RTC驱动程序装载时,会调用rtc_init( )函数,进行初始化。 在rtc_init( )函数中,将注册中断处理程序,代码见下页:,20,其中的第2个参数是中断处理程序rtc_interrupt,其代码见下页。,if (request_irq(rtc_irq, rtc_interrupt, SA_INTERRUPT, rtc, (void *) ,21,中断处理程序rtc_interrupt( ),static unsigned long rtc_irq_data = 0; irqreturn_

12、t rtc_interrupt (int irq, void *dev_id, struct pt_regs *regs) spin_lock (,22,rtc_interrupt( ) (续),spin_unlock ( ,23,6.5 中断上下文,当执行一个中断处理程序或下半部时,内核处于中断上下文中。 中断上下文不能睡眠,因此不能从中断上下文中调用某些会睡眠的函数。,24,6.6 中断处理机制的实现,中断处理系统的实现依赖于体系结构。依赖于处理器、所使用的中断控制器的类型、体系结构的设计及机器本身。 中断从硬件到内核的路由见下页图。,25,中断从硬件到内核的路由,26,在内核中,中断的旅

13、程开始于预定义入口点,对于每条中断线,处理器都会跳到对应的一个唯一位置。这样,内核就可以知道所接收中断的IRQ号了。 然后,内核调用do_IRQ( )函数。,27,do_IRQ( )函数,通过orig_eax读出堆栈中的值,并将高位屏蔽掉,得到IRQ号。,unsigned int do_IRQ(struct pt_regs *regs) int irq = regs-orig_eax ,28,补充:pt_regs结构,struct pt_regs long ebx;long ecx; long edx;long esi; long edi;long ebp; long eax;int xds;

14、 int xes;long orig_eax; long eip;int xcs; long eflags;long esp; int xss; ;,29,do_IRQ( ) handle_IRQ_event( ),int handle_IRQ_event (unsigned int irq, struct pt_regs * regs, struct irqaction * action) int status= 1; int retval = 0; if (!(action-flags ,30,补充:irqaction数据结构,struct irqaction irqreturn_t (*

15、handler)(int, void *, struct pt_regs *); unsigned long flags; cpumask_t mask; const char *name; void *dev_id; struct irqaction *next; int irq; struct proc_dir_entry *dir; ;,31,/proc/interrupts,procfs是一个虚拟文件系统,它只存在于内核内存,一般安装于/proc目录下。 /proc/interrupts文件:存放系统中与中断相关的统计信息。见下页。,32,/proc/interrupts文件的内容,3

16、3,6.7 中断控制,Linux内核提供了一组接口用于操作机器上的中断状态。这些接口为我们提供了能够禁止当前处理器的中断系统、或屏蔽掉整个机器的一条中断线的能力。,34,6.7.1 禁止和激活中断,用于禁止当前处理器上的本地中断,随后又激活它们的语句为:,local_irq_disable( ) ; /*禁止中断*/ local_irq_enable( );,这两个函数通常以单个汇编指令实现,其代码在include/asm-i386/system.h中,见下页:,35,如果在调用local_irq_disable( )之前已经禁止了中断,那么该例程往往会带来潜在的危险。同样local_irq_

17、enable( )也存在潜在危险。 因此需要一种机制把中断恢复到以前的状态而不是简单地禁止或激活。,#define local_irq_disable( ) _asm_ _volatile_(cli: : :memory) #define local_irq_enable( ) _asm_ _volatile_(sti: : :memory),36,在禁止中断之前应该保存中断系统的状态;而在准备激活中断时,只需要把中断恢复到它们原来的状态。如下所示:,unsigned long flags; local_irq_save(flags); /*/ local_irq_restore(flags)

18、;,对local_irq_save( )的调用和对local_irq_restore( )的调用必须在同一个函数中进行。,37,6.7.2 禁止指定中断线,在某些情况下,只禁止整个系统中一条特定的中断线就够了。这就是所谓的屏蔽掉一条中断线。 Linux提供了四个接口: void disable_irq(unsigned int irq); void disable_irq_nosync(unsigned int irq); void enable_irq(unsigned int irq); void synchronize_irq(unsigned int irq);,38,6.7.3 中断系统的状态,宏irqs_disabled( ):如果本地处理器上的中断系统被禁止,则它返回非0,否则返回0。 宏in_interrupt( ):如果内核处于中断上下文中,返回非0。说明内核此时正在执行中断处理程序,或者正在执行下半部处理程序。 宏in_irq( ):只有在内核确实正在执行中断处理程序时才返回非0。,39,6.8 下半部简介,中断处理程序是内核中必不可少的,但本身存在一些局限: 它以异步方式执行并且有可能会打断其他重要代码

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论