精华内容
下载资源
问答
  • 中断时计算机科学最基本、也是十分重要的个概念,可以说没有中断概念的引入和应用就不会今天的计算机,至少不会搞效率的计算机。 、基本概念 二、BIOS中断服务 三、DOS中断服务 四、中断处理技术 五、...

     中断时计算机科学中最基本、也是十分重要的一个概念,可以说没有中断概念的引入和应用就不会有今天的计算机,至少不会有搞效率的计算机。

    • 一、基本概念
    • 二、BIOS中断服务
    • 三、DOS中断服务
    • 四、中断处理技术
    • 五、中断处理程序实例

    一、中断:
    定义:中断就是使CPU暂时挂起当前正在进行的工作并转向某紧急事件的服务与处理程序(该服务与处理程序称为中断服务程序),在执行完中断服务程序后再返回到被中止的原有工作处的过程。
    中断分类:中断按其产生的方式可分为硬件中断和软件中断。硬件中断又分为内部和外部两种。


    二、内部硬件中断

    一个字节即一共256个中断,00H~FFH。
    定义:内部硬件中断是由某些特殊的指令触发的,例如单步中断、除法出错中断。通常我们所说的硬件中断即指内部硬件中断。
    硬件中断举例:在使用DEBUG调试程序时我们经常使用T命令和P命令,而T命令和P命令的执行恰好正是利用了内部硬件中断。

    • (1)INT 00H:除法错误中断。
    • (2)INT 01H:单步中断,由T命令产生。
      • 它的特征是将陷阱标志位TF置位,这样当程序运行时,会在每一条指令的后面产生一个单步中断,从而中止指令的继续执行。
    • (3)INT 03H:断点中断,由P命令产生。
      • 与INT 01H类似,但不会跟踪进子程序、中断调用等。
    • (4)INT 04H:溢出中断。
      • 在指令序列中,若上一个指令由于某些特殊原因使溢出标志OF置1,那么当执行溢出中断指令INTO是立即产生中断04H;若OF为0,则INTO不起作用。

    三、外部硬件中断

    定义:外部硬件中断是指从处理器外部的硬件设备中产生并发向处理器的中断。
    分类:分为可屏蔽中断不可屏蔽中断两种。分别由INTR引脚NMI引脚的信号来触发。即有2条外部中断请求线。

    1、可屏蔽中断–INTR
     可以通过设置中断控制器的屏蔽参数来禁止某些指定的中断。
     可屏蔽中断还可以通过指令CLI(关中断)来禁止CPU响应所有的外部中断。
    2、不可屏蔽中断–NMI
     是用来处理一些紧急情况的,如机器掉电等。它不能由用户通过编制软件来屏蔽,一旦CPU接收到NMI引脚上的信号时就必须立即响应,转向NMI的服务程序,硬件将自动完成断点保护及现场保护,且在中断返回时执行一条RETN指令。


    四、软中断

    定义:严格说来,软件中断是内部中断的一种,是由软件引起的非屏蔽型中断。

    1、INT n 指令
     CPU执行INT n指令时,立即产生一个软件中断,中断的类型由指令中的n指明。
    应用:因为指令中可以指定任何的类型号,故此指令可以方便地用来调试为外设编好的中断服务程序。
    2、中断向量表
     中断过程中很关键的一步是要由中断处理程序对因各种原因触发的相应中断进行处理。因此每一个中断都要对应的有一个中断处理程序。对这些中断进行管理的就是中断向量表了。
    (1)中断向量表结构
    中断向量表的长度为1K字节(1024字节),共有256项,每一项4个字节,对应一个中断。也就是说一张表中断最多可对应256个中断(当然,实际上并没有这么多中断,这就为用户自己编制并扩充中断服务程序提供了便利的条件)
     中断向量表在内存中靠前的部分并固定在这个段地址为00H,偏移量为00H~3FFH,即00000H—003FFH的位置。
    中断向量表每项的四个字节存放着该项对应中断的中断处理程序的入口地址。四个字节也就是两个字,高字存放中断处理程序入口地址的段CS,低字存放偏移IP。
    (2)中断服务程序的调用
     中断指令INT n 发出以后,就要到向量表中去找其对应的服务程序的地址。
    n* 4所得到的就是中断INT n 所对应的n号中断的四个字节地址在向量表中的首地址。
     由首地址开始的四个连续字节即两个字中顺序存放着其对应中断服务程序的入口地址的偏移和段地址,然后程序跳到此入口地址,并将控制交给中断服务程序。
    (3)中断向量表的优点

    • 1)便于管理和扩充,就像通过仓库存货单可以找到任何一件存储的物品那样,我们可以通过向量表来找到每一个中断对应的中断服务程序。
    • 2)当用户想要编制和使用自己的中断服务程序时,可以先设置中断向量,以确定该中断在中断向量表中的位置,然后将自己编制的中断服务程序(可以是驻留内存的,也可以是非驻留内存的)的地址返回给它在中断向量表中对应位置的两个字中,至此,用户就可以十分方便地为自己建立一个软中断了。

    例一:保存5号中断入口,然后重置5号中断的入口

    PUSH ES
    MOV AX,3505H  ;取中断向量
    INT 21H
    MOV [OLD_IP],BX ;保存旧的偏移地址
    MOV [OLD_ES],ES ;保存旧的段地址
    POP ES 
    MOV AX,2505H ;重置中断向量
    MOV DX,OFFSET INT05H
    INT 21H

    3、中断类型号的提供
    (1)INT 00H ~ 05H自动提供

    • INT 00H — 除法错误
    • INT 01H — 单步错误
    • INT 02H — 非屏蔽中断NMI
    • INT 03H — 断点中断
    • INT 04H — 溢出中断
    • INT 05H — 屏幕打印(拷屏)中断

    4、软中断的处理过程
     软中断被响应后,CPU进入中断响应周期。CPU将中断类型号乘以4,得到中断向量表的入口地址,并执行一下动作:

    • (1)将标志寄存器压入堆栈。
    • (2)用清中断标志(IF)和单步标志(TF)禁止硬件中断,即关中断。
      • 所以当我们自己编制中断服务程序时,在程序内必要时可以开中断,即打开由硬件自动关闭的中断允许触发器,使之能够响应更高级的中断。
    • (3)将当前代码段寄存器的内容(CS)压栈。
    • (4)将当前指令指针(IP)压栈。
      • 步骤(3)、(4)的目的是要确保中断处理完毕之后能够正确地返回中断调用者。
    • (5)转向中断服务程序入口并将控制交给中断服务程序。

     在中断服务程序执行完后,即CPU接收到IRET指令时,它又将产生以下步骤:

    • (1)弹出IP:从堆栈中将保存的指令指针IP由堆栈弹出到IP中。
    • (2)弹出CS:将保存的段寄存器内容由堆栈弹出到代码段寄存器中。
    • (3)恢复标志寄存器

    5、中断服务程序的编写
     中断服务程序可以按各个设备的要求来加以编制,但一般有:

    • (1)保护现场(入栈)
    • (2)恢复现场(出栈)
    • (3)中断返回(IRET)
      说明:软中断指令非常类似子程序调用的CALL指令(即中断的INT 21H指令),但两者之间还是有明显区别的:
    • (1)软中断全部都是段间的调用,所以在结束时用IRET返回;
    • (2)软中断的IRET指令具有自动恢复断点和标志的功能。

    6、软中断的分类
     一般情况下,目前使用的软中断可分为三大类:

    • (1)BIOS中断 — 10H ~ 1FH(16个)
      • 它主要是提供I/O驱动程序使用,提供了应用程序、DOS与设备的接口功能。用户可以忽略对具体设备硬件上的了解,直接应用这些功能调用完成对具体设备的控制。
    • (2)DOS中断 — 20H ~ 3FH(32个)
      • 目前使用了其中的20H ~ 27H和2FH,其余的为保留中断。
    • (3)自由中断 — 40H ~ FFH(192个)
      • 这类中断是由系统或应用程序设置开发的。可以理解为这类中断是系统或应用程序为了完成特定的功能而扩展出来的中断。可以看得出来,系统给自身和应用程序留下了相当大的余地。这类中断是不定。

    7、软中断的访问
     软中断的访问在不同的环境中有不同的形式,在这里我们仅仅就汇编语言对软中断的访问讨论一下。用汇编语言申请一个标准DOS或BIOS中断是非常简单的,用户程序通过规定的寄存器与中断服务程序之间进行内定的规范的信息交换。大部分的中断处理程序都有一个入口和一个出口,在入口处用寄存器传入规定的数据,在中断请求完毕之后再通过特定的寄存器传递出返回值。

    MOV DL,'A'
    MOV AH,02H
    INT 21H  ;显示一个字符
    展开全文
  • linux 中断中断处理程序

    千次阅读 2013-07-26 13:59:20
    在linux中中断的使用是无时不在,下面就自己的学习心得和大家分享 一下!

    在linux中中断的使用是无时不在,下面就自己的学习心得和大家分享 一下!

                  那么什么叫中断呢, 中断还是打断,这样一说你就不明白了。唉,中断还真是有点像打断。我们知道linux管理所有的硬件设备,要做的第一件事先是通信。然后,我们天天在说一句话:处理器的速度跟外围硬件设备的速度往往不在一个数量级上,甚至几个数量级的差别,这时咋办,你总不能让处理器在那里傻等着你硬件做好了告诉我一声吧。这很容易就和日常生活联系起来了,这样效率太低,不如我处理器做别的事情,你硬件设备准备好了,告诉我一声就得了。这个告诉,咱们说的轻松,做起来还是挺费劲啊!怎么着,简单一点,轮训(polling)可能就是一种解决方法,缺点是操作系统要做太多的无用功,在那里傻傻的做着不重要而要重复的工作,这种方法一般我们是不采用的,这里有更好的办法---中断,这个中断不要紧,关键在于从硬件设备的角度上看,系统已经实现了从被动为主动的历史性突破。

           中断的例子一般是按键就是一个很好的例子,这个很显然啊。分析中断,本质上是一种特殊的电信号,由硬件设备发向处理器,处理器接收到中断后,会马上向操作系统反应此信号的带来,然后就由OS负责处理这些新到来的数据,中断可以随时发生,才不用操心与处理器的时间同步问题。不同的设备对应的中断不同,他们之间的不同从操作系统级来看,差别就在于一个数字标识-----中断号。专业一点就叫中断请求(IRQ)线,通常IRQ都是一些数值量。有些体系结构上,中断好是固定的,有的是动态分配的,这不是问题所在,问题在于特定的中断总是与特定的设备相关联,并且内核要知道这些信息,这才是最关键的。

           用书上一句话说:讨论中断就不得不提及异常,异常和中断不一样,它在产生时必须要考虑与处理器的时钟同步,实际上,异常也常常称为同步中断,在处理器执行到由于编程失误而导致的错误指令的时候,或者是在执行期间出现特殊情况,必须要靠内核来处理的时候,处理器就会产生一个异常。因为许多处理器体系结构处理异常以及处理中断的方式类似,因此,内核对它们的处理也很类似。这里的讨论,大部分都是适合异常,这时可以看成是处理器本身产生的中断。

           中断产生告诉中断控制器,继续告诉操作系统内核,内核总是要处理的,是不?这里内核会执行一个叫做中断处理程序或中断处理例程的函数。这里特别要说明,中断处理程序是和特定中断相关联的,而不是和设备相关联,如果一个设备可以产生很多中断,这时该设备的驱动程序也就需要准备多个这样的函数。一个中断处理程序是设备驱动程序的一部分,这个我们在linux设备驱动中已经说过,就不说了,后面我也会提到一些。前边说过一个问题:中断是可能随时发生的,因此必须要保证中断处理程序也能随时执行,中断处理程序也要尽可能的快速执行,只有这样才能保证尽可能快地恢复中断代码的执行。

           但是,不想说但是,我们的中断说不定还真有奇迹发生。这个奇迹就是将中断处理切为两个部分或两半。中断处理程序上半部(top half)---接收到一个中断,它就立即开始开始执行,但只做严格时限的工作,这些工作都是在所有中断被禁止的情况下完成的。同时,能够被允许稍后完成的工作推迟到下半部(bottom half)去,此后,下半部会被执行,通常情况下,下半部都会在中断处理程序返回时立即执行。我会在后面谈论linux所提供的是实现下半部的各种机制。

           说了那么多,现在开始第一个问题:如何注册一个中断处理程序。我们在linux驱动程序理论里讲过,通过一下函数可注册一个中断处理程序:

    中断的注册函数:

    1
    int request_irq(unsigned int irq,irqreturn_t (*handler)( int , void *, struct pt_regs *),unsigned long irqflags, const char * devname, void *dev_id)

           有关这个中断的一些参数说明,说明如下:

           第一个参数:irq 表示要分配的中断号。这个值分为3种情况,1是已经分配好的,也就是说系统已经定下来的终端号,2:对于大多数的设备这个值是通过探测获取的。

                             3:同时也是可以动态分配。

          第二个参数:handler是一个指针,指向处理这个中断的实际处理程序,只要操作系统接受到这个中断,这个中断的处理程序会立即执行,温馨提示:handler的函数原型是固定的-----它接受三个参数,并有一个irqreturn_t的返回值。

          第三个参数:irqflags可以是0,或是下列一个或是多个标志的位掩码。

                            1:SA_INTERRUPT:

                             如果设置是这个标志,表示这个中断是快速的中断处理程序,通常中断的机制分为快速和慢速两种机制,在这里如果是设置为快速的话,表示在本地的处理器上,快速的中断处理程序是在禁止所用的中断情况下,运行的。这会使的快速中断在不被其他中断的干扰下,得以快速的执行。一般在默认的情况下,这个标志位是不设置的,那就是另一种的状态:除了正在运行的中断处理程序的对应的那个中断线是被屏蔽外,其他的中断都是激活的状态。

                            在系统里的实例,一般只有时钟中断是被设置为,快速中断的方式。绝大多数的中断是不设置这个标志位的。

                           2:SA_SAMPLE_RANDOM :此标志表示是这个设备产生的中断是对内核嫡池(后续慢慢研究)。

                           3:SA_SHIRQ:此标志表示是多个中断处理程序之间可以共享中断线。也就是说在同一个给定的线上,注册的每一个中断处理程序都是需要这个标准位。

                                否则,每一个线上只能有一个中断处理程序。

              第四个参数: devname是与中断相关的设备名的ASCII的文本的表示方法,例如 ,按键的设备名一般是“keyboard”这个名字会在/proc/irq和/proc/interrupt文件里面注册,以便后续应用的出现访问这个设备文件进行通信。

              第五个参数:dev_id 主要是用于共享的数据线,当一个中断处理出现需要释放时,dev_id将会提供唯一的标志信息。以便从共享中断线中删除指定的那一个中断处理程序。如果没有这个参数,那么内核根本不知道在给定的共享中断线上到底要删除哪一个中断的处理程序。

                                如果不是共享的中断,那么这个值是可以设置为NULL。

                request_irq函数成功会返回0,如果失败则是-EBUSY(表示申请的中断被使用)。

               温馨提示:request_irq这个函数是可能会睡眠的,所以说是不允许在中断的上下文或是不允许阻塞的代码中调用这个函数。照成这个函数休眠原因是:

                                  在注册的过程中,内核需要在/proc/irq文件里面创建dev_name,函数proc_mkdir()  就是用来创建这个新的procfs项,proc_makedir()通过调用proc_creat()对这个新的procfs进行设置,而proc_creat()函数会调用kmalloc()函数来请求分配内存,问题来了,kmalloc()函数是可以休眠的。所以request_irq 是会跑到kmalloc里面休眠哦

     

       中断的释放函数:

    1
    void free_irq(unsigned int irq, void *dev_id)

           这里需要说明的就是要必须要从进程上下文调用free_irq().好了,现在给出一个例子来说明这个过程,首先声明一个中断处理程序:

             如果指定的中断线不是共享的中断,那么该函数在删除处理程序的同时将禁用这条中断线,如果是指定的共享的中断,则仅仅是删除dev_id所对应的处理程序。而这条中断线本身是只有在删除最后一个处理程序时,才会被禁用。

    编写中断处理程序:

    1
    static irqreturn_t intr_handler( int irq, void *dev_id, struct pt_regs *regs)

           注意:这里的类型和前边说到的request_irq()所要求的参数类型是匹配的,参数不说了。对于返回值,中断处理程序的返回值是一个特殊类型,irqrequest_t,可能返回两个特殊的值:IRQ_NONE和IRQ_HANDLED.当中断处理程序检测到一个中断时,但该中断对应的设备并不是在注册处理函数期间指定的产生源时,返回IRQ_NONE;当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回IRQ_HANDLED.C此外,也可以使用宏IRQ_RETVAL(x),如果x非0值,那么该宏返回IRQ_HANDLED,否则,返回IRQ_NONE.利用这个特殊的值,内核可以知道设备发出的是否是一种虚假的(未请求)中断。如果给定中断线上所有中断处理程序返回的都是IRQ_NONE,那么,内核就可以检测到出了问题。最后,需要说明的就是那个static了,中断处理程序通常会标记为static,因为它从来不会被别的文件中的代码直接调用。另外,中断处理程序是无需重入的,当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止在同一个中断上接收另外一个新的中断。通常情况下,所有其他的中断都是打开的,所以这些不同中断线上的其他中断都能被处理,但当前中断总是被禁止的。由此可见,同一个中断处理程序绝对不会被同时调用以处理嵌套的中断。      

           下面要说到的一个问题是和共享的中断处理程序相关的。共享和非共享在注册和运行方式上比较相似的。差异主要有以下几点:

    1.request_irq()的参数flags必须设置为SA_SHIRQ标志。
    2.对每个注册的中断处理来说,dev_id参数必须唯一。指向任一设备结构的指针就可以满足这一要求。通常会选择设备结构,因为它是唯一的,而且中
       断处理程序可能会用到它,不能给共享的处理程序传递NULL值。
    3.中断处理程序必须能够区分它的设备是否真的产生了中断。这既需要硬件的支持,也需要处理程序有相关的处理逻辑。如果硬件不支持这一功能,那中
       断处理程序肯定会束手无策,它根本没法知道到底是否与它对应的设备发生了中断,还是共享这条中断线的其他设备发出了中断。

    指定SA_SHIRQ标志以调用request_irq()时,只有在以下两种情况下才能成功:中断当前未被注册或者在该线上的所有已注册处理程序都指定了SA_SHIRQ.A。注意,在这一点上2.6与以前的内核是不同的,共享的处理程序可以混用SA_INTERRUPT.  一旦内核接收到一个中断后,它将依次调用在该中断线上注册的每一个处理程序。因此一个处理程序必须知道它是否应该为这个中断负责。如果与它相关的设备并没有产生中断,那么中断处理程序应该立即退出,这需要硬件设备提供状态寄存器(或类似机制),以便中断处理程序进行检查。毫无疑问,大多数设备都提这种功能。

    中断处理程序的实例:      

              可以参考drivers/char/rtc.c的代码。

    中断上下文和中断处理机制:

           当执行一个中断处理程序或下半部时,内核处于中断上下文(interrupt context)中。对比进程上下文,进程上下文是一种内核所处的操作模式,此时内核代表进程执行,可以通过current宏关联当前进程。此外,因为进程是进程上下文的形式连接到内核中,因此,在进程上下文可以随时休眠,也可以调度程序。但中断上下文却完全不是这样,它可以休眠,因为我们不能从中断上下文中调用函数。如果一个函数睡眠,就不能在中断处理程序中使用它,这也是对什么样的函数能在中断处理程序中使用的限制。还需要说明一点的是,中断处理程序没有自己的栈,相反,它共享被中断进程的内核栈,如果没有正在运行的进程,它就使用idle进程的栈。因为中断程序共享别人的堆栈,所以它们在栈中获取空间时必须非常节省。内核栈在32位体系结构上是8KB,在64位体系结构上是16KB.执行的进程上下文和产生的所有中断都共享内核栈。
           下面给出中断从硬件到内核的路由过程(截图选自liuux内核分析与设计p61),然后做出总结:

            中断处理路由

                                              图一       中断从硬件到内核的路由

           上面的图内部说明已经很明确了,我这里就不在详谈。在内核中,中断的旅程开始于预定义入口点,这类似于系统调用。对于每条中断线,处理器都会跳到对应的一个唯一的位置。这样,内核就可以知道所接收中断的IRQ号了。初始入口点只是在栈中保存这个号,并存放当前寄存器的值(这些值属于被中断的任务);然后,内核调用函数do_IRQ().从这里开始,大多数中断处理代码是用C写的。do_IRQ()的声明如下:

    1
    unsigned int do_IRQ( struct pt_regs regs)

           因为C的调用惯例是要把函数参数放在栈的顶部,因此pt_regs结构包含原始寄存器的值,这些值是以前在汇编入口例程中保存在栈上的。中断的值也会得以保存,所以,do_IRQ()可以将它提取出来,X86的代码为:

    1
    int irq = regs.orig_eax & 0xff

           计算出中断号后,do_IRQ()对所接收的中断进行应答,禁止这条线上的中断传递。在普通的PC机器上,这些操作是由mask_and_ack_8259A()来完成的,该函数由do_IRQ()调用。接下来,do_IRQ()需要确保在这条中断线上有一个有效的处理程序,而且这个程序已经启动但是当前没有执行。如果这样的话, do_IRQ()就调用handle_IRQ_event()来运行为这条中断线所安装的中断处理程序,有关处理例子,可以参考linux内核设计分析一书,我这里就不细讲了。在handle_IRQ_event()中,首先是打开处理器中断,因为前面已经说过处理器上所有中断这时是禁止中断(因为我们说过指定SA_INTERRUPT)。接下来,每个潜在的处理程序在循环中依次执行。如果这条线不是共享的,第一次执行后就退出循环,否则,所有的处理程序都要被执行。之后,如果在注册期间指定了SA_SAMPLE_RANDOM标志,则还要调用函数add_interrupt_randomness(),这个函数使用中断间隔时间为随机数产生熵。最后,再将中断禁止(do_IRQ()期望中断一直是禁止的),函数返回。该函数做清理工作并返回到初始入口点,然后再从这个入口点跳到函数ret_from_intr().该函数类似初始入口代码,以汇编编写,它会检查重新调度是否正在挂起,如果重新调度正在挂起,而且内核正在返回用户空间(也就是说,中断了用户进程),那么schedule()被调用。如果内核正在返回内核空间(也就是中断了内核本身),只有在preempt_count为0时,schedule()才会被调用(否则,抢占内核是不安全的)。在schedule()返回之前,或者如果没有挂起的工作,那么,原来的寄存器被恢复,内核恢复到曾经中断的点。在x86上,初始化的汇编例程位于arch/i386/kernel/entry.S,C方法位于arch/i386/kernel/irq.c其它支持的结构类似。

           下边给出PC机上位于/proc/interrupts文件的输出结果,这个文件存放的是系统中与中断相关的统计信息,这里就解释一下这个表:

            interruptinfo

           上面是这个文件的输入,第一列是中断线(中断号),第二列是一个接收中断数目的计数器,第三列是处理这个中断的中断控制器,最后一列是与这个中断有关的设备名字,这个名字是通过参数devname提供给函数request_irq()的。最后,如果中断是共享的,则这条中断线上注册的所有设备都会列出来,如4号中断。

            Linux内核给我们提供了一组接口能够让我们控制机器上的中断状态,这些接口可以在<asm/system.h>和<asm/irq.h>中找到。一般来说,控制中断系统的原因在于需要提供同步,通过禁止中断,可以确保某个中断处理程序不会抢占当前的代码。此外,禁止中断还可以禁止内核抢占。然而,不管是禁止中断还是禁止内核抢占,都没有提供任何保护机制来防止来自其他处理器的并发访问。Linux支持多处理器,因此,内核代码一般都需要获取某种锁,防止来自其他处理器对共享数据的并发访问,获取这些锁的同时也伴随着禁止本地中断。锁提供保护机制,防止来自其他处理器的并发访问,而禁止中断提供保护机制,则是防止来自其他中断处理程序的并发访问。

           在linux设备驱动理论帖里详细介绍过linux的中断操作接口,这里就大致过一下,禁止/使能本地中断(仅仅是当前处理器)用:

    1
    2
    local_irq_disable();
    local_irq_enable();

           如果在调用local_irq_disable()之前已经禁止了中断,那么该函数往往会带来潜在的危险,同样的local_irq_enable()也存在潜在的危险,因为它将无条件的激活中断,尽管中断可能在开始时就是关闭的。所以我们需要一种机制把中断恢复到以前的状态而不是简单地禁止或激活,内核普遍关心这点,是因为内核中一个给定的代码路径可以在中断激活饿情况下达到,也可以在中断禁止的情况下达到,这取决于具体的调用链。面对这种情况,在禁止中断之前保存中断系统的状态会更加安全一些。相反,在准备激活中断时,只需把中断恢复到它们原来的状态:

    1
    2
    3
    unsigned long flags;
    local_irq_save(flags);
    local_irq_restore(flags);

           参数包含具体体系结构的数据,也就是包含中断系统的状态。至少有一种体系结构把栈信息与值相结合(SPARC),因此flags不能传递给另一个函数(换句话说,它必须驻留在同一个栈帧中),基于这个原因,对local_irq_save()的调用和local_irq_restore()的调用必须在同一个函数中进行。前面的所有的函数既可以在中断中调用,也可以在进程上下文使用。

           前面我提到过禁止整个CPU上所有中断的函数。但有时候,好奇的我就想,我干么没要禁止掉所有的中断,有时,我只需要禁止系统中一条特定的中断就可以了(屏蔽掉一条中断线),这就有了我下面给出的接口:

    1
    2
    3
    4
    void disable_irq(unsigned int irq);
    void disable_irq_nosync(unsigned int irq);
    void enable_irq(unsigned int irq);
    void synchronise_irq(unsigned int irq);
     
    前两个函数是禁止中断控制器上指定的中断线,即禁止给定的中断向系统中所有处理器传递。另外,函数只有在当前执行的所有处理程序完成后,disable_irq()才能返回。所以调用者不仅要确保不在指定线上传递新的中断,同时还要确保已经开始执行的处理程序已经全部退出。
    函数2是不会等待当前中断处理程序执行完毕。
     函数4是等待一个特定的中断处理程序的退出,如果该处理程序正在执行,那么该函数必须退出后才可以返回。
        对以上函数的调用是可以嵌套调用的,但是要记住一点是在一条指定的中断线上,对1和2函数的调用,都需要相应的调用一次3,只有对3完成最后一次的调用后才可以激活新的中断线。
     
    中断系统的状态:

     另外,禁止多个中断处理程序共享的中断线是不合适的。禁止中断线也就禁止了这条线上所有设备的中断传递,因此,用于新设备的驱动程序应该倾向于不使用这些接口。

    另外,我们也可以通过宏定义在<asm/system.h>中的宏irqs_disable()来获取中断的状态,如果中断系统被禁止,则它返回非0,否则,返回0;

    用定义在<asm/hardirq.h>中的两个宏in_interrupt()和in_irq()来检查内核的当前上下文的接口

    。由于代码有时要做一些像睡眠这样只能从进程上下文做的事,这时这两个函数的价值就体现出来了。

           最后,作为对这篇博客的总结,这里给出我前边提到的用于控制中断的方法列表:

          interruptslist

     这里分析的是linux中断机制的上半部分的机制。。。。。。

    展开全文
  • I/O方式 —— 程序中断方式

    千次阅读 多人点赞 2019-09-01 12:06:01
    中断向量:中断服务程序寻址 执行中断服务程序 步骤中断请求 (1)中断请求分类 程序中断方式属于I/O 中断,因此属于外中断。 硬件中断:通过外部的硬件产生的中断。硬件中断属于外中断。 软件中断:...

    一、基本概念


    需要CPU中断自己的任务,转而执行I/O设备与存储器之间的数据传送。

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

    二、工作流程


    1. 中断请求:中断源向CPU发送中断请求信号。
    2. 中断判优:多个中断源同时提出请求时,通过中断判优逻辑响应一个中断源。
    3. 中断响应及中断隐指令。
    4. 中断服务程序寻址
    5. 执行中断服务程序
      在这里插入图片描述

    步骤一:中断请求

    (1)中断请求分类

    • 程序中断方式属于I/O 中断,因此属于外中断。

    • 硬件中断:通过外部的硬件产生的中断。硬件中断属于外中断。

    • 软件中断:通过某条指令产生的中断,这种中断是可以变成实现的,软件中断属于内中断。
      在这里插入图片描述

    (2)中断请求标记

    • 每个中断源向CPU发出中断请求的时间是随机的。
    • 为了记录中断事件并区分不同的中断源,中断系统需对每个中断源设置中断请求标记触发器INTR,当其状态为“1”时,表示中断源有请求。以方便CPU知道是哪个硬件发起中断请求
    • 这些触发器可组成中断请求标记寄存器,该寄存器可集中在CPU中,也可分散在各个中断源中。

    在这里插入图片描述

    步骤二:中断判优

    中断判优既可以用硬件实现,也可用软件实现

    一般来说,

    1. 硬件故障中断属于最高级,其次是软件中断;
    2. 非屏蔽中断优于可屏蔽中断;
    3. DMA请求优于I/0设备传送的中断请求;
    4. 高速设备优于低速设备;
    5. 输入设备优于输出设备;
    6. 实时设备优于普通设备。

    (1)硬件实现

    硬件实现是通过硬件排队器实现的,它既可以设置在CPU中,也可以分散在各个中断源中
    在这里插入图片描述

    (2)软件实现

    软件实现是通过查询程序实现的。

    在这里插入图片描述

    步骤三:中断响应(中断隐指令)

    CPU响应中断必须满足以下3个条件:

    1. 中断源有中断请求。
    2. CPU允许中断即开中断。
    3. 一条指令执行完毕,且没有更紧迫的任务。

    (1)外中断

    CPU是在统一的时刻,即每条 指令执行阶段结束前 向接口发出 中断查询信号,以获取 I/O 的中断请求,而在每条 指令执行阶段结束时 向接口发出 CPU中断响应

    (2)内中断

    内中断的发生跟指令的执行有关,因此可以在任意时间段响应内中断。

    (3)工作流程

    1. 关中断。在中断服务程序中,为了保护中断现场(即CPU主要寄存器中的内容)期间不被新的中断所打断,必须关中断,从而保证被中断的程序在中断服务程序执行完毕之后能接着正确地执行下去。
    2. 保存断点。为了保证在中断服务程序执行完毕后能正确地返回到原来的程序,必须将原来程序的断点(即程序计数器(PC)的内容)保存起来。可以存入堆栈,也可以存入指定单元。
    3. 引出中断服务程序。引出中断服务程序的实质就是取出中断服务程序的入口地址并传送给程序计数器(PC)。

    在这里插入图片描述

    步骤四:中断服务程序寻址

    不同的设备有不同的中断服务程序,每个中断服务程序都有一个入口地址,CPU必须找到这个入口地址,即中断向量。
    在这里插入图片描述

    【注1】中断向量是中断服务程序的入口地址,中断向量地址是指中断服务程序的入口地址的地址

    【注2】为什么不直接给出中断向量(入口地址),而是给出中断向量地址,再由中断向量地址找到中断向量?

    answer:中断向量地址可以保持不变,而中断向量可以灵活变动,不受硬件限制。

    步骤五:执行中断服务程序

    在执行中断服务程序的过程中,对于单重中断和多重中断有不同的处理方法

    • 单重中断:执行中断服务程序时不响应新的中断请求。

    • 多重中断:又称中断嵌套,执行中断服务程序时可响应新的中断请求。需要用到中断屏蔽技术

    在这里插入图片描述
    中断屏蔽技术主要用于多重中断,CPU要具备多重中断的功能,须满足下列条件。

    1. 在中断服务程序中提前设置开中断指令。
    2. 优先级别高的中断源有权中断优先级别低的中断源。

    每个中断源都有一个屏蔽触发器,所有屏蔽触发器组合在一起,便构成一个屏蔽字寄存器,屏蔽字寄存器的内容称为屏蔽字。屏蔽字设置有以下规则:

    1. 一般用‘1’表示屏蔽,0’表示正常申请。
    2. 每个中断源对应一个屏蔽字(在处理该中断源的中断服务程序时,屏蔽寄存器中的内容为该中断源对应的屏蔽字)。
    3. 屏蔽字中1’越多,优先级越高。每个屏蔽字中至少有一个’1(至少要能屏蔽自身的中断)。

    在这里插入图片描述

    三、程序中断和调用子程序的区别


    两者的根本区别主要表现在服务时间和服务对象上不一样

    1. 调用子程序过程的时间是已知的;程序中断的时间是随机的
    2. 子程序为主程序服务,两者之间是从属关系;程序中断与主程序没有联系,属于平行关系
    3. 主程序调用子程序的过程完全属于软件处理过程;中断处理程序需要软硬件的结合
    4. 子程序的嵌套由堆栈大小限制,中断嵌套由中断处理优先级(对应中断屏蔽字)限制
    展开全文
  • linux内核分析--中断中断处理程序

    千次阅读 2014-04-12 12:00:05
    在前面的这篇文章linux内核分析--中断的分类

    写在前面:

          在前面的这篇文章linux内核分析--中断的分类讲解了关于中断的基本概念,从宏观的角度了解了中断的基本知识。从这篇文章中要明白几点知识

          1、中断是由硬件产生的异步中断,而异常则是处理器产生的同步中断

          2、中断质上是一种特殊的电信号,由硬件设备发向处理器,处理器接收到中断后,会马上向操作系统反应此信号的带来,然后就由OS负责处理这些新到来的数据,中断可以随时发生,才不用操心与处理器的时间同步问题。不同的设备对应的中断不同,他们之间的不同从操作系统级来看,差别就在于一个数字标识-----中断号。专业一点就叫中断请求(IRQ)线,通常IRQ都是一些数值量。有些体系结构上,中断好是固定的,有的是动态分配的,这不是问题所在,问题在于特定的中断总是与特定的设备相关联,并且内核要知道这些信息,这才是最关键的,

         3、中断产生告诉中断控制器,继续告诉操作系统内核,内核总是要处理的,是不?这里内核会执行一个叫做中断处理程序或中断处理例程的函数。这里特别要说明,中断处理程序是和特定中断相关联的,而不是和设备相关联,如果一个设备可以产生很多中断,这时该设备的驱动程序也就需要准备多个这样的函数。一个中断处理程序是设备驱动程序的一部分,在接下来的文章中会介绍关于如何注册中断。前边说过一个问题:中断是可能随时发生的,因此必须要保证中断处理程序也能随时执行,中断处理程序也要尽可能的快速执行,只有这样才能保证尽可能快地恢复中断代码的执行。

         4、为了达到第三步的条件,尽可能让中断处理程序快速执行结束。将中断处理切为两个部分或两半。中断处理程序上半部(top half)---接收到一个中断,它就立即开始开始执行,但只做严格时限的工作,这些工作都是在所有中断被禁止的情况下完成的。同时,能够被允许稍后完成的工作推迟到下半部(bottom half)去,此后,下半部会被执行,通常情况下,下半部都会在中断处理程序返回时立即执行。linux内核分析--为什么把中断分为上半部和下半步这篇文章讲解了其中的原因

    下面进入今天的正题:

    一、注册中断处理程序

    如何注册一个中断处理程序。通过一下函数可注册一个中断处理程序:

    int request_irq(unsigned int irq,irqreturn_t (*handler)(int, void *,struct pt_regs *),unsigned long irqflags,const char * devname,void *dev_id)

    有关这个中断的一些参数说明,我就不说了,一旦注册了一个中断处理程序,就肯定会有释放中断处理,这是调用下列函数

    void free_irq(unsigned int irq, void *dev_id)

    这里需要说明的就是要必须要从进程上下文调用free_irq().好了,现在给出一个例子来说明这个过程,首先声明一个中断处理程序:

    static irqreturn_t intr_handler(int irq, void *dev_id, struct pt_regs *regs)

    注意:这里的类型和前边说到的request_irq()所要求的参数类型是匹配的,参数不说了。对于返回值,中断处理程序的返回值是一个特殊类型,irqrequest_t,可能返回两个特殊的值:IRQ_NONE和IRQ_HANDLED.当中断处理程序检测到一个中断时,但该中断对应的设备并不是在注册处理函数期间指定的产生源时,返回IRQ_NONE;当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回IRQ_HANDLED.C此外,也可以使用宏IRQ_RETVAL(x),如果x非0值,那么该宏返回IRQ_HANDLED,否则,返回IRQ_NONE.利用这个特殊的值,内核可以知道设备发出的是否是一种虚假的(未请求)中断。如果给定中断线上所有中断处理程序返回的都是IRQ_NONE,那么,内核就可以检测到出了问题。最后,需要说明的就是那个static了,中断处理程序通常会标记为static,因为它从来不会被别的文件中的代码直接调用。另外,中断处理程序是无需重入的,当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止在同一个中断上接收另外一个新的中断。通常情况下,所有其他的中断都是打开的,所以这些不同中断线上的其他中断都能被处理,但当前中断总是被禁止的。由此可见,同一个中断处理程序绝对不会被同时调用以处理嵌套的中断。      

           下面要说到的一个问题是和共享的中断处理程序相关的。共享和非共享在注册和运行方式上比较相似的。差异主要有以下几点:

    1.request_irq()的参数flags必须设置为SA_SHIRQ标志。
    2.对每个注册的中断处理来说,dev_id参数必须唯一。指向任一设备结构的指针就可以满足这一要求。通常会选择设备结构,因为它是唯一的,而且中
       断处理程序可能会用到它,不能给共享的处理程序传递NULL值。
    3.中断处理程序必须能够区分它的设备是否真的产生了中断。这既需要硬件的支持,也需要处理程序有相关的处理逻辑。如果硬件不支持这一功能,那中
       断处理程序肯定会束手无策,它根本没法知道到底是否与它对应的设备发生了中断,还是共享这条中断线的其他设备发出了中断。

           在指定SA_SHIRQ标志以调用request_irq()时,只有在以下两种情况下才能成功:中断当前未被注册或者在该线上的所有已注册处理程序都指定了SA_SHIRQ.A。注意,在这一点上2.6与以前的内核是不同的,共享的处理程序可以混用SA_INTERRUPT.  一旦内核接收到一个中断后,它将依次调用在该中断线上注册的每一个处理程序。因此一个处理程序必须知道它是否应该为这个中断负责。如果与它相关的设备并没有产生中断,那么中断处理程序应该立即退出,这需要硬件设备提供状态寄存器(或类似机制),以便中断处理程序进行检查。毫无疑问,大多数设备都提这种功能。

           当执行一个中断处理程序或下半部时,内核处于中断上下文(interrupt context)中。对比进程上下文,进程上下文是一种内核所处的操作模式,(关于进程上下文和中断上下文的区别可以看文章linux内核--中断上下文&进程上下文)此时内核代表进程执行,可以通过current宏关联当前进程。此外,因为进程是进程上下文的形式连接到内核中,因此,在进程上下文可以随时休眠,也可以调度程序。但中断上下文却完全不是这样,它不可以休眠,因为我们不能从中断上下文中调用函数。如果一个函数睡眠,就不能在中断处理程序中使用它,这也是对什么样的函数能在中断处理程序中使用的限制。还需要说明一点的是,中断处理程序没有自己的栈,相反,它共享被中断进程的内核栈,如果没有正在运行的进程,它就使用idle进程的栈。因为中断程序共享别人的堆栈,所以它们在栈中获取空间时必须非常节省。内核栈在32位体系结构上是8KB,在64位体系结构上是16KB.执行的进程上下文和产生的所有中断都共享内核栈。
           下面给出中断从硬件到内核的路由过程(截图选自liuux内核分析与设计p61),然后做出总结:

            中断处理路由

                                              图一       中断从硬件到内核的路由

           上面的图内部说明已经很明确了,我这里就不在详谈。在内核中,中断的旅程开始于预定义入口点,这类似于系统调用。对于每条中断线,处理器都会跳到对应的一个唯一的位置。这样,内核就可以知道所接收中断的IRQ号了。初始入口点只是在栈中保存这个号,并存放当前寄存器的值(这些值属于被中断的任务);然后,内核调用函数do_IRQ().从这里开始,大多数中断处理代码是用C写的。do_IRQ()的声明如下:

    unsigned int do_IRQ(struct pt_regs regs)

           因为C的调用惯例是要把函数参数放在栈的顶部,因此pt_regs结构包含原始寄存器的值,这些值是以前在汇编入口例程中保存在栈上的。中断的值也会得以保存,所以,do_IRQ()可以将它提取出来,X86的代码为:
    int irq = regs.orig_eax & 0xff

           计算出中断号后,do_IRQ()对所接收的中断进行应答,禁止这条线上的中断传递。在普通的PC机器上,这些操作是由mask_and_ack_8259A()来完成的,该函数由do_IRQ()调用。接下来,do_IRQ()需要确保在这条中断线上有一个有效的处理程序,而且这个程序已经启动但是当前没有执行。如果这样的话, do_IRQ()就调用handle_IRQ_event()来运行为这条中断线所安装的中断处理程序,有关处理例子,可以参考linux内核设计分析一书,我这里就不细讲了。在handle_IRQ_event()中,首先是打开处理器中断,因为前面已经说过处理器上所有中断这时是禁止中断(因为我们说过指定SA_INTERRUPT)。接下来,每个潜在的处理程序在循环中依次执行。如果这条线不是共享的,第一次执行后就退出循环,否则,所有的处理程序都要被执行。之后,如果在注册期间指定了SA_SAMPLE_RANDOM标志,则还要调用函数add_interrupt_randomness(),这个函数使用中断间隔时间为随机数产生熵。最后,再将中断禁止(do_IRQ()期望中断一直是禁止的),函数返回。该函数做清理工作并返回到初始入口点,然后再从这个入口点跳到函数ret_from_intr().该函数类似初始入口代码,以汇编编写,它会检查重新调度是否正在挂起,如果重新调度正在挂起,而且内核正在返回用户空间(也就是说,中断了用户进程),那么schedule()被调用。如果内核正在返回内核空间(也就是中断了内核本身),只有在preempt_count为0时,schedule()才会被调用(否则,抢占内核是不安全的)。在schedule()返回之前,或者如果没有挂起的工作,那么,原来的寄存器被恢复,内核恢复到曾经中断的点。在x86上,初始化的汇编例程位于arch/i386/kernel/entry.S,C方法位于arch/i386/kernel/irq.c其它支持的结构类似。

           下边给出PC机上位于/proc/interrupts文件的输出结果,这个文件存放的是系统中与中断相关的统计信息,这里就解释一下这个表:

            interruptinfo

           上面是这个文件的输入,第一列是中断线(中断号),第二列是一个接收中断数目的计数器,第三列是处理这个中断的中断控制器,最后一列是与这个中断有关的设备名字,这个名字是通过参数devname提供给函数request_irq()的。最后,如果中断是共享的,则这条中断线上注册的所有设备都会列出来,如4号中断。

            Linux内核给我们提供了一组接口能够让我们控制机器上的中断状态,这些接口可以在<asm/system.h>和<asm/irq.h>中找到。一般来说,控制中断系统的原因在于需要提供同步,通过禁止中断,可以确保某个中断处理程序不会抢占当前的代码。此外,禁止中断还可以禁止内核抢占。然而,不管是禁止中断还是禁止内核抢占,都没有提供任何保护机制来防止来自其他处理器的并发访问。Linux支持多处理器,因此,内核代码一般都需要获取某种锁,防止来自其他处理器对共享数据的并发访问,获取这些锁的同时也伴随着禁止本地中断。锁提供保护机制,防止来自其他处理器的并发访问,而禁止中断提供保护机制,则是防止来自其他中断处理程序的并发访问。

           在linux设备驱动理论帖里详细介绍过linux的中断操作接口,这里就大致过一下,禁止/使能本地中断(仅仅是当前处理器)用:

    local_irq_disable();
    local_irq_enable();

           如果在调用local_irq_disable()之前已经禁止了中断,那么该函数往往会带来潜在的危险,同样的local_irq_enable()也存在潜在的危险,因为它将无条件的激活中断,尽管中断可能在开始时就是关闭的。所以我们需要一种机制把中断恢复到以前的状态而不是简单地禁止或激活,内核普遍关心这点,是因为内核中一个给定的代码路径可以在中断激活饿情况下达到,也可以在中断禁止的情况下达到,这取决于具体的调用链。面对这种情况,在禁止中断之前保存中断系统的状态会更加安全一些。相反,在准备激活中断时,只需把中断恢复到它们原来的状态:

    unsigned long flags;
    local_irq_save(flags);
    local_irq_restore(flags);

           参数包含具体体系结构的数据,也就是包含中断系统的状态。至少有一种体系结构把栈信息与值相结合(SPARC),因此flags不能传递给另一个函数(换句话说,它必须驻留在同一个栈帧中),基于这个原因,对local_irq_save()的调用和local_irq_restore()的调用必须在同一个函数中进行。前面的所有的函数既可以在中断中调用,也可以在进程上下文使用。

           前面我提到过禁止整个CPU上所有中断的函数。但有时候,好奇的我就想,我干么没要禁止掉所有的中断,有时,我只需要禁止系统中一条特定的中断就可以了(屏蔽掉一条中断线),这就有了我下面给出的接口:

    void disable_irq(unsigned int irq);
    void disable_irq_nosync(unsigned int irq);
    void enable_irq(unsigned int irq);
    void synchronise_irq(unsigned int irq);

           对有关函数的说明和注意,我前边已经说的很清楚了,这里飘过。另外,禁止多个中断处理程序共享的中断线是不合适的。禁止中断线也就禁止了这条线上所有设备的中断传递,因此,用于新设备的驱动程序应该倾向于不使用这些接口。另外,我们也可以通过宏定义在<asm/system.h>中的宏irqs_disable()来获取中断的状态,如果中断系统被禁止,则它返回非0,否则,返回0;用定义在<asm/hardirq.h>中的两个宏in_interrupt()和in_irq()来检查内核的当前上下文的接口。由于代码有时要做一些像睡眠这样只能从进程上下文做的事,这时这两个函数的价值就体现出来了。

           最后,作为对这篇博客的总结,这里给出我前边提到的用于控制中断的方法列表:

          interruptslist



    参考资料:http://www.cnblogs.com/hanyan225/archive/2011/07/17/2108609.html

    展开全文
  • 中断中断处理(二)

    千次阅读 2015-07-13 09:22:50
    **书接上回**(六):中断上下文当执行中断处理程序的时候,内核处于中断上下文中.中断上下文由于没有后备进程,所以不可以睡眠,同时中断上下文具有...现在每中断处理程序自己的中断栈,大小是原来的一半,
  • Linux设备驱动程序学习-中断处理

    千次阅读 2013-07-03 17:55:26
    个“中断”仅是个信号,当硬件需要获得处理器对它的关注时,就可以发送这个信号。 Linux 处理中断的方式非常类似在用户空间处理信号的方式。 大多数情况下,个驱动只需要为它的设备的中断注册个处理例程,并...
  • linux设备驱动程序第二版 中断处理

    千次阅读 2007-08-24 14:59:00
    事实上中断处理的接口如此之好,以至于编写和安装中断处理程序几乎和编写其它核心函数一样容易。但是由于中断处理程序和系统的其它部分是异步运行的,使用时要注意一些事项。 本章的示例代码使用并口来产生中断。...
  • AVR中断优先级

    千次阅读 2012-12-25 09:53:58
    AVR单片机在同个优先级,中断向量入口地址越低,其优先级越高。AVR单片机在响应 断以后,会禁止系统响应其余中断。如果程序需要在某个中断服务程序中响应其它中断事 件,可以在该中断服务程序中用SEI指令或_SEI...
  • Linux中断一:初看Linux中断

    千次阅读 2012-03-13 20:33:23
    中断是Linux内核比较难而且比较重要的部分,如果想掌握这些东西,理解是首当其冲的个重要环节。所谓的难点,新知识,如果完全理解了原理,至少相当于掌握了80%,这对于任何知识都一样,所谓真正理解,就是要...
  • 在调试时,发现有中断有 挂起、激活、失能等状态,考虑这些状态都是干啥用的呢!他们是Cortex-M核所共有的,因此这里不针对与具体用的STM32 MCU,直接上升到 Cortex-M内核来了解一下! 简介   中断(也称为“异常...
  • 中断响应时间/中断步骤/中断

    千次阅读 2017-06-29 10:10:32
     计算机也是采用的这种方法,五个中断源,每个中断产生后都到个固定的地方去找处理这个中断的序,当然在去之前首先要保存下面将执行的指令的地址,以便处理完中断后回到原来的地方继续往下执行程序。...
  • DSP之中断总结篇

    万次阅读 2012-08-14 13:15:04
    中断定义:由硬件或软件驱动的信号,使DSP将当前的程序挂起,执行另个称为中断服务程序(ISR)的任务。 C55x支持32个ISR。有些ISR可以由软件或硬件触发,有些只能由软件触发。 当CPU同时收到多个硬件中断请求时...
  • 中断处理

    千次阅读 2012-05-07 20:29:02
    16. 中断处理 上一页    ...16. 中断处理 ...对于中断和异常的定义在ULK的第4章中给予...同步中断是党指令执行时由CPU控制单元产生的,之所以称为同步,是因为只有在一条指令中止执行后CPU才会发出中断。 异步
  • 中断和异常

    千次阅读 2016-07-24 21:01:10
    中断和异常发生时, 典型的结果是迫使处理器将控制从当前正在执行的程序或任务转移到另个历程或任务去. 该例程叫做中断处理程序, 或者异常处理程序. 如果是个任务, 则发生任务切换. 1. 中断(Interrupt) ...
  • 正如在前文中你所知道的那样,个使用tasklet的中断程序首先会通过执行中断处理程序来快速完成上半部分的工作,接着通过调用tasklet使得下半部分的工作得以完成。可以看到,下半部分被上半部分所调用,至于下半部分...
  • DSP中断总结

    千次阅读 2018-07-03 13:35:55
    1 中断概述中断定义:由硬件或软件驱动的信号,使DSP将当前的程序挂起,执行另个称为中断服务程序(ISR)的任务。C55x支持32个ISR。有些ISR可以由软件或硬件触发,有些只能由软件触发。当CPU同时收到多个硬件中断...
  • 中断上下部分

    千次阅读 2012-02-13 13:59:01
    从 linux1.x版本开始,中断处理程序...但是下半部分(如果的话)几乎做了中断处理程序所有的事情,可以 推迟执行。内核把上半部分和下半部分作为独立的函数来处理,上半部分的功能就是“登记中断”,决定其相关的下半
  • 中断函数

    千次阅读 2014-10-22 12:44:15
    C51的中断函数的格式为:void FuncIr...但是程序中允不允许使用return呢?答案是允许的,不过只能用"return;",不能用"return(z);";用在一些需要快速返回的地方,对应的汇编会多个ret语句,相对效率会高一些。  
  • 第五课. 内核中断系统的设备树

    千次阅读 2018-11-22 14:30:57
    这节课讲解如何在中断系统使用设备树,也就是用设备树如何描述中断中断体系在4.x内核变化很大,中断体系又跟pinctrl系统密切相关,pinctrl又涉及GPIO子系统,这样讲下去的话,设备树课程就变成驱动专题了...
  • 中断和异常的处理

    万次阅读 2014-03-15 18:14:47
    中断和异常发生时, 典型的结果是迫使处理器将控制从当前正在执行的程序或任务转移到另个历程或任务去. 该例程叫做中断处理程序, 或者异常处理程序. 如果是个任务, 则发生任务切换. 1. 中断(Interrupt)
  • ARM中断源之定时器中断

    千次阅读 2018-02-02 14:14:07
     实时时钟请求中断。在控制遇到定时检测和...走到这里,大家肯定对Linux的中断处理概念了,下面我们通过个具体的实例,来了解Linux内核处理中断的全过程,那就是定时器中断。在详细分析这个过程之前,我们把
  • Unity如何中断C#脚本的无限循环

    千次阅读 2016-06-24 18:48:16
    无限循环似乎应该很容易避免。但时不时就会遇到它的变种。曾经有次因为错误的随机函数返回了1.000001这个值导致无限...再后来还有坏掉的数据结构贯穿了个规则假定了current = current.next;并认为这个规则一定会
  • linux 中断

    千次阅读 2007-07-23 13:38:00
    中断 目 录 中断中断中断 定时器代码分析 from aka 硬件中断中断
  • eCos中断模型

    千次阅读 2014-06-30 15:48:13
    中断控制器这两个寄存器不一定存在,但是其所代表的功能是存在的,同样,CPU某寄存器的两个比特位也不一定都存在,但是CPU一定别的东西来代替它(至少i-bit的概念一定是存在的)。 0.1 综述 下面以...
  • ARM中断

    千次阅读 2011-10-04 21:37:46
    S3C2440系统中断 分类: ARM体系结构 2011-06-20 14:17 196人阅读评论(0) 收藏举报 1.1 S3C2440系统中断 CPU和外设构成了计算机系统,CPU和外设之间通过总线进行连接,用于数据通信和控制,CPU管理监视计算机...
  • 计算机中断机制

    千次阅读 2009-05-10 00:03:00
    计算机中断机制摘自《操作系统精髓与设计原理》BY William Stallings...下表列出五种常见中断类型: 程序中断:在程序执行的过程,发现了程序性质的错误或出现了某些特定状态而产生的中断。如浮点溢出、用户态下
  • 定时器中断

    千次阅读 2010-03-07 17:54:00
    走到这里,大家肯定对Linux的中断处理概念了,下面我们通过个具体的实例,来了解Linux内核处理中断的全过程,那就是定时器中断。在详细分析这个过程之前,我们把Linux时间管理的概念先缕缕。 在当前的80x86...
  • linux中断处理详解

    千次阅读 2012-02-23 15:46:40
    上文我们通过个简单的例子分析了中断程序的基本结构。可以看到,中断处理程序在处理中断时起到了关键作用,也是中断程序必不可少的部分。不过,现如今的中断处理流程都会分为两部分:上半部分(top half...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 60,657
精华内容 24,262
关键字:

中断服务程序中至少有一条