最近在使用STM32F3芯片的时候,遇到这样一个问题:如果外部中断来的频率足够快,上一个中断没有处理完成,新来的中断如何处理? 在调试时,发现有中断有 挂起、激活、失能等状态,考虑这些状态都是干啥用的呢!他们是Cortex-M核所共有的,因此这里不针对与具体用的STM32 MCU,直接上升到 Cortex-M内核来了解一下!
中断(也称为“异常”)是微控制器一个很常见的特性。中断一般是由硬件(例如外设、外部引脚)产生,当中断产生以后 CPU 就会中断当前的程序执行流程转而去处理中断服务中指定的操作。
所有的Cortex-M 内核都会系统一个用于中断处理的组件:NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器)。它处理处理中断,还处理其他需要服务的事件(例如 SVC 指令),通常称为“异常”。 按照 ARM 的说法,中断也是一种异常。
注意,本文所说的 Cortex-M 主要指定是 Cotex-M3和 Cotex-M4。
Cortex-M0、Cortex-M0+、Cortex-M1 基于 ARMv6-M。与Cotex-M3和 Cotex-M4相比,他们的指令集较小。而且,Cortex-M1 是专门为FPGA应用设计的,没有独立MCU。
Cortex-M 处理器的异常中,编号 1~15 的为系统异常,16及以上的则为中断输入。所有终端机部分系统异常都具有可编程的优先级。部分系统异常具有固定优先级。ARM给出了以下一张表:
类型 | 位置 | 优先级 | 描述 |
---|---|---|---|
- | 0 | - | 在复位时栈顶从向量表的第一个入口加载 |
Reset 复位 | 1 | -3(最高) | 在上电和热复位(warm reset)时调用,在第一条指令上优先级降到最低(线程模式),异步的 |
Non-maskable Interrupt 不可屏蔽中断(NMI) | 2 | -2 | 不能被除复位之外的任何异常停止或占先。异步的。 |
Hard Fault 硬故障 | 3 | -1 | 由于优先级的原因或可配置的故障处理被禁止而导致不能将故障激活时的所有类型故障,同步的 |
Memory Management 存储器管理 | 4 | 可配置 | MPU 不匹配,包括违反访问规范以及不匹配,是同步的,即使MPU 被禁止或不存在,也可以用它来支持默认的存储器映射的XN 区域 |
Bus Fault 总线故障 | 5 | 可配置 | 预取指故障,存储器故障,以及其它相关的地址/存储故障,精确时是同步,不精确时时异步 |
Usage Fault 使用故障 | 6 | 可配置 | 使用故障,例如,执行未定义的指令或尝试不合法的状态转换,是同步的 |
- | 7~10 | - | 保留 |
SVCall 系统服务调用 | 11 | 可配置 | 利用SVC 指令调用系统服务,是同步的 |
Debug Monitor 调试监控 | 12 | 可配置 | 调试监控,在处理器没有停止时出现,是同步的,但只有在使能时是有效的,如果它的优先级比当前有效的异常的优先级低,则不能被激活 |
- | 13 | - | 保留 |
PendSV 可挂起的系统服务请求 | 14 | 可配置 | 可挂起的系统服务请求,是异步的,只能由软件来实现挂起 |
SysTick 系统节拍定时器 | 15 | 可配置 | 系统节拍定时器(System tick timer)已启动,是异步的 |
External Interrupt 外部中断 | 16 及以上 | 可配置 | 在内核的外部产生(外部设备),INTISR[239:0],通过NVIC(设置优先级)输入,都是异步的 |
针对 Cortex-M 系列的内核,ARM 提供了一套叫做 CMSIS 的东西。目前,所有的MCU均使用CMSIS 作为编程基础。在 CMSIS-Core 中,中断标识有中断枚举实现,从数值 0 开始(代表中断#0)。其中,系统异常的编号为负数。具体如下:
当某种内部或外部事件发生时,MCU 的中断系统将迫使 CPU 暂停正在执行的程序,转而去进行中断事件的处理,中断处理完毕后,又返回被中断的程序处,继续执行下去。
主程序正在执行,当遇到中断请求(Interrupt Request)时,暂停主程序的执行转而去执行中断服务例程(Interrupt Service Routine,ISR),称为响应,中断服务例程执行完毕后返回到主程序断点处并继续执行主程序。多个中断是可以进行嵌套的。正在执行的较低优先级中断可以被较高优先级的中断所打断,在执行完高级中断后返回到低级中断里继续执行。
管理中断所使用的大部分寄存器都位于NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器)和SCB(System Control Block,系统控制块)中。实际上,SCB是作为NVIC的一部分来实现的,不过在CMSIS-Core中,将其定义在了独立的结构体中。除此之外,处理器内核中还有用于中断屏蔽寄存器:PRIMASK、FAULTMASK、BASEPRI。
NVIC和SCB位于系统控制空间,地址从0xE000E00开始,大小4KB。SCB中还有SysTick定时器,存储器保护单元等。
这部分暂且不说!
在Cortex-M内核中,每个中断都具有多个属性:
这些状态属性具有多种可能的组合。例如,在处理中断时,可以将其禁止,若在中断提出掐产生了同一个中断的新请求,由于该活跃中断被禁止了,那就会处于挂起状态。
NVIC在设计上既支持产生 脉冲中断请求 的外设,也支持产生 高电平中断请求 的外设。无需配置任何一个 NVIC 寄存器以选择其中一种中断类型。对于脉冲中断请求,脉冲宽度至少要为一个时钟周期;而对于电平触发的请求,在ISR中的操作清湖请求之前,请求服务的外设要一直保持电平信号(如写入寄存器以清除中断请求) 。尽管外部中断请求在 I/O 引脚上的电平可能是低电平有效,但是 NVIC 收到的额请求信号为高有效!
中断的挂起状态被存储在 NVIC 的可编程寄存器中,当 NVIC 的中断输入被确认后,它就会引发该中断的挂状态。即便中断请求被取消,挂起状态仍会为高。这样,NVIC 就可以处理脉冲中断请求了。
挂起状态的意思是,中断被置于一种等待处理器处理的状态。有些情况下,处理器在中断挂起时就会进行处理。不过,若处理器已经在处理另外一个更高或同优先级的中断,或者中断被某个中断屏蔽寄存器给屏蔽掉了,那么在其他的中观处理结束前或者中断屏蔽被清除前,挂起请求会一直保持。
当中断开始处理中断请求时,中断的请求信号会被自动清除。当中断正在被处理时,它就会处于活跃状态。
联系客服