一、前言
中断是什么?举个例子来说,当我们正在工作时,突然电话响了,这时你会把手里的工作先停下来,然后去接电话,当接完电话后,电话里的人安排你马上做一件事,这时你需要立刻去做这件事,当把这件事做完后你会继续之前被打断的工作,这个过程为一次中断。
在计算机科学中,中断指计算机CPU获知某些事,暂停正在执行的程序,转而去执行处理该事件的程序,当这段程序执行完毕后再继续执行之前的程序。整个过程称为中断处理,简称中断,而引起这一过程的事件称为中断事件。中断是计算机实现并发执行的关键,也是操作系统工作的根本。中断能提高CPU的效率,同时能对突发事件做出实时处理。实现程序的并行化,实现嵌入式系统进程之间的切换。
后续将从以下图1中所示的几个方面对STM32的中断系统进行基本的解析。
图1 中断系统学习框架
二、 基本原理概述
图2 基本原理概述
1、中断的作用
(1)速度匹配,提高机器系统效率。 系统中处理机的工作速度远高于外围设备的工作速度。通过中断可以协调它们之间的工作。当外围设备需要与处理机交换信息时,由外围设备向处理机发出中断请求,处理机及时响应并作相应处理。不交换信息时,处理机和外围设备处于各自独立的并行工作状态。
(2)分时操作,维持系统可靠正常工作。现代计算机中,程序员不能直接干预和操纵机器,必须通过中断系统向操作系统发出请求,由操作系统来实现人为干预。主存储器中往往有多道程序和各自的存储空间。在程序运行过程中,如出现越界访问,有可能引起程序混乱或相互破坏信息。为避免这类事件的发生,由存储管理部件进行监测,一旦发生越界访问,向处理机发出中断请求,处理机立即采取保护措施。
(3)实时响应,满足实时处理要求。 在实时系统中,各种监测和控制装置随机地向处理机发出中断请求,处理机随时响应并进行处理。
(4)提供故障现场处理手段,可靠性高。 处理机中设有各种故障检测和错误诊断的部件,一旦发现故障或错误,立即发出中断请求,进行故障现场记录和隔离,为进一步处理提供必要的依据。
2、中断和异常
ARM公司设计了如Cortex-M3或Cortex-M4内核,这个内核就包含了中断系统框架,ST公司根据该内核,因地制宜的设计了STM32系列产品。
CPU内核中断和核外外设中断,其中内核中断,在官方手册上,内核中断叫异常(exception)和核外外设中断才叫中断(interrupt),其实是一回事。
ARM Cortex M3内核支持256个中断,包括16个内核中断和240个外设中断,拥有256个中断优先级别。
◆Cortex-M4内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
◆STM32并没有使用Cortex-M4内核的全部东西,而是只用了它的一部分,中断数量及中断优先级也进行裁剪用了一部分。
◆STM32的每个外设都可以产生中断,如STM32F407系列一共有98个中断,包括16个内核中断和82个可屏蔽中断,具有16级可编程的中断优先级。
通常,把CPU内部产生的紧急事件叫做异常。异常通常是微处理器内部发生的,大多是软件引起的,比如比如非法指令(除零)、地址访问越界、特权调用异常等待。异常是指由于cpu本身故障、程序故障或者请求服务等引起的错误,异常属于不正常现象。
把来自CPU外部的片上外设产生的紧急事件叫做中断。中断是微处理器外部发送的,通过中断通道送入处理器内部,一般是硬件引起的,比如GPIO引脚电平变化、定时器溢出、串口接收中断等。中断是指系统停止当前正在运行的程序转而其他服务,可能是程序接收了比自身高优先级的请求,或者是人为设置中断,中断是属于正常现象。
不管是中断还是异常,异常与中断都是硬件支持的,微处理器通常都有相应的中断/异常服务程序,异常和中断的效果基本一致,都是暂停当前任务,优先执行紧急事件。
图3 异常和中断编号表
所有的异常和中断用一个表管理起来,编号为0~15 的称为内核异常(需要说明的是,16个编号的内核中断,但是STM32本身的内核中断是11个,还有5个是保留的没用的),而 16 以上的则称为核外(外部)中断(相对内核而言,对于不同系列的STM32,大致的编号和数量相同,但是对于高级的,因为片上外设要多一些,所以中断的数量也会多一些),这个表就称为中断向量表。这个中断向量表,这个中断向量表,本质上可以理解成一个4个字节类型Int的数组,每一个元素就是放的是对应编号的中,外部中断是我们必须学习掌握的知识,包含线中断,定时器中断,I2C,SPI等所有的外设中断,可配置优先级。
Reset( 复位)、NMI( Non Maskable Interrupt,不可屏蔽中断)、HardFault( 硬件异常)的优先级是固定的,且优先级是负数,也就是最高的(优先级数字越小,优先级越高)。剩下的异常或中断,都是可以通过修改NVIC的寄存器调整优先级( 但不能设置为负数)。NVIC作为在内核里的外设,也是通过存储器映射的方式访问。
3、NVIC中断控制器
有如此多的中断信号, CPU如何去控制它呢?内核有一个专门管理中断的外设NVIC(嵌套向量中断控制器),可以实现低延迟的中断处理和晚到中断的高效处理,通过优先级控制中断的嵌套和调度来管理;NVIC是一个总的中断控制器,无论是来在内核的异常还是外设的外部中断, 都由NVIC统一进行管理。NVIC收到外设的中断请求,会将其中断请求发送给内核,内核收到NVIC的中断通知之后,就会去判断此时哪个中断发生,然后查找FLASH中断向量表去获取相应的中断处理函数。
它具有以下特征:
(1)支持嵌套和向量中断;
(2)自动保存和恢复处理器状态;
(3)动态改变优先级;
(4)简化的和确定的中断时间。
带来的优势:
(1)响应速度提高;
(2)标准化,统一管理。
图4 NVIC在芯片上的位置
4、中断的分类
中断按事件来源分类,可以分为外部中断和内部中断。中断事件来自于内核外部的被称为外部中断,来自于内核内部的则为内部中断。
进一步细分,外部中断还可分为可屏蔽中断(maskable interrupt)和不可屏蔽中断(non-maskable interrupt)两种,而内部中断按事件是否正常来划分可分为软中断和异常两种。
外部中断的中断事件来源于内核外部,必然是某个硬件产生的,所以外部中断又被称为硬件中断(hardware interrupt)。计算机的外部设备,如网卡、声卡、显卡等都能产生中断。外部设备的中断信号是通过两根信号线通知CPU的,一根是IRQ,另一根是NMI。CPU从IRQ收到的中断信号都是不影响系统运行的,CPU可以选择屏蔽(通过设置中断屏蔽寄存器中的IF位),而从NMI中收到的中断信号则是影响系统运行的严重错误,不可屏蔽,因为屏蔽的意义不大,系统已经无法运行。
内部中断来自于内核内部,其中软中断是由软件主动发起的中断,常被用于系统调用(system call),任务切换(PendSV)等;而异常则是指令执行期间CPU内部产生的错误引起的。异常也和不可屏蔽中断区别在于不可屏蔽中断发生的事件会导致处理器无法运行(如断电、电源故障等),而异常则是影响系统正常运行的中断(如除0、越界访问等)。
三、 中断管理机制
图5 中断管理机制要素
1、中断向量
由于CPU随时都可能检测到中断信息,也就是说,CPU 随时都可能执行中断处理程序,所以中断处理程序必须一直存储在内存某段空间之中。中断处理程序在内存中的入口地址称为中断向量;而要确定中断处理程序的入口地址,处理器利用了一种向量表机制:即中断向量,必须存储在对应的中断向量表表项中。采用向量表处理中断,处理器会从存储器的向量表中,自动定位中断的程序入口。从发生中断到中断的处理中间的时间被缩减。
STM32的内部闪存地址起始于0x8000000,一般情况下,程序文件就从此地址开始写入。此外STM32其内部通过“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动。而这张“中断向量表”的起始地址是0x8000004,当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。
图6 中断向量执行
(1)STM32复位后,会从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序,如图6中标号①所示。
(2)复位中断服务程序执行的最终结果是跳转至C程序的main函数,如图6中标号②所示,而main函数应该是一个死循环,是一个永不返回的函数。
(3)在main函数执行的过程中,发生了一个中断请求,此时STM32的硬件机制会将PC指针强制指回中断向量表处,如图6中标号③所示。
(4)根据中断源进入相应的中断服务程序,如图6中标号④所示。
(5)中断服务程序执行完毕后,程序再度返回至main函数中执行,如图6中标号⑤所示。
2、中断优先级
中断优先级通过优先级配置寄存器进行配置,本寄存器宽度为8位,原则上每个中断可配置编程的优先级为0255,实际上可编程优先级的实际数量由芯片设计商决定,多数Cortex-M3或Cortex-M4芯片支持的优先级较少,这是因为大量的优先级会增加NVIC的复杂度,而且会增加功耗降低速度,多数情况下,应用程序只需要少量的编程优先级,因此芯片厂商需要基于目标应用的优先级数量设计处理器优先级,优先级的减少是通过去除优先级配置寄存器的低位实现,STM32只用到了中断优先级寄存器的的高4位。如图,使用到了bit7到bit4,最多可以配置016个中断优先级:
图7 4位优先级寄存器
这个4 位数字的位数分可以配成抢占优先级部分和响应优先级部分,因此可以有5组配置选择:
图8 中断优先级描述
优先级数值越小,优先级越高。
抢占优先级,是指打断其他中断的属性,即因为具有这个属性会出现嵌套中断,抢占优先级的概念等同于单片机中的常规中断。假设有两中断先后触发,已经在执行的中断抢占优先级如果没有后触发的中断抢占优先级更高,就会先处理抢占优先级高的中断。也就是说有较高的抢占优先级的中断可以打断抢占优先级较低的中断。
响应优先级也叫做亚优先级或者子优先级, 响应属性则应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断。
回到优先级上来。具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套在低抢占式优先级的中断中。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断向量表中的排位顺序决定先处理哪一个,中断向量表排在前面的中断优先级高。
看了上面的介绍后,相信大家都明白了这里面的关系了,总结下就是:抢占式优先级>响应优先级>中断表中的排位顺序。
3、中断嵌套
中断嵌套是指中断系统正在执行一个中断服务时,有另一个优先级更高的中断提出中断请求,这时会暂时终止当前正在执行的级别较低的中断源的服务程序,去处理级别更高的中断源,待处理完毕,再返回到被中断了的中断服务程序继续执行的过程。
在STM32中,只有抢占优先级才决定了中断嵌套。
如下图所示,抢占优先级高的任务出现后,会打断抢占优先级低的任务,即所谓的中断嵌套。例如:
图9 中断嵌套示意图
抢占优先级为N的中断任务正在运行,此时,抢占优先级为2的中断产生,则MCU会将抢占优先级为N的任务暂时停止,先响应执行中断优先级为2的任务,待该任务完成后,再来完成抢占优先级为N的任务。
若是抢占优先级为2的中断正在运行,又有新的抢占优先级为2的中断产生,则新产生的中断会等待当前中断任务完成后,再执行新产生的中断。
若是抢占优先级相同的任务同时产生,则响应优先级高的中断先执行。若是抢占优先级,响应优先级均相同的中断同时产生,则根据该中断在中断向量表的顺序来执行中断任务。
四、 中断处理流程
图10 中断处理流程
下图为中断处理流程示意图,可以概括性的将处理流程分为:进入中断、中断处理和退出中断。
图11 中断处理示意
进入中断:
(1)中断源发出请求,硬件判断处理器是否允许中断及该中断是否被屏蔽,若允许中断则当前运行的程序被打断;
(2)处理器将各寄存器的内容压入堆栈保存,主要是PC, xPSR, R0-R3, R12, LR寄存器;
(3)根据中断向量号,到中断向量表中找到中断服务程序的入口地址跳转执行。
中断处理:
(1)执行中断服务程序;
(2)遵循中断优先级和中断嵌套的执行规则。
退出中断:
(1)将保存在堆栈中的现场信息弹出到原来的寄存器中;
(2)返回被原先被中断的程序处继续执行。
五、总结
本篇主要是针对STM32的中断系统,目前从基本原理,中断管理机制,中断处理流程这几个方面对中断的基本特性和概念进行了较为详细的概述,目的是为了在以后STM32的中断使用中对中断的理解有较好的帮助,也可以看出NVIC在STM32中起到的作用。在下一篇将继续介绍中断系统基础知识之寄存器功能原理。