精华内容
下载资源
问答
  • KL25提供的周期中断定时器(PIT)、低功耗定时器(LPTMR)、实时时钟(RTC)三个模块均可以产生定时信号。 RIT、LPTMR、RTC 功能概述 周期中断定时器RIT:KL25/26内部支持一个周期中断定时器模块RIT,内含两个通道,...

    定时信号

    KL25提供的周期中断定时器(PIT)、低功耗定时器(LPTMR)、实时时钟(RTC)三个模块均可以产生定时信号。

    RIT、LPTMR、RTC

    功能概述

    周期中断定时器RIT:KL25/26内部支持一个周期中断定时器模块RIT,内含两个通道,没有外部引脚。每个通道都有一个独立的32位减一计数器(CVALn,n=0,1),时钟源固定为系统总线时钟并且不可分频。

    低功耗定时器LPTMR:KL25/26支持一个低功耗定时器模块LPTMR,可以被配置为具有可选预分频因子的定时器,也可以被配置为带有脉冲干扰滤波器功能的脉冲计数器,用以普通单次计时。

    时钟源可以多种选择,即可配置为1KHz的LPO时钟,32KHz的慢速IRC时钟,4MHz的快速IRC时钟,8MHz额OSCERCLK时钟。时钟源分频范围大,最小分频1,最大分频65536。当采用1KHz的LPO时钟时,最大中断周期可达50天。

    实时时钟RTC:KL25/26支持一个实时时钟RTC,RTC正常情况下需要外接32.768KHz晶振、匹配电容、备用电源等元件,提供MCU掉电累计计时功能。

    在KL25评估板上芯片晶振与RTC晶振引脚复用在一起产生冲突,无外部晶振,故无法提供掉电计时功能,KL25上的RTC可作为普通累计计时和闹钟报警使用。RTC定时器由一个具有报警功能的32位秒计数寄存器和一个具有补偿功能的16位预分频寄存器组成。

    工作原理

    周期中断定时器PIT工作原理:

    1. 当PIT模块的某一通道被初始化使能后,计数器CVALn的值会自动加载重载寄存器LDVALn的值,开始按照时钟源频率减一计数。
    2. 到0时,标志寄存器TFLGn的TIF位被置1,产生定时溢出中断。

    中断周期的最大值可由时钟源频率及计数器位数计算获得。

    例如时钟源频率为24MHz,可计算得出中断周期最大值为178时,实际的中断周期由重载寄存器LDVALn值决定。

    低功耗定时器LPTM工作原理:LPTMR模块内含16位的递增定时器

    1. 在LPTMR模块初始化使能后,定时器从0开始加1计数。
    2. 当计数器CNR的值与重载寄存器LPTMR0_CMR的值相等就会置控制和状态寄存器CSR的比较标志位TCF并产生中断。
    3. 程序转而运行该中断向量号对应的中断服务例程,并在例程中通过向该位写1来完成清比较标志位的工作。
    4. 此时LPTMR模块就会重新开始计时。

    实时时钟RTC工作原理:

    RTC模块包括两个中断向量号,秒中断的中断向量号37,其他中断对应的中断向量号36。

    RTC模块的计数器为递增计数,累计计数时间可达2³²秒,超过135年。

    时钟源有多种,单次中断时间取决于时钟源的频率。

    当时钟源为32.768KHz时,中断时间为1秒,即正常计时使用的中断时间,而如果中断为1KHz的LPO时钟,中断时间就会变为32.768秒。

    1. 在RTC模块初始化使能后,每个时钟周期,预分频寄存器TPR的值加1。
    2. 定时条件成熟时,程序转而运行该中断向量号对应的中断服务例程。

    因为没有秒中断标志位,所以在例程中无需清除,在硬件设计上减少了软件开销。

    如果此时秒计时器TSR的值与报警寄存器TAR的值相等,就可产生报警中断,程序转而运行该中断向量对应的中断服务例程,并在例程中通过重写报警寄存器TAR的值来完成清报警中断标志位TAF的工作。

    驱动构件封装要求

    PIT模块:该模块有两个独立的通道,时钟源为系统总线时钟,为方便使用,在头文件中给出通道号

    及工作时钟频率的宏定义。

    在中断服务例程中,需要判断某一通道计数器是否产生溢出中断。因此在头文件中给出宏函数PIT_GET_FLAG(index)用于判断index(通道号)通道计数器是否产生溢出中断。

    头文件中还有清中断标志位宏函数PIT_CLEAR_FLAG(index)。

    除了宏定义及宏函数,头文件还需给出对外接口函数:

    PIT模块初始化函数pit_init,形参为通道号及以毫秒为单位的中断周期;

    使能中断函数函数pit_enable_int禁止中断函数pit_disable_int,形参为通道号。

    LPTMR模块:该模块的时钟源有很多,为区分不同的时钟源,在头文件中给出时钟源的宏定义。

    在中断服务例程中,需要判断计数器是否产生溢出中断,因此在有文件中给出了宏函数LPTMR_GET_FLAG,用于判断计数器是否产生溢出中断。

    头文件中还给出了用于清中断标志的宏函数LPTMR_CLEAR_FLAG。

    除了宏定义及宏函数,头文件还需给出对外接口函数:

    LPTMR模块初始化函数lptmr_init,形参为时钟源类别;

    使能中断函数lptmr_enable_init禁止中断函数lptmr_disable_int,无形参。

    RTC模块:在中断服务例程中,需要判断计数器是否产生无效中断,因此,在头文件中给出了宏函数RTC_GET_INVALID_FLAG,用于判断计数器是否产生无效中断。提供宏函数RTC_GET_OVERFLOW_FLAG,用于判断溢出中断;宏函数RTC_GET_ALAM_FLAG,用于判断报警中断;宏函数RTC_CLEAR_FLAG,用于清除中断标志。

    除宏函数外,头文件还需给出对外接口函数:RTC模块初始化函数rtc_imit,形参为报警值;复位秒计数器函数rtc_reset_second_time,形参为秒计数值。

    启动计时函数rtc_start,无形参;停止计时函数rtc_stop,无形参;使能中断函数rtc_enable_int禁止中断函数rtc_disable_int,无形参。

     

    驱动构件的使用方法

    使用方法与SysTick和TPM类似,使用时先进行初始化,再使能中断,然后在中断中编程。

     

    嵌入式技术基础与实践(第4版)

    展开全文
  • 中断

    千次阅读 2013-10-31 11:54:00
    中断是一种使CPU中止正在执行的程序而转去处理特殊事件的操作。这些引起中断的事件称为...一般称为硬件中断或外中断,由程序中安排的中断指令INT产生中断,或由CPU的某些错误结果产生中断称为软件中断或内中断
    中断是一种使CPU中止正在执行的程序而转去处理特殊事件的操作。这些引起中断的事件称为中断源,它们可能是来自外部设备的输入/输出请求,也可能是计算机的一些异常事故或其它内部原因。由外设控制器或协处理器(8087/80287)引起的中断
    一般称为硬件中断或外中断,由程序中安排的中断指令INT产生的中断,或由CPU的某些错误结果产生的中断称为软件中断或内中断。

      8086/8088的中断源如动画所示。图中引线端标示的数字为系统分配的中断类型号。


      连到CPU的非屏蔽中断(NMI)是为电源错、内存或I/O总线的奇偶等异常事件的中断保留的,它不受中断允许标志IF的屏蔽,而且在整个系统中只能有一个非屏蔽中断,其中断类型号为2。

      外部设备的中断是通过Intel 8259A可编程中断控制器(PIC)连到主机上。CPU通过一组I/O端口控制8259A,而8259A则通过INTR管脚给CPU传送中断信号。多个8259A PIC可以树形结构连在一起,从而使大量的外部设备顺序连接到CPU的中断系统上。外部设备和8259A PIC的连法是由设计人员规定好的,这种外中断类型的分配由硬件连线实现,因而软件不能对其修改。动画中外设与8259A PIC的连法是80X86的标准连法。内中断不是由连线接到硬件上的,中断20H到3FH用于调用DOS功能例行程序,其它中断号小于20H或大于3FH的中断,用于调用IBM PC ROM BIOS或一些应用软件,这些内容在以后的章节中将要陆续讲到。

      中断是CPU和外部设备进行输入/输出的有效方法。这种输入/输出方式一直被大多数计算机所采用,它可以避免因反复查询外部设备的状态而浪费时间,从而提高了CPU的效率。

    8.3.1 8086的中断分类

     
    8.3.1.1 软件中断
     
      软件中断又称为内中断,它通常由三种情况引起:
      (1) 由中断指令INT引起。
      (2) 由于CPU的某些错误而引起。
      (3) 为调试程序(DEBUG)设置的中断。
      

      单步是 一种很有用的调试方法。当标志位TF置为1时,每条指令执行后,CPU自动产生类型号为1的中断-单步中断。产生单步中断时,CPU同样自动地将 FLAGS、CS和IP的内容保存入栈,然后清除TF、IF,于是,当进入单步中断处理程序后,就不是处于单步方式了,它将按正常方式运行中断处理程序。 在单步处理程序结束时,原来的FLAGS从堆栈中取回,又把CPU重新置成单步方式。
      
      使用单步中断可以一条指令一条指令地跟踪程序的流程,观察CPU每执行一条指令后,各个寄存器及有关存储单元的变化,从而指出和确定产生错误的原因。

      断点中断也是供DEBUG调试程序使用的,通常调试程序时,把程序按功能分成几段,然后每段设一个断点。当CPU执行到断点时便产生中断,这时程序员可以检查各寄存器及有关存储单元的内容。
      在上述内中断中,INT指令和INTO指令产生的中断,以及除法错中断都不能被禁止,并且比任何外部中断的优先权都高
    1. 中断指令INT引起的内中断
     
        CPU执行完一条INT n指令后,会立即产生中断,并且调用系统中相应的中断处理程序来完成中断功能,中断指令的操作数n指出中断类型号。

      例如,我们要对存储器的容量进行测试,可在程序中安排一条中断指令:
        
         INT 12H
      
      当CPU执行这条指令时,立即产生了一个中断,并从中断向量表的0:48H开始的四个字节单元中取出段地址和偏移地址,然后转去执行相应的中断处理程序以完成对存储器的测试,返回调用程序后,AX寄存器中的数据即为存储器的大小。
      
      INT指令可以指定0~0FFH中的任何类型号。除系统占用的类型号之外,用户还可利用为用户保留的类型号扩充新的中断处理功能。

      2. 处理CPU某些错误的中断
       
       (1) 除法错中断,中断类型号为0。
       在执行除法指令时,若发现除数为0或商超过了寄存器所能表达的范围,则立即产生一个类型为0的中断。

       (2) 溢出中断,中断类型号为4。
       INTO指令专门用来处理溢出中断,下例为测试加法溢出的指令:
       
       ADD AX,VALUE
       INTO

      如果溢出标志OF置1,指令INTO可中断发生溢出的算术操作,如OF为0,则INTO指令不产生中断,CPU继续运行原程序。溢出中断处理程序的主 要功能是打印出一个出错信息,在处理程序结束时,不返回原程序继续运行,而是把控制交给操作系统。

      3. 为调试程序(DEBUG)设置的中断

      (1) 单步中断,中断类型号为1。

      (2) 断点中断,中断类型号为3。
      断点可以设置在程序的任何地方,设置断点实际上是把一条断点指令INT 3插入程序中,CPU每执行到断点处的INT3指令便产生一个中断。

    8.3.1.2 硬件中断

      硬件中断来自处理机的外部条件,如I/O设备或其它处理机等,以完全随机的方式中断现行程序而转向另一处理程序。硬件中断又称为外中断。
      
      硬件中断主要有两种来源,一种是非屏蔽中断(NMI),另一种是来自各种外部设备的中断。由外部设备的请求引起的中断也称为可屏蔽中断。

      微型计算机配置的外部设备一般有硬磁盘(DISK),软磁盘(FLOPPY DISK),显示器(CRT)和各种打印机(LINE PRINTER)等。这些外部设备通过8259A可编程中断控制器和CPU相连,8259A可编程中断控制器可接收来自外设的中断请求信号,并把中断源的中断类型号送CPU,如果CPU响应该外设的中断请求,就自动转入相应的中断处理程序。

      从外设发出中断请求到CPU响应中断,有两个控制条件是起决定性作用的:

      (1) 该外设的中断请求是否屏蔽,这个条件由8259A的中断屏蔽寄存器控制;中断屏蔽寄存器的某位为0表示允许某种外设中断请求,某位为1表示某种外设的中断请求被屏蔽(禁止)。
      (2) CPU是否允许响应中断,这由标志寄存器(FLAG)中的中断允许位IF控制。如果IF=0,CPU就禁止响应任何外设的中断,如果IF=1,则允许CPU响应外设的中断请求。有两条指令能设置和清除IF位。
      STI 设置中断允许位(IF=1)
      CLI 清除中断允许位(IF=0)
    中断屏蔽寄存器的I/O端口地址是21H,它的8位对应控制8个外部设备(见图8.4(a)),通过设置这个寄存器的某位为0或为1来允许或禁止某外部设备的中断。某位为0表示允许某种外设中断请求,某位为1表示某种外设的中断请求被屏蔽(禁止)。
      
      例如,只允许键盘中断,可设置如下中断屏蔽字:
      MOV AL, 11111101B
      OUT 21H, AL
      
      如果系统重要新增设键盘中断,则可用下列指令实现:
      IN AL, 21H
      AND AL, 11111101B
      OUT 21H, AL

      在编写中断程序时,应在主程序的初始化部分设置好中断屏蔽寄存器,以确定允许用中断方式工作的外部设备。

      外部设备向CPU发出中断请求,CPU是否响应还与标志寄存器中的中断标志位IF有关。如果IF=0,CPU就禁止响应任何外设的中断,也就是 说,CPU将不会产生中断来处理外设的请求。如果IF=1,则允许CPU响应外设的中断请求, 允许CPU响应外设的中断请求(IF=1)也叫做开中断,反之叫做关中断(IF=0)。

      我们已经知道,当任何类型的中断发生时,当前的FLAGS要保存入栈,然后清除IF位进入中断处理程序。如果允许在一个中断处理程序的执行过程中发生 硬中断,则必须用一条STI指令开中断。当执行到中断返回指令IRET,又取出FLAGS先前的值,其中IF为1,CPU将允许硬中断再次发生。



    非屏蔽中断是一种特殊的硬件中断,它和IF标志位无关。非屏蔽中断的类型号为2,CPU不能禁止非屏蔽中断。

      对非屏蔽中断, CPU总会响应的,所以非屏蔽中断主要用于一些紧急的意外处理,如电源掉电等。另外计算机内部的实时钟希望能不停地计时,所以也可以把非屏蔽中断提供给实时钟。

      中断结束命令是由中断命令寄存器中的中断结束位(5位)控制的。当EOI位为1时,当前正在处理的中断请求就被清除。

      结束硬件中断用下面的指令:
      MOV AL, 20H
      OUT 20H, AL
      在一次中断处理结束之前,还应给8259A可编程中断控制器的中断命令寄存器发出中断结束命令 (End Of Interrupt -- EOI)。中断命令寄存器的I/O端口地址为20H(见图8.4(b)),它的各控制位可动态地控制中断处理过程,其中L2-L0三位指定IR0-IR7 中具有最低优先级的中断请求。6位(Set Level)和7位(Rotate)控制IR0-IR7的中断优先级的顺序。5位(EOI)是中断结束位,当EOI位为1时,当前正在处理的中断请求就被 清除,所以在中断处理完成后,必须把中断结束位置为1,否则以后将屏蔽掉对同级中断或低级中断的处理。当然在必要的时候,在中断处理程序中也可利用EOI 命令清除当前的中断请求,使得在中断处理的过程中又能响应同级和低级中断。

      ts.gif    
    图8.4 中断屏蔽寄存器和中断命令寄存器  
     8_3_4.gif


    8.3.2 中断向量表

      中断向量表是各类型中断处理程序的入口地址表。

      各类型中断处理程序的段地址和偏移地址在中断向量表中按中断类型号顺序存放,因此每类中断向量的地址可由中断类型号乘以4计算出来。

       动画以BIOS中断INT 4AH为例,表示出中断操作的5个步骤:
      (1) 取中断类型号
      (2) 计算中断向量地址
      (3) 取中断向量,偏移地址送IP,段地址送CS
      (4) 转入中断处理程序
      (5) 中断返回到INT指令的下一条指令
    我们给每种中断都安排一个中断类型号。80x86中断系统能处理256种类型的中断,类型号为 0-0FFH。如图8.3所示的中断源,系统时钟的中断类型为08,键盘为09,软中断中的除法错误的中断类型为0,等等。每种类型的中断都由相应的中断 处理程序来处理,中断向量表就是各类型中断处理程序的入口地址表。
     
      ts.gif            
    图8.5 中断向量表        
             8_3_5.gif
      我们知道存储器的低1.5K字节,地址从0段0000 ~ 5FFH为系统占用,其中最低的1K字节,地址从0000 ~ 3FFH存放中断向量。中断向量表中的256项中断向量对应256种中断类型,每项占用四个字节,其中两个字节存放中断处理程序的段地址(16位),另两 个字节存放偏移地址(16位)。因为各处理程序的段地址和偏移地址在中断向量表中按中断类型号顺序存放(如图8.5所示),所以每类中断向量的地址可由中 断类型号乘以4计算出来。例如,报警中断的中断类型为4AH,它的中断向量地址为4AH*4=128H,即128H、129H两字节存放的是报警中断处理 程序的偏移地址,12AH、12BH两字节存放的是报警中断处理程序的段地址,取出段地址和偏移地址放入CS和IP,CPU就可以转入相应的中断处理程 序。

      采用向量中断的方法,大大加快了中断处理的速度,因为计算机可直接通过中断向量表转向相应的处理程序,而不需要CPU去逐个检测和确定中断原因。  
    表8.2列出了80X86各类型中断在中断向量表中的地址。
      例8.4 使用DOS功能调用存取中断向量
     
      为中断类型N设置中断向量的程序:
    MOV AX, 0
    MOV ES, AX    ;set to base interrupt vectors
    MOV BX, N * 4   ;offset of type N interrupt
    MOV AX, OFFSET INTHAND
    MOV ES:WORD PTR [BX], AX  ;set addr of INTHAND
    MOV AX, SEG INTHAND
    MOV ES : WORD PTR[BX+2], AX
    ...
    INHAND:  ;interrupt processing routine
    ...
    IRET

       
      bg.gif         表8.2 中断向量表地址分配

    地 址    中断类型号
    0 - 7F     0 - 1F     BIOS中断向量
    80 - FF    20 - 3F    DOS中断向量
    100 - 17F   40 - 5F  扩充BIOS中断向量
    180 - 19F   60 - 67    用户中断向量
    1A0 - 1BF   68 - 6F    保留

    地址    中断类型号
    1C0 - 1DF  70 - 77   I/O设备中断向量
    1E0 - 1FF  78 - 7F    保留
    200 - 3C3  80 - FD    BASIC
    3C4 - 3FF  F1 - FF    保留

      用 户可以利用保留的中断类型号扩充自己需要的中断功能,对新增加的中断功能要在中断向量表中建立相应的中断向量。如果新的中断功能只供自己使用,或用自己编 写的中断处理程序代替系统中的某个中断处理功能时,要注意保存原中断向量。在设置自己的中断向量时,应先保存原中断向量再设置新的中断向量,在程序结束之 前恢复原中断向量。

      实际上,我们在检查或设置任何中断向量时,总是避免直接使用中断向量的绝对地址,而是使用DOS功能调用(21H)存取中断向量。

      存取中断向量的DOS功能调用
     
      
    设置中断向量
        把由AL指定的中断类型的中断向量DS : DX放在中断向量表中
      预置:AH = 25H
         AL = 中断类型号
         DS : DX = 中断向量
      执行:INT 21H

      取中断向量
        把由AL指定的中断类型的中断向量从中断向量表中取到ES : BX中
      预置:AH = 35H
         AL = 中断类型号


      执行:INT 21H
      返回时送:ES : BX = 中断向量


      cxd.gif 
    例8.4  
         
    ...
          MOV    AL, N          ;type N interrupt
          MOV    AH, 35H         ;get interrupt vector
          INT    21H
          PUSH    ES            ;save the old base and
          PUSH    BX           ; offset of interrupt N
          PUSH   DS
          MOV    AX, SEG INTHAND
          MOV    DS, AX          ;base of INTHAND in DS
          MOV    DX, OFFSET INTHAND   ;offset in DX
          MOV    AL, N          ;type N
          MOV    AH, 25H        ;set interrupt vector
          INT    21H
          POP    DS
          ...
          POP    DX           ;restore the old offset
          POP    DS           ; and base of interrupt
          MOV    AL, N          ;type N
          MOV    AH, 25H        ;set interrupt vector
          INT    21H
          RET               ;return
         
    ;
     INTHAND: ...                ;interrupt processing routine
          ...
          IRET

    8.3.3 中断过程

      当中断发生时,由中断机构自动完成下列动作:
      1. 取中断类型号N
      2. 标志寄存器(FLAGS)内容入栈
      3. 当前代码段寄存器(CS)内容入栈
      4. 当前指令计数器(IP)内容入栈
      5. 禁止硬件中断和单步中断(IF=0, TF=0)
      6. 从中断向量表中取4*N的字节内容送IP,取4*N+2中的字节内容送CS
      7. 转中断处理程序
     
      中断过程如动画所示

      中断发生的过程很像我们所熟悉的子程序调用,不同的是在保护中断现场时,除了保存返回地址CS:IP之外,还保存了标志寄存器FLAGS的内容。因为 标志寄存器记录了中断发生时,程序指令运行的结果特征,当CPU处理完中断请求返回原程序时,要保证原程序工作的连续性和正确性,所以中断发生时的 FLAGS内容也要保存起来。另一个不同点是,在中断发生时,CPU还自动清除了IF位和TF位,这样设计的目的是使CPU转入中断处理程序后,不允许再 产生新的中断,如果在执行中断处理程序的过程中,还允许外部的中断,可通过STI指令再把IF置为1。

      编写中断处理程序和编写子程序一样,所使用的汇编语言指令没有特殊限制,只是中断程序返回时使用IRET指令。这条指令的工作步骤和中断发生时的工作 步骤正好相反。它首先把IP、CS和FLAGS的内容出栈,然后返回到中断发生时紧接着的下一条指令

    8.3.4 中断优先级和中断嵌套

      1.中断优先级
      8086规定中断的优先级次序为:

    8_4_1.gif

      可屏蔽中断的优先权又分为八级,按图8.3的连接,在正常的优先级方式下,定时器的优先级最高,键盘其次,打印机的优先权最低。


     
     在 8086系统中,有软件中断、硬件中断等多个中断源,当多个中断源同时向CPU请求中断时,CPU应如何处理呢?办法是我们给各种中断源事先安排一个中断 优先级次序,当多个中断源同时申请中断时,CPU先比较他们的优先级(Priority),然后从优先级高到优先级低的次序来依次处理各个中断源的中断请 求。

      在8.3节中我们已经提到8259A的中断命令寄存器(图8.4)的6位和7位能控制各中断请求端的优先次序。在正常的优先级方式下,优先级次序是:
      IR0,IR1,IR2,IR3,IR4,IR5,IR6,IR7

      在发出一个EOI命令时,7位(R)和6位(SL)有四种组合,其含义如下:
      R SL
      0  0  正常优先级方式
      0  1  清除由 L2 - L0指定的中断请求
      1  0  各中断优先级依次左循环一个位置
      1  1  各中断优先级依次循环到由L2 - L0指定的中断请求到达最低优先级位置上。

      硬件中断的优先级次序一般在正常优先级方式下(R=0,SL=0),但在必要的情况下,设置中断命令寄存器能改变IR0-IR7的优先级次序,例 如,IR0-IR7原为正常的优先级次序,现在要使IR4成为最低级的中断请求,则给端口20H送命令码:11100100,即 R=1,SL=1,EOI=1,L2L1L0=100,这样,各中断优先级就依次循环到IR4为最低优先级的位置上:
      IR5,IR6,IR7,IR0,IR1,IR2,IR3,IR4,IR5

      如果再送一个命令码:10100000,则优先级次序再向左循环一个位置,成为:
      IR6,IR7,IR0,IR1,IR2,IR3,IR4,IR5

      在下面的描述中,如无特别说明,中断优先级是指正常方式下的中断优先级。



      2.中断嵌套
      中断嵌套是指正在运行的中断处理程序,又被其它中断源中断的情况。

      一个正在执行的中断处理程序,在开中断(IF=1)的情况下,能被优先级高于它的中断源中断,但如果要被同级或低级的中断源中断,则必须发出EOI命令,清除正在执行的中断请求,才能响应同级或低级的中断。


      80X86没有规定中断嵌套的深度(中断程序又被中断的层次),但在实际使用时,多重的中断嵌套要受到堆栈容量的限制,所以在编写中断程序时,一定要考虑有足够的堆栈单元来保存多次中断的断点及各寄存器的内容。

      首先,CPU响应优先级高的IR2,转去处理IR2的中断处理程序。进入IR2处理程序后,IF被置为1。当IR1的中断请求到达后,因IR1的优先 级高于IR2,CPU就立即中断IR2的程序,转去执行IR1的处理程序。在IR1处理程序中,由指令发出了EOI命令,结束了IR1的中断请求。返回 IR2处理程序后,同样由于发出EOI命令清除了IR2的中断请求,所以在较低级的中断请求IR4到达后,即转向处理IR4的中断请求。在IR4处理程序 的执行过程中,IR3的中断请求到达,当判断IF已被置为1,则又中断了IR4的程序,转去执行IR3的程序。在IR3程序中,也发出了开中断指令 (STI)和中断结束命令(EOI),最后IRET指令使其返回到IR4程序,IR4在返回IR2之前也发出了EOI命令,结束了IR4的中断请求。

      IR2中断请求在前面已被清除,所以IR4执行完后,IR2继续执行直到返回主程序。

      中断嵌套举例:
      该动画的例子是在正常优先级方式下,优先级中断和中断嵌套发生时的处理过程。该例子假定在主程序的执行过程中,IR2和IR4的中断请求同时发生, 而后IR1的中断请求又到达,最后IR3的中断请求也到达。

    多级8259A 中断系统:
      硬件中断的扩充使用多级的8259A系统。在多级中断系统中,从属的8259A连接到主8259A的哪一端上,它就具有那一端的中断优先级别,如图8.6所示。


      在图8.6的连接方式下,各中断请求端的优先级排列顺序如下:

    8_4_4.gif

      对于主8259A和从属8259A的中断屏蔽寄存器,禁止相应端中断请求的原理和单级8259A是一样的。

    8_4_3.gif


    8.3.5 中断处理程序
     
      通过前面几节对中断的介绍,我们对如何编写中断程序已经有一些了解了,现在把它们归纳在一起就更清楚了。

      左面是主程序为响应中断所作的准备工作以及硬件(包括CPU和外设接口)自动完成的动作:


      中断处理程序的编写方法和标准子程序很类似,下面是编写中断处理子程序的步骤,请注意与子程序编写的一些不同之处。

      
    8_5.gif

      至此,CS和IP寄存器取得了中断处理程序的段地址和偏移地址,CPU就把控制转给中断处理程序。

      这里要注意的是设备发到CPU的中断请求信号在时间上是随机的,只要未被屏蔽的设备本身的状态是准备好或空闲的,它就会向CPU请求中断,如果此时 CPU正在执行一条指令,那么就要等这条指令执行完后,才响应中断。对加封锁的指令(如LOCK MOV AX, BX)应看作为一条指令处理;对加重复前缀的串指令(如REP MOVSB),也要作为一个整体来处理,但不是把串操作全部重复执行完,而是执行一次重复和串指令即可响应中断。对MOV指令和POP指令,如果处理对象 是段寄存器时,那么本条指令执行完后,接着再执行一条指令才响应中断。对开中断指令STI和中断返回指令IRET,也是要在STI或IRET指令执行完 后,再执行一条指令才响应中断。以上是几种特殊情况,对一般指令,只要一条指令的执行周期结束即可响应中断。  

      (1) 保存寄存器内容
      (2) 如允许中断嵌套,则开中断(STI)
      (3) 处理中断
      (4) 关中断 (CLI)
      (5) 送中断结束命令(EOI)给中断命令寄存器
      (6) 恢复寄存器内容
      (7) 返回被中断的程序(IRET)

      进入中断处理程序时,IF和TF已经被清除,这样在执行中断处理程序的过程中,将不再响应其它外设的中断请求,如果这个中断处理程序允许其它设备中 断,则需用STI指令把IF位置1。中断结束命令(EOI)在程序的什么地方发出,这要看程序员是否要求在其处理过程中允许同级或低级中断。一般设备希望 一次中断的处理过程最好是完整的,所以只在中断处理结束之前发出EOI命令。

      处理中断部分是中断处理程序的主体部分,它要完成的任务是各种各样的,这与实际应用有关。如果它的任务是处理某种错误的,一般要求显示输出一系列出错 信息。如果它是对一个I/O设备进行服务的,就按其端口地址接收或发送一个单位(字节或字)的数据。要注意的是CPU产生一次中断,I/O设备只完成一个 字节(或字)的输入/输出,所以中断处理程序所用的指针变量或数据变量一般应设置存储单元来保存。

    8.3.6 中断程序举例

      例8.5 编写一个中断处理程序,要求在主程序运行过程中,每隔10秒响铃一次,同时在屏幕上显示出信息“The bell is ring!”

     在系统定时器(中断类型为8)的中断处理程序中,有一条中断指令 INT 1CH,时钟中断每发生一次(约每秒中断18.2次)都要嵌套调用一次中断类型1CH的处理程序。在ROM BIOS例程中,1CH的处理程序只有一条IRET指令,实际上它并没有做任何工作,只是为用户提供了一个中断类型号。如果用户有某种定时周期性的工作需 要完成,就可以利用系统定时器的中断间隔,用自己设计的处理程序来代替原有的1CH中断程序。

      1CH作为用户使用的中断类型,可能已被其它功能的程序所引用,所以在编写新的中断程序时,应作下述工作:
      (1) 在主程序的初始化部分,先保存当前1CH的中断向量,再置新的中断向量。
      (2) 在主程序的结束部分恢复保存的1CH中断向量。

    cxd.gif 
    Purpose: ring and display a message every 10 seconds.
      ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      ;eg8-5.asm
      ;Purpose: ring and display a message every 10 seconds.
      ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

         .model small
    ;-------------------------------------------------------------------------
         .stack
    ;-------------------------------------------------------------------------
         .data
      count   dw   1
      msg    db   'The bell is ringing!', 0dh, 0ah, '$'
    ;-------------------------------------------------------------------------
         .code
    ; Main   program
      main    proc far
      start:
      mov    ax, @data   ;allot data segment
      mov    ds, ax

    ; save old interrupt vector
      mov    al, 1ch    ;al<=vector number
      mov    ah, 35h    ;to get interrupt vector
      int    21h      ;call DOS
      push   es       ;save registers for restore
      push   bx
      push   ds

    ;set new interrupt vector
      mov    dx, offset ring  ;dx<=offset of procedure ring
      mov    ax, seg ring    ;ax<=segment of procedure ring
      mov    ds, ax       ;ds<=ax
      mov    al, 1ch      ;al<=vector#
      mov    ah, 25h      ;to set interrupt vector
      int    21h        ;call DOS

      pop ds            ;restore ds
      in     al, 21h      ;set interrupt mask bits
      and    al, 11111110b
      out    21h, al
      sti

       mov    di, 20000
    delay: mov si, 30000
    delay1:dec si
       jnz    delay1
       dec   di
       jnz   delay

    ;restore old interrupt vector
       pop    dx        ;restore registers
       pop    ds
       mov   al, 1ch      ;al<=vector#
       mov    ah, 25h      ;to restore interrupt
       int   21h        ;call DOS

       mov    ax, 4c00h     ;exit
       int   21h
    main endp


    ring proc   near
       push   ds         ;save the working registers
       push   ax
       push   cx
       push   dx

       mov    ax, @data     ;allot data segment
       mov    ds, ax
       sti


    ;siren if it is time for ring
      dec    count       ;count for ring interval
      jnz    exit        ;exit if not for ring time

      mov    dx, offset msg   ;dx<=offset of msg
      mov    ah, 09h      ;to display msg
      int    21h        ;call DOS

      mov    dx, 100      ;dx<=turn on/off times(100)
      in     al, 61h      ;get port 61h
      and    al, 0fch      ;mask bits 0,1


    sound:
      xor    al, 02       ;toggle bit 1
      out    61h, al      ;output to port 61h
      
    mov    cx, 1400h     ;value of wait

    wait1:
      loop   wait1
      dec    dx        ;control turn on/off 10 times
      jne    sound
      mov    count, 182    ;control ring interval delay(10s)


    exit:
      cli
      mov    al,20h      ;set EOI
      mov    20h,al
      pop    dx        ;restore the reg.
      pop    cx
      pop    ax
      pop    ds
      iret            ;interrupt return
    ring endp

    ;-------------------------------------------------------------------------
      end start          ;end assemble

    例8.6 在配置了键盘输入(中断类型09)和打印机输出(中断类型0FH)两种外部设备的8086中断系统中,要求从键盘上接收字符,同时对32字节的输入缓冲区进行测试,如果缓冲区已满,则键盘挂起(禁止键盘中断输入),由打印机输出一个提示信息。

      键盘和打印机分别由中断屏蔽寄存器(21H)的1位和7位控制。键盘的输入寄存器端口地址为60H,控制寄存器的端口地址为61H。打印机输出寄存器的端口地址为378H,打印机控制寄存器的端口地址为37AH。

      在这种特定情况下,只要求打印机在键盘输入缓冲区满了后,打印出提示信息,因此它可以在屏蔽键盘中断的同时,设置打印机的中断屏蔽位。另外,在中断处 理程序中用到的一些指针及计数值要保存在指定的存储单元中,每次进入中断,取出指针及计数值,退出中断时,再把修改后的指针及计数值保存起来。


      这个中断程序包括以下几部分:
      MAIN 初始化部分,保存09和0FH的原中断向量,设置新的中断向量。主程序用有限循环来模拟。主程序结束时,恢复原中断向量。
      KBDINT 键盘中断处理程序。接收按键的扫描码并保存在缓冲区中,如果输入的字符数超过32,则屏蔽键盘中断,允许打印机中断,并调用INIT-PRT子程序初始化打印机。
      INIT-PRT初始化打印机,启动适配器,发出选通信号。
      PRTINT 打印机中断处理程序。按照指针取出打印机字符送到输出寄存器,发出选通信号。
      DISPLAY-HEX 用十六进制显示AL中的代码。

    Purpose: accept keyboard input and print messages on the printer 
      ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      ;eg8-6.asm
      ;Purpose: accept keyboard input and print messages on the printer
      ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


         .model tiny
    ;-------------------------------------------------------------------------
         .stack
    ;-------------------------------------------------------------------------
         .data
      old_ip09   dw ?
      old_cs09    dw ?
      old_ip0f   dw ?
      old_cs0f    dw ?
      count     dw ?
      buffer     db 20h dup(' ')
      buf_p     dw ?
      start_msg   db 0ah, 0dh, 'RUN', 0ah, 0dh, '$'
      end_msg    db 0ah, 0dh, 'END', 0ah, 0dh, '$'
      full_msg    db 0ah, 0dh, 'Buffer full!$'

    ;-------------------------------------------------------------------------
         .code
    ; Main   program
      main    proc far
    start:
      mov    ax, @data           ;ds<=data segment
      mov    ds, ax

    ; initialize
      lea    ax, buffer          ;buf_p<=buffer address
      mov    buf_p, ax
      mov    count, 0           ;count<=0

    ; save old interrupt 09h
      mov    al, 09h            ;al<=vector#
      mov    ah, 35h            ;to get interrupt vector
      int    21h              ;call DOS
      mov    old_cs09, es          ;save registers for restore
      mov    old_ip09, bx
      push    ds               ;save ds


    ;set new interrupt 09h
      lea    dx, kbdint           ;dx<=offset of procedure kbdint
      mov    ax, seg kbdint        ;ax<=segment of procedure kbdint
      mov    ds, ax            ;ds<=ax
      mov    al, 09h            ;al<=intrrupt number
      mov    ah, 25h            ;to set interrupt vector
      int    21h              ;call DOS
      pop    ds               ;restore ds

    ;set keyboard interrupt mask bits
      in     al, 21h
      and    al, 0fdh
      out    21h, al

    ;save old interrupt 0fh
      mov    al, 0fh            ;al<=vector#
      mov    ah, 35h            ;to get interrupt vector
      int    21h               ;call DOS
      mov    old_cs0f, es          ;save registers for restore
      mov    old_ip0f, bx
      push    ds               ;save ds

    ;set new interrupt 0fh
      lea    dx, prtint           ;dx<=offset of procedure prtint
      mov    ax, seg prtint         ;ax<=segment of procedure prtint
      mov    ds, ax            ;ds<=ax
      mov    al, 0fh            ;al<=vector#
     
      mov    ah, 25h            ;to set interrupt vector
      int    21h              ;call DOS
      pop    ds              ;restore ds

      mov    ah, 09h            ;print start message
      lea    dx, start_msg
      int    21h
      
      sti
      mov    di,20000            ;main process
    mainp: mov   si,30000
    mainp1:dec  si
      jnz    mainp1
      dec    di
      jnz    mainp

      mov    ah, 09h            ;print end msg of main process
      lea    dx, end_msg
      int    21h

      cli
    ;restore old interrupt 09h
      push    ds              ;save ds
      mov    dx, old_ip09          ;ds:dx<=old handler address
      mov    ax, old_cs09
      mov    ds, ax
      mov    al, 09h            ;al<=vector#
      mov    ah, 25h            ;to restore interrupt vector
      int    21h              ;call DOS
      pop    ds               ;restore ds

    ; restore old interrupt 0fh
      push   ds               ;save ds
      mov    dx, old_ip0f          ;ds:dx<=old address
      mov    ax, old_cs0f
      mov    ds, ax
      mov    al, 0fh            ;al<=vector#
      mov    ah, 25h            ;to restore interrupt
      int    21h              ;call DOS
      pop    ds              ;restore ds

    ; enable keyboard interrupt
      in    al, 21h
      and    al, 0fdh

    ; enable keyboard interrupt
      in     al, 21h
      and    al, 0fdh
      out    21h, al

      sti
      mov   ax, 4c00h
      int   21h
    main endp


    ;-----------------------------------------------------
    ; Interrupt Handler kbd
    ;  Purpose: fill buffer until full when substituted for interrupt 09h
      kbdint proc near
      push   ax            ; save registers

      push   bx

      cld                ;direction: forward
      in    al, 60h         ;read a character
      push   ax            ;save it
      in    al, 61h          ;get the control port
      mov    ah, al          ;save the value in ah
      or    al, 80h          ;reset bits for kbd
      out    61h, al         ;send out
      xchg   ah, al          ;restore control value
      out    61h, al          ;kdb has been reset

      pop   ax            ;restore scan code
      test   al, 80h          ;press or release?
      jnz    return1         ;ignore when release

      mov    bx, buf_p        ;bx<=buffer pointer
      mov    [bx], al         ;store in buffer
      call   display_hex        ;display in hex
      inc    bx            ;move pointer
      inc    count          ;count characters
      mov    buf_p, bx        ;save the pointer

    check:
      cmp    count, 20h ;judge whether full
      jb    return1
      in    al, 21h
      or    al, 02          ;mask kdb bits
      and   al, 7fh         ;enable prt bits
      out   21h, al
      call   init_prt         ;initiate printer

    return1:
      cli
      mov   al, 20h         ;end of interrupt
      out    20h, al

    ;restore registers
      pop   bx
      pop   ax
      iret               ;interrupt return
    kbdint endp

    ;------------------------------------------------------------------------

    ; Interrupt Handler prtint
    ; Purpose: print characters when substituted for interrupt 0fh
      prtint proc near
      push   ax            ;save registers
      push   bx
      push   dx

      mov    bx, buf_p        ;bx<=buffer pointer
      mov    al, [bx]         ;get from buffer
      mov    dx, 378h         ;printer data port
      out    dx, al          ;output a character

      push   ax            ;save ax
      mov    dx, 37ah         ;printer control port
      mov    al, 1dh          ;al<=control code
      out    dx, al          ;send out
      jmp    $+2           ;slight delay
      mov    al, 1ch          ;al<=control code
      out    dx, al          ;send out
      pop    ax            ;restore ax

      inc    bx            ;move pointer
      mov    buf_p, bx        ;save the pointer
      cmp    al, 0ah         ;end of message?
      jnz    return2
      in     al, 21h         ;disable printer
      or    al, 80h         ; interrupt
      out    21h, al

    return2:
      mov    al, 20h         ;end of interrupt
      out    20h, al

      pop    dx            ;restore registers
      pop    bx
      pop    ax
      iret                ;interrupt return
    prtint endp

    ;------------------------------------------------------------------------

    ; Procedure init_prt
      init_prt proc near
      push    ax            ;save registers
      push   bx
      push   dx

      cli
      lea    bx, full_msg       ;bx<=offset of full_msg
      mov    buf_p, bx         ;save full_msg address

      mov    dx, 378h         ;printer data port
      mov    al, 0dh         ;CR
      out    dx, al          ;output a character

      mov    dx, 37ah         ;printer control port
      mov    al, 1dh         ;al<=control code
      out    dx, al          ;send out
      jmp    $+2            ;slight delay
      mov    al, 1ch          ;al<=control code
      out    dx, al          ;send out

      pop    dx            ;restore registers
      pop    bx
      pop    ax

      ret
    init_prt endp
    ;------------------------------------------------------------------------


    display_hex proc   near       ;display char with hex
        push     ax 
        push     cx
        push     dx
        mov     ch, 2       ;number of digits
        mov      cl, 4
    nextb:
        rol      al, cl      ;highest of bits to lowest
        push     ax
        mov     dl, al
        and     dl, 0fh     ;mask off left digit

       or      dl, 30h     ;convert to ASCII
        cmp     dl, 3ah
        jl      dispit
        add      dl,7h       ;digit is A to F

    dispit:
        mov      ah, 2       ;display character
        int     21h
        pop     ax
        dec      ch        ;done 2 digits?
        jnz      nextb      ;not yet
        mov      ah, 2
        mov     dl,','      ;display ','
        int      21h
        pop      dx
        pop     cx
        pop      ax
        ret              ;return from display_hex
    display_hex endp

    ;------------------------------------------------------------------------
        end start



    例8.7 除数为0时的软件中断(类型0)处理程序
      此程序分成两个主要部分:初始化部分和中断处理部分。


      初始化部分(Init)设置新的0型中断向量,显示一条信息,然后完成终止和驻留后退出程序。这种特殊的退出是用INT 21H的功能31H,它将保留程序所占的内存,从而使这些内存单元不被以后的应用程序破坏。

      中断处理程序(Zdiv)在发生一个被零除中断时接收控制。中断处理程序先保存有关寄存器的值,然后打印出信息询问用户是退出程序(Quit)还是继 续(Continue)。若键入"C"要求继续执行程序,则处理程序恢复所有寄存器并执行IRET返回主程序(显示一个标记符#),当然此时除法的操作结 果应是无效的。若键入"Q"要求退出,则从处理程序直接返回DOS(无标记符显示)。这里返回DOS,是用INT 21H的功能4CH,该功能是唯一不依赖于任何段寄存器内容的终止功能,例如,CS寄存器不必指向PSP所在的段。该功能的另一个优点是能在AL中返回一 个表明程序是否正常终止的出口代码。系统出口代码的含义为:00 - 正常终止;01 - 用Ctrl-C终止;02 - 严重设备错误引起终止;03 - 用功能调用31H终止。左侧是处理除数为0错误的中断处理程序清单。

    Purpose: zero_division handler  
      ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      ;eg8-7.asm
      ;Purpose: zero_division handler
      ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


         .model small
    ;-------------------------------------------------------------------------
         .stack
    ;-------------------------------------------------------------------------
         .code
    ; Main program
    main    proc   near
    ;reset  interrupt  vector 0
          lea   dx, zdiv    ;set interrupt vector
          mov   ax, seg zdiv
          mov   ds, ax
          mov   al, 0     ;interrupt number
          mov   ah, 25h     ;to reset interrupt vector
          int   21h       ;call DOS

    ;print introduction message
          mov   ax, @code    ;ds<=code segment
          mov   ds, ax
          mov   dx, ok_msg   ;print introduction
          mov   ah, 9
          int   21h

    ;simulate zero_division condition
          mov   ax, 1
          mov   dl, 0
          div   dl

    ; display '# 'after return from interrupt handler zdiv
          mov   ah, 2      ;to display a character
          mov   dl, '#'     ;dl<='#'
          int   21h       ;call DOS

    ;exit and reside in memory
          mov   ah, 31h     ;to exit and reside
          mov   al, 0     ;return code: 0
          mov   dx, ((prog_len+15)/16)+16   ;dx<=memory paragraph

    ; for residence
          int   21h      ;call DOS
    main endp





    ;-------------------------------------------------------------------------
    ; Interrupt Handler zdiv
    zdiv   proc   far
         push   ax    ;save registers
         push   bx
         push   cx
         push   dx
         push   si
         push   di
         push   bp
         push   ds
         push   es
         sti

    prt_warn:
         mov   ax, @code
         mov   ds, ax
         mov   dx, offset warn_msg   ;print warning
         mov   ah, 9
         int   21h


    input:
         mov   ah, 1           ;to accept keyboard input
         int    21h           ;call DOS
         cmp    al, 'c'          ;judge whether 'c'
         je    continue
         cmp    al, 'q'         ;judege whether 'q'
         je    exit

         mov    dx, offset beep      ;beep when illegal input
         mov    ah, 09
         int    21h
         jmp   prt_warn


    exit:
         mov    ax, 4cffh
         int    21h
    continue:
         mov    dx, offset crlf      ;print CR & LF
         mov    ah, 09
         int   21h
         cli


         pop    es            ;restore registers
         pop    ds
         pop    bp
         pop   di
         pop   si
         pop   dx
         pop   cx
         pop   bx
         pop    ax
         iret               ;interrupt return
    zdiv   endp

    ;------------------------------------------------------------------------

    ; Data area
    ok_msg  db 0dh, 0ah, 'Zero-division Handler installed!'
         db 0dh, 0ah, '$'
    warn_msg db 'Zero-division detected, ', 07h
         db 'Continue or Quit(c/q)?$'
    beep   db 07h, '$'
    crlf   db 0dh, 0ah, '$'
    prog_len equ $-main


    ;------------------------------------------------------------------------
         end main

    【本章小结】

     
    1. 程序直接控制I/O的方式:
      这是一种使用I/O指令直接在端口级上进行数据传送的编程方式,这种方式有时需要查询外设的状态,如果外设处于准备好或空闲状态,则CPU通过接口中 的数据寄存器进行输入或输出,如果外设没有准备好或是忙状态,CPU就查询等待,不再作有效的工作。

      2. 中断程序的设计方法:
      对于要求以中断方式工作的I/O设备,它们的中断类型已由硬件连线确定(如图8.3)。主程序为中断所做的准备工作如下:
      (1) 保存原中断向量(INT 21H的35H功能),设置新的中断向量(INT 21H的25H功能);
      (2) 设置设备的中断屏蔽位(仅对可屏蔽中断);
      (3) 设置CPU的中断允许位(开中断);
      (4) 在主程序结束前,恢复原中断向量。

      主程序完成了上述准备工作后,I/O设备即以完全随机的方式产生中断。当CPU响应了中断请求,中断系统将自动完成以下工作:
      (1) CPU接收外设的中断类型号;
      (2) 当前的FLAGS、CS、IP的内容入栈保存;
      (3) 清除IF、TF;
      (4) 根据中断类型号取出中断向量送CS和IP;
      (5) 转中断处理子程序。

      中断处理子程序的编写方法:
      (1)保存工作寄存器内容;
      (2)如允许中断嵌套,则开中断(STI);
      (3)处理中断任务;
      (4)关中断 (CLI);
      (5)送中断结束命令(EOI)给中断命令寄存器(仅对硬件中断);
      (6)恢复工作寄存器内容;
      (7)返回被中断的程序(IRET)。

    <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
    阅读(1458) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~
    评论热议
    展开全文
  • 计算机中断机制

    千次阅读 2018-01-26 15:07:21
    前一阵子忽然蛋疼菊紧,对计算机硬件的工作原理产生了些许兴趣。故查阅了一些资料,加上本人的总结和理解(以及猜测),为园友先奉上一文如下。 附:本文仅对CPU中断技术进行理论上的剖析,而没有针对中断技术的实现...
    
    

    前一阵子忽然蛋疼菊紧,对计算机硬件的工作原理产生了些许兴趣。故查阅了一些资料,加上本人的总结和理解(以及猜测),为园友先奉上一文如下。

    附:本文仅对CPU中断技术进行理论上的剖析,而没有针对中断技术的实现进行分析。

     

    Ready Go

     

    目录

    一、什么是CPU中断?

    二、CPU中断的作用

    三、CPU中断的类型

    四、CPU中断的过程

    五、多核CPU对中断的处理

     

    一、什么是CPU中断?

      使用计算机的过程中,经常会遇到这么一种情景:

      1. 你正在看电影

      2. 你的朋友发来一条QQ信息

      3. 你一边回复朋友的信息,一边继续看电影

            

      这个过程中,一切是那么的顺其自然。但理论上来说,播放电影的时候,CPU正在一丝不苟的执行着一条又一条的指令,它是如何在维持电影播放的情况下,及时接收并响应你的键盘输入信息呢?

     

      这就是CPU中断技术在起作用。

          

           CPU中断技术的定义如下:

    1. 计算机处于执行期间
    2. 系统内发生了非寻常或非预期的急需处理事件
    3. CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序
    4. 处理完毕后返回原来被中断处继续执行

     

      在这里,“非寻常或非预期的事件”指的就是你回复朋友的QQ时,用键盘键入信息。为了及时响应你键入的信息,CPU将正在执行的任务“播放电影”暂时中断,处理完你键入的信息后,继续执行“播放电影”的任务。由于这个“中断当前任务->响应键盘输入->继续当前任务”的执行周期非常短(一般都是微秒级),所以一般人感觉不出来。

            

      举个现实中的例子:

      你正在看书,突然你的朋友打来电话,于是你放下书本去接电话,电话打完接着看书。

      电话响->放下书本->接电话->继续看书这一个过程,就类似于CPU中断的处理过程。

     

    二、CPU中断的作用

      早期的CPU处理外设的事件(比如接收键盘输入),往往采用“轮询”的方式。即CPU像个查岗的一样轮番对外设顺序访问,比如它先看看键盘有没被按下,有的话就处理,没的话继续往下看鼠标有没有移动,再看看打印机……这种方式使CPU的执行效率很低,且CPU与外设不能同时工作(因为要等待CPU来“巡查”)。

     

      中断模式时就是说CPU不主动访问这些设备,只管处理自己的任务。如果有设备要与CPU联系,或要CPU处理一些事情,它会给CPU发一个中断请求信号。这时CPU就会放下正在进行的工作而去处理这个外设的请求。处理完中断后,CPU返回去继续执行中断以前的工作。

     

       中断模式的作用和优点在于:

      1. 可以使CPU和外设同时工作,使系统可以及时地响应外部事件。

      2. 可允许多个外设同时工作,大大提高了CPU的利用率,也提高了数据输入、输出的速度。

      3. 可以使CPU及时处理各种软硬件故障(比如计算机在运行过程中,出现了难以预料的情况或一些故障,如电源掉电、存储出错、运算溢出等等。计算机可以利用中断系统自行处理,而不必停机或报告工作人员。)

     

    三、CPU中断的类型

      在计算机系统中,根据中断源的不同,通常将中断分为两大类:

      1. 硬件中断

      2. 软件中断

            

      硬件中断

      硬件中断又称外部中断,主要分为两种:可屏蔽中断、非屏蔽中断。

            

      可屏蔽中断:

      1. 常由计算机的外设或一些接口功能产生,如键盘、打印机、串行口等

      2. 这种类型的中断可以在CPU要处理其它紧急操作时,被软件屏蔽或忽略

     

      非屏蔽中断:

      1. 由意外事件导致,如电源断电、内存校验错误等

      2. 对于这种类型的中断事件,无法通过软件进行屏蔽,CPU必须无条件响应

     

      在x86架构的处理器中,CPU的中断控制器由两根引脚(INTRNMI)接收外部中断请求信号。其中:

      1. INTR接收可屏蔽中断请求

      2. NMI接收非屏蔽中断请求

     

      典型事例:

      1. 典型的可屏蔽中断的例子是打印机中断,CPU对打印机中断请求的响应可以快一些,也可以慢一些,因为让打印机稍等待一会也是完全合理的。

      2. 典型的非屏蔽中断的例子是电源断电,一旦出现此中断请求,必须立即无条件地响应,否则进行其他任何工作都是没有意义的。

     

      软件中断

      软件中断又称内部中断,是指在程序中调用INTR中断指令引起的中断。比如winAPI中,keybd_eventmouse_event两个函数,就是用来模拟键盘和鼠标的输入(这个仅为笔者本人的猜测)。

     

    四、CPU中断的过程

      中断请求

      中断请求是由中断源向CPU发出中断请求信号。外部设备发出中断请求信号要具备以下两个条件:

      1. 外部设备的工作已经告一段落。例如输入设备只有在启动后,将要输入的数据送到接口电路的数据寄存器(即准备好要输入的数据)之后,才可以向CPU发出中断请求。

      2. 系统允许该外设发出中断请求。如果系统不允许该外设发出中断请求,可以将这个外设的请求屏蔽。当这个外设中断请求被屏蔽,虽然这个外设准备工作已经完成,也不能发出中断请求。

            

      中断响应、处理和返回

      当满足了中断的条件后,CPU就会响应中断,转入中断程序处理。具体的工作过程如下:

      1. 关闭中断信号接收器

      2. 保存现场(context)

      3. 给出中断入口,转入相应的中断服务程序

      4. 处理完成,返回并恢复现场(context)

      5. 开启中断信号接收器

     

      中断排队和中断判优

      1. 中断申请是随机的,有时会出现多个中断源同时提出中断申请。

      2. CPU每次只能响应一个中断源的请求。

      3. CPU不可能对所有中断请求一视同仁,它会根据各中断源工作性质的轻重缓急,预先安排一个优先级顺序。当多个中断源同时申请中断时,即按此优先级顺序进行排队,等候CPU处理。

     

      了解了CPU中断处理的过程,就不难理解下面一种常见的情景:

      正在拷贝文件时,往某个文本框输入信息,这个文本框会出现短暂的假死,键盘输入的数据不能及时显示在文本框中,需要等一会儿才能逐渐显示出来。

     

      这是因为该中断操作(往文本框输入信息)在中断队列的优先级比较低,或者CPU认为正在处理的操作(拷贝文件)进行挂起的代价太大,所以只有等到CPU到了一个挂起代价较低的点,才会挂起当前操作,处理本次中断信息。

     

    五、多核CPU对中断的处理

      多核CPU的中断处理和单核有很大不同。多核的各处理器核心之间需要通过中断方式进行通信,所以CPU芯片内部既有各处理器核心的本地中断控制器,又有负责仲裁各核之间中断分配的全局中断控制器。

     

      现今的多核处理器在中断处理和中断控制方面主要使用的是APIC(Advanced Programmable Interrupt Controllers),即高级编程中断控制器。它是基于中断控制器两个基础功能单元——本地单元以及I/O单元的分布式体系结构。在多核系统中,多个本地和I/O APIC单元能够作为一个整体通过APIC总线互相操作。

     

      APIC的功能有:

      1. 接受来自处理器中断引脚的内部或外部I/O APIC的中断,然后将这些中断发送给处理器核心进行处理

      2. 在多核处理器系统中,接收和发送核内中断消息

     

      对于外部设备发出的中断请求,由全局中断控制器接收请求并决定交给CPU的哪一个核心处理。也可针对APIC编程,让所有的中断都被一个固定的CPU处理。


    转自http://www.cnblogs.com/funeral/archive/2013/03/06/2945485.html

    展开全文
  • 中断详解

    千次阅读 2018-10-24 01:28:04
    1.中断的基本概念 程序中断是指在计算机执行现行程序的过场中,出现某些急需处理的异常情况或特殊请求,CPU暂停中断现行程序,而专区对这些异常情况或特殊情况进行处理,在处理完毕后CPU又自动返回到现行程序的断点...

    1.中断的基本概念

    程序中断是指在计算机执行现行程序的过场中,出现某些急需处理的异常情况或特殊请求,CPU暂停中断现行程序,而专区对这些异常情况或特殊情况进行处理,在处理完毕后CPU又自动返回到现行程序的断点处,继续执行原程序。

    程序中断的作用如下:
    ①实现CPU与I/O设备的并行工作。

    ②处理硬件故障和软件错误。

    ③实现人机交互,用户干预机器需要用到中断系统。

    ④实现多道程序、分时操作,多道程序的切换需要借助于中断系统。

    ⑤实时处理需要借助中断系统来实现快速响应。

    ⑥实现应用程序和操作系统(管态程序)的切换,称为“软中断”。

    ⑦多处理系统中各处理器之间的信息交流和任务切换。

    思想:CPU在程序中安排好某一时刻启动某一台外设,然后CPU继续执行原来程序,不需要像查询方式那样一直等待外设准备就绪。一旦外设完成数据传送的准备工作,便主动向CPU发送中断请求,请求CPU为自己服务。在可以相应中断的条件下,CPU暂停终止正在执行的程序,转去执行中断服务程序为外设服务,在中断服务程序中完成一次主机与外设之间的数据传送,传送完成后,CPU返回原来的程序。

    2.程序中断工作流程

    (1)中断请求

    中断请求是指中断源向CPU发送中断请求信号。

    ①内中断和外中断

    中断源是请求CPU中断的设备或事件,一台计算机允许有多个中断源。根据中断源的类别,可把中断源分为内中断和外中断两种。

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

    外中断是指来自处理器和内存以外的部件引起的中断,包括I/O设备发出的I/O中断、外部信号中断(如用户按键),以及各种计时器引起的时钟中断等。外中断在狭义上一般被称为中断。

    内中断主要指在处理器和内存内部产生的中断。包括程序运算引起的各种错误,如地址非法、检验错、页面失效、存储访问控制错、算术操作溢出、数据格式非法、除数为0、非法指令、用户程序执行特权指令、分时操作系统中的时间片中断以及用户态到核心态的切换等。

    ②硬件中断和软件中断

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

    软件中断:通过某条指令产生的中断。这种中断可以编程实现,软件中断属于内中断。

    ③非屏蔽中断和可屏蔽中断(全是外中断)

    非屏蔽中断:非屏蔽中断是一种硬件中断,此种中断通过不可屏蔽中断请求NMI控制,不受中断标志位IF的影响,即使关中断(IF=0)的情况下也会被响应。

    可屏蔽中断:可屏蔽中断也是一种硬件中断,此种中断通过中断请求标记触发器INTR控制,且受中断标志位IF的影响,在关中断情况下不接受中断请求。

    (2)中断判优

    中断系统在任意瞬间只能响应一个中断源的请求,由于许多中断源提出中断请求的时间都是随机的,因此当多个中断源同时提出请求时,需通过中断判优逻辑确定哪个中断源的请求。如故障中断的优点级较高,然后是I/O中断。

    中断判优既可以用硬件实现,也可以用软件实现。硬件实现是通过硬件排队器实现的,它既可以设置在CPU中,也可以分散在各个中断源中,软件实现是通过查询程序实现的。

    一般来说,硬件故障中断属于最高级,其次是低速设备,输入设备优于输出设备,实时设备低于普通设备。

    (3)CPU响应中断的条件

    CPU在满足一定的条件下响应中断源发出的中断请求,并经过一些特定的操作,专区执行中断服务程序。

    条件:

    ①中断源有中断请求。

    ②CPU允许中断及开中断。

    ③一条指令执行完毕,没有更紧迫的任务。

    注意:I/O设备的就绪时间是随机的,而CPU是在统一的时刻即每条指令执行阶段结束前后,接口发出中断查询信号,以获取I/O的中断请求,也就是说,CPI响应中断的时间是在每条执行阶段的结束时刻。这里说的中断仅指外中断,内中断不属于此类情况。

    (4)中断隐指令

    CPU响应中断后,经过某些操作,转去执行中断服务程序。这些操作是由硬件直接实现的,把它称为中断隐指令。中断隐指令并不是指令系统中的一条真正的指令,它没有操作码。所以中断隐指令是一种不允许、也不可能为用户使用的特殊指令。它完成的操作是:
    ①关中断。在中断服务程序中,为了保护中断现场(即CPU主要寄存器的内容)期间不被新的中断所打断,必须关中断,从而保证被中断的程序在中断程序服务程序完毕之后能接着正确地执行下去。

    ②保存断点。为了保证在中断服务程序执行完毕后能正确地返回到原来的程序,必须将原来程序的断点(即程序计数器(PC)的内容)保存起来。

    ③引出中断服务程序。取出中断服务程序的入口地址(中断向量)并传送给程序计数器(PC).

    (5)中断向量

    不同的设备有不同的中断服务程序,每个中断服务程序都有一个入口地址,CPU必须找到这个入口地址,即中断向量,把系统的全部中断向量存放到存储器的某一区域内,这个存放中断向量的存储区就叫中断向量表,即中断服务程序入口地址表。

    当CPU响应中断后,中断硬件会自动将中断向量地址传动到CPU,由CPU实现程序的切换,这种方法称为中断向量法,采用中断向量法的中断称为向量中断。

    注意:中断向量是中断服务程序的入口地址,中断向量地址是指中断服务程序的入口地址的地址。

    (6)中断处理过程

    ①关中断。

    处理器响应中断后,首先要保护程序的现场状态,在保护现场过程张,CPU不应该响应更高级中断源的中断请求。否则,如果现场保存不完整,在中断服务程序结束后,就不能正确地恢复并继续执行现行程序。

    ②保存断点。为了保证中断服务程序执行完毕后正确地返回到原来的程序,必须将原来程序的断点保存起来。断点可以压入堆栈,也可以存入主存的特定单元中。

    ③引出中断服务程序。取出中断服务程序的入口地址(中断向量)并传送给程序计数器(PC).

    通常由两种方法寻址中断服务程序的入口地址:硬件向量法和软件查询法。

    硬件向量法是通过引荐产生中断向量地址,再由中断向量地址找到中断服务的入口地址,软件查询法是用软件编程的办法找到入口地址。

    注意:硬件产生的实际是中断类型号。而中断服务程序后首先要保存现场,现场信息一般指的是程序状态字、中断屏蔽寄存器和CPU中某些寄存器的内容。

    ④保护现场和屏蔽字。进入中断服务程序后首先要保存现场,现场信息一般指的是程序状态字,中断屏蔽寄存器和CPU中某些寄存器的内容。

    ⑤开中断。这将允许更高级中断请求得到响应,实现中断嵌套。

    ⑥执行中断服务程序。这是中断系统的核心。

    ⑦关中断。保证在恢复现场和屏蔽字时不被中断。

    ⑧恢复现场和屏蔽字。将现场和屏蔽字恢复到原来的状态。

    ⑨开中断、中断返回。中断服务程序的最后一条指令通常是一条中断返回指令,使其返回到源程序的断点处,以便继续执行远程序。

    其中,①-③在CPU进入中断周期后,由中断隐指令(硬件自动)完成;④-⑨由中断服务程序完成。

    注意:恢复现场是指在中断返回前,必须将寄存器的内容恢复到中断处理前的状态,这部分工作由中断服务程序完成,中断返回由中断服务程序的最后一条中断返回指令完成。

    3.多重中断和中断屏蔽技术

    如果CPU在执行中断服务程序的过程中,又出现了新的更高的优先级的中断请求,而CPU对新的中断请求不予响应,这种中断为单重中断。

    如果CPU在执行现行的中断服务程序,转去处理新的中断请求,这种中断为多重中断,又称中断嵌套。

    中断屏蔽技术主要用于多重中断,CPU要具备多重中断的功能,必须满足下列条件。

    ①在中断服务程序中提前设置开中断指令。

    ②优先级别高的中断源有权中断优先级别低的中断源。每个中断源都有一个屏蔽触发器1表示屏蔽该中断源的请求,0表示可以正常申请,所有屏蔽触发器组合在一起,便构成一个屏蔽字寄存器,屏蔽字寄存器的内容称为屏蔽字。

    牢记中断处理过程:
    1.关中断(在此中断处理完成前,不处理其它中断)
    2.保护现场
    3.执行中断服务程序
    4.恢复现场
    5.开中断

    展开全文
  • 中断响应时间/中断步骤/中断

    千次阅读 2017-06-29 10:10:32
    中断的响应时间就是中断的响应过程的时间,中断的响应过程是当有事件产生,进入中断之前必须先记住当前正在做的事情,然后去处理发生的事情,处理这个过程的时间,叫做中断响应时间。  计算机中也是采用的这种方法...
  • linux中断--LINUX中断机制与信号

    千次阅读 2013-09-22 21:49:13
    在学习APUE时学习信号编程,很多地方不是理解,便查阅了网络上的相关资料,最常见的一句话就是“信号是中断机制的一种模拟”,...定义:中断是由其他硬件设备依照CPU时钟周期信号随机产生的。 分类: 可屏蔽中断 非可
  • cpu的中断响应时间

    万次阅读 2016-05-05 10:47:58
    从发出中断请求到进入中断处理所用的时间 计算机中CPU的中断响应时间指的是()的时间。 A.从发出中斯请求到中断处理结束 B.从中断处理开始到中断处理结束 C....取指周期结束 D.程序执行结束
  • 中断向量,中断向量表 ,中断服务函数

    千次阅读 多人点赞 2019-07-29 12:31:52
    所谓中断是指CPU在正常执行程序的过程中,由于内部/外部事件的触发或由程序的预先安排,引起CPU暂时中断当前正在运行的程序,而转去执行为内部/外部事件或程序预先安排的事件的服务子程序,待中断服务子程序执行完毕...
  • 中断的作用

    万次阅读 2018-05-15 10:31:36
    计算机更是如此,依靠时钟发生器,人为的设置没几个时钟周期做一个任务,不管是否做完,一旦规定的时间到了,那么就要强制“中断”,以作下一个任务……就这样,直道所有的任务都作过了(但不一定都做完毕),再接着做...
  • 中断线程

    千次阅读 2016-09-12 16:59:03
    中断线程 线程的thread.interrupt()方法是中断线程,将会设置该线程为中断状态,即设置为true。线程中断后的结果是死亡、还是等待新的任务或是继续运行至下一步,取决于这个程序本身。线程会不时地检测这个中断标识...
  • 7.4.2 程序中断方式

    千次阅读 2016-09-22 17:21:05
    1.中断的基本概念 程序中断是指在计算机执行现行程序的过场中,出现某些急需处理的异常情况或特殊请求,CPU暂停中断现行程序,而专区对这些异常情况或特殊情况进行处理,在处理完毕后CPU又自动返回到现行程序的断点...
  • 中断处理

    千次阅读 2012-05-07 20:29:02
    16. 中断处理 上一页    ...16. 中断处理 ...对于中断和异常的定义在ULK中的第4章中给予...同步中断是党指令执行时由CPU控制单元产生的,之所以称为同步,是因为只有在一条指令中止执行后CPU才会发出中断。 异步中
  • 所谓中断是指CPU在正常执行程序的过程中,由于内部/外部事件的触发或由程序的预先安排,引起CPU暂时中断当前正在运行的程序,而转去执行为内部/外部事件或程序预先安排的事件的服务子程序,待中断服务子程序执行完毕...
  • 中断程序

    千次阅读 2016-08-24 16:31:56
    前段时间用STM32F103VBT6写了一个中断的函数,借此机会想了解下STM32的中断机制,用过之后发现STM32的中断配置相当灵活,稳定行很高,测试发现几乎没出过什么差错。我在程序里开了三个中断,一个计数器用于精确延时...
  • 中断

    千次阅读 2013-12-19 16:41:01
    中断一般是指由指令int引起的“伪”中断动作——给CPU制造一个中断的假象;而硬中断则是实实在在由8259的连线触发的中断。因此,严格的讲,int与IRQ毫无关系,但二者均与中断向量有关系。int引起的中断,CPU是从...
  • 51单片机的定时中断(三)

    千次阅读 多人点赞 2018-12-02 09:49:32
    前言:单片机的中断系统(一) 图片和内容来自普中科技的ppt。 相关知识: 周期: 振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期) 状态周期:2个振荡周期为1个状态周期,用S表示。...
  • linux 中断

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

    千次阅读 2016-11-28 18:30:20
    dsp28335一个有16个中短线 RESET,NMI---------不可屏蔽中断   INT1~INT12-----------每组中断线有8个中断。例:INT1.1,INT12.8 INT13-------------------定时器1中短线 (当XNMI.SELECT=0时,nmi复用INT13) ...
  • 51单片机定时器中断实验

    千次阅读 2020-08-04 10:52:08
    附:中断基本概念 定时器相关内容 CPU时序的有关知识 ①振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)。 ②状态周期:2 个振荡周期为 1 个状态周期,用 S 表示。振荡周期又称 S 周期或...
  • 线程中断详解

    万次阅读 多人点赞 2018-07-05 19:01:44
    中断线程线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示...
  • 定时器中断

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

    千次阅读 2014-03-31 17:16:51
    C51中断(void timer1(void) interrupt 3 using 3) 2013-11-13 20:29:30 分类: 嵌入式 原文:http://blog.sina.com.cn/s/blog_6ad38fb60100leam.html interrupt 表示中断优先级,using表示...
  • ARM中断

    千次阅读 2014-08-17 16:08:40
    S3C2440系统中断 分类: ARM体系结构 2011-06-20 14:17 196人阅读评论(0) 收藏举报 1.1 S3C2440系统中断 CPU和外设构成了计算机系统,CPU和外设之间通过总线进行连接,用于数据通信和控制,CPU管理监视...
  • RTC实现功能 RTC开节拍中断、闹钟中断。 节拍中断——串口输出时间 XXXX年XX月XX日XX时XX分XX秒 和 LED闪亮 闹钟中断——beep声 和 LED亮 5秒
  • 【操作系统】系统中断技术

    千次阅读 2017-11-21 20:04:28
    二、CPU中断的作用三、CPU中断的类型四、CPU中断的过程五、多核CPU对中断的处理一、什么是CPU中断? 使用计算机的过程中,经常会遇到这么一种情景: 1. 你正在看电影 2. 你的朋友发来一条QQ信息 3. 你一边回复...
  • 单片机之中断

    千次阅读 2021-01-07 19:26:31
    中断的概念 日常生活的中断现象举例 中断是指在突发事件到来时先中止当前正在进行的工作,转而去处理突发事件。待处理完成后,再返回到原先被中止的工作处,继续进行随后的工作。 中断的一般概念 中断响应过程...
  • 本周的学习内容主要是PWM,外部中断和定时器中断,了解了PWM的基本功能以及外部中断,定时器中断的执行过程.     一·PWM 1.PWM一般是指脉冲宽度调制,通过PWM功能就能调节输出电压。     2.占空比指的是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,810
精华内容 19,124
关键字:

中断周期的产生条件