如果中断请求没有立即执行,并且在确认之前被软件清除了,处理器将会忽略掉本次请求,并且不会执行中断处理。
如果在软件清除挂起状态时,外设仍然保持着中断请求,挂起状态寄存器还会立即生成。
03
中断等待
通常情况下,处理器的中断等待时间为16个周期,这个等待时间从中断确认的处理器
时钟周期开始,一直到中断处理开始执行结束。
计算中断等待需具备以下前提:
该中断使能并没有PRIMASK或者其他正在执行的异常处理所屏蔽
存储器系统没有任何等待状态,在中断处理、压栈、取向量表或者中断处理开始时取指都会用到总线
传输,如果
存储器系统需要等待,那么总线传输时产生的等待状态则可能使得中断延迟。
下面几种情况可能会导致不同的中断等待:
中断的咬尾连锁,如果一个中断返回时立即产生另外一个中断请求,处理器就会跳过出栈和压栈时间,减少了中断等待时间。
延迟到达,如果中断发生时,另外一个低优先级中断正在进行压栈处理,由于延迟到达,高优先级的中断就会立即执行,这样会导致高优先级的中断等待时间减少。
04
异常屏蔽寄存器PRIMASK
有些对时间敏感的应用,需要在短时间内禁止响应所有的中断,对于这种应用,处理器不是直接使用中断使能、禁止控制寄存器来禁止所有中断再恢复,而是一个单独的特殊寄存器 - PRIMASK,通过它可以屏蔽掉除了NMI和HardFault异常的其他的所有的中断和系统异常。
PRIMASK寄存器只有1位有效,并且在复位后默认为0。该寄存器为0时,所有的中断和异常都处于允许状态,设置为1后,只有NMI和HardFault处于使能状态。MOVS R0, #0x1 ; //中断#2
MSR PRIMASK , R0 ; //将R0的值送到PRIMASK
NVIC编程提示软件使用CPSIE i和CPSID i
指令来启用和禁用中断。CPSIE i ; //清除 PRIMASK(使能中断)
CPSID i ; //设置 PRIMASK(不响应中断)
CMSIS设备驱动库提供了C语言的实现函数,用户可以直接使用函数来设置和清除PRIMASK寄存器:void __disable_irq(void) //不响应中断
void __enable_irq(void) //启用中断
在对时间敏感的程序完成后,应该清除PRIMASK。要不然即使在中断处理中使用__disable_irq()函数,处理器将停止接受新的中断请求。主要原因是PRIMASK寄存器和Xpsr是相互独立的,因此异常返回不会影响中断屏蔽状态。
05
NVIC使用提示
确保软件使用正确对齐的寄存器访问,处理器不支持对 NVIC 寄存器的未对齐访问。
即使中断被禁用,它也可以进入挂起状态。
禁用中断只能防止处理器处理中断。
在对中断向量表重定义之前,必须包含所有的异常中断,例如 NMI、HardFault 和外设中断等。