中断处理的核心是中断向量表(IVT),它是一个存储中断服务例程(ISR)地址的内存结构。当中断发生时,MCU通过IVT找到对应的ISR地址并跳转执行。
本文将深入探讨MCU(以ARM Cortex-M架构为例)如何从向量表过渡到中断服务。
1
中断向量表
中断向量表(IVT)是一个存储中断和异常处理程序地址的表格,位于MCU的内存中。在ARM Cortex-M处理器中,IVT通常从地址0x00000000开始,包含初始堆栈指针和各种异常处理程序的地址。
每个表项占用4字节,存储一个32位地址,指向对应的ISR或异常处理函数。
IVT的作用是提供一种快速查找机制,使MCU在中断发生时能够迅速定位并执行相应的处理程序。例如,当定时器中断触发时,MCU会根据中断号从IVT中获取ISR地址。
以下是一个简化的IVT结构示例:
IVT通常存储在闪存(Flash)中,但可以通过向量表偏移寄存器(VTOR)将其重定位到其他内存区域(如SRAM),以支持动态更新或引导加载程序(Bootloader)场景。
ARM Cortex-M处理器通过嵌套向量中断控制器(NVIC)管理中断。以下是中断处理的具体步骤:
向量表通常在启动代码中定义,由工具链提供或由开发者编写。在C语言中,向量表可以定义为一个函数指针数组。例如:
void (* const vectors[])(void) __attribute__((section(".vectors"))) = {
(void (*)(void)) &_stack_top, // 初始堆栈指针
Reset_Handler, // 复位处理程序
NMI_Handler, // NMI处理程序
HardFault_Handler, // 硬故障处理程序
// ... 其他处理程序
SysTick_Handler // SysTick处理程序
};
其中:
在汇编语言中,向量表可能如下定义(以Keil MDK的startup.s为例):
.section .vectors
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
// ...
.word SysTick_Handler
链接脚本确保.vectors段位于正确地址。开发者通常无需直接修改向量表,只需实现对应的ISR函数。
2
编写中断服务例程
ISR是处理特定中断的函数,必须高效且可靠。以下是编写ISR的最佳实践:
以下是一个简单的定时器中断ISR示例:
void TIM2_IRQHandler(void) {
TIM2->SR &= ~TIM_SR_UIF; // 清除更新中断标志
// 执行操作,例如切换LED状态
}
ARM Cortex-M通过NVIC支持嵌套中断,允许高优先级中断抢占低优先级中断。优先级通过NVIC的优先级寄存器(IPR)配置,值越小优先级越高。例如,Cortex-M3/M4支持最多256个优先级级别,但具体实现可能只使用部分位(如4位,支持16个级别)。
开发者可以通过以下方式管理中断优先级:
嵌套中断的典型场景是高优先级中断(如紧急传感器触发)打断低优先级中断(如定时器任务),确保关键任务优先执行。
从向量表到中断服务的过程是嵌入式系统中中断管理的核心。通过理解IVT的结构、中断处理流程以及如何配置和编写ISR,开发者可以设计高效、实时的嵌入式系统。ARM Cortex-M的NVIC和硬件优化(如尾链式处理)进一步降低了中断延迟,提高了系统性能。
虽然本文以ARM Cortex-M为例,但其他MCU(如8051)也有类似的中断处理机制,尽管向量表地址和异常号可能不同。开发者应参考具体MCU的数据手册和工具链文档以获取详细信息。