在学习STM32的中断时,总是能够看到两个单词:异常(exception)和中断(Interrupt)。这两者有什么区别呢?
异常和中断主要有二个不同点。
区别一 产生位置的不同
由内核产生的称之为异常,而外设产生的称为中断。
我们可以从下图中的IRQ number中看出两者的区别。IRQ number < 0的都是内核的异常,其中就包括我们常见的systick和操作系统常用的PendSV异常。而IRQ number >= 0 的则是中断,由外设产生。
那么内核和外设都指的是什么呢?以STM32F103为例,其使用的是ARM Cortex-M3内核,然后ST公司以内核为基础添加了多种外设,如USART, SPI, TIMER, I2C等。
区别二 管理位置的不同
在管理上异常和中断也有区别。异常是由内核产生的,也是由内核的模块进行管理,管理内核的模块称为System control block,简写为SCB。SCB中有多个寄存器管理内核异常的使能、优先级,并能查询异常的状态。但是NMI和HardFault这两个异常比较特别,这两个异常是一直使能的,并且优先级是固定的,为最高的2个优先级。其它的几个内核异常默认是不使能的,这个可以从寄存器的复位值中观察到。要想设置这几个内核异常的使能,则需要设置SCB中的System Handler Control and State Register寄存器。
而外设产生的中断是由NVIC进行管理的,NVIC可以控制其开关和优先级。
我们可以在ARM提供的库函数中看出对内核异常和外设中断设置上的区别(下面的函数在core_cm4.h中):
/**
\brief Set Interrupt Priority
\details Sets the priority of a device specific interrupt or a processor exception.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
\note The priority cannot be set for every processor exception.
*/
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else
{
SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
从上面的代码中可以看出IRQ number >= 0 的,设置的是NVIC中的寄存器,而 IRQ number < 0 的则是设置的SCB中的寄存器。
总结
以上就是异常和中断的区别。本质的区别在于产生中断的位置和管理这些中断的寄存器之间的区别。