短文标题:异常与中断:系统异常是“内忧”,外设中断是“外患”
你有没有想过一个问题:复位和串口中断都叫“中断”,它们有什么不同?复位是“系统异常”(内忧),串口中断是“外设中断”(外患)。Cortex-M把所有能打断CPU正常运行的事件统称为异常,分为两类:
系统异常:内核的“紧急事件”系统异常由CPU内核自身产生,优先级大多固定:
外设中断:通过NVIC管理,外设中断由片内外设产生,通过NVIC管理:
- 抢占优先级:决定能否嵌套
- 子优先级:决定同时到达时的顺序
- 优先级分组:决定4个优先级位的分配
外设中断需要软件配置优先级和使能,系统异常部分固定、部分可配置。中断响应流程(硬件自动完成)
- 外设产生中断请求
- NVIC裁决优先级(判断是否嵌套)
- 硬件自动压栈:8个寄存器(PC、xPSR、R0-R3、R12、LR),32字节
- 从向量表取ISR地址(向量表在Flash起始0x08000000)
- 跳转执行ISR
- ISR返回:硬件自动出栈恢复现场
压栈、取址、出栈都由硬件完成,不依赖软件——这是Cortex-M中断响应快的核心原因。向量表及VTOR重定位,向量表默认在Flash起始地址(0x08000000),第一个字是栈顶地址(__initial_sp),第二个字是复位向量。通过SCB->VTOR寄存器可将向量表重定位到RAM:
SCB->VTOR = 0x20000000; // 搬移到RAM起始
用途:
- Bootloader跳转APP前需重设VTOR,否则APP的中断向量指向Bootloader区
- 运行时动态修改中断函数指针(热补丁)
尾链优化:连续中断更快,中断A未退出,中断B已挂起。传统架构:出栈A→压栈B→执行B(耗时长)。Cortex-M尾链:跳过A的出栈和B的压栈,直接执行B,连续响应仅6个时钟周期。
这个故事的启示,系统异常管“内忧”(复位、故障),外设中断管“外患”(串口、定时器)。它们都通过向量表、NVIC、硬件压栈构成统一的中断响应机制。写在最后,异常和中断是同一种机制的不同来源。系统异常来自内核,外设中断来自外设。前者保系统不死,后者让外设干活。
(本文灵感源于于振南《新概念ARM32单片机》教程第5.4节、第5.5节、第5.8节。)
觉得有用?点赞、转发,让更多人看懂异常和中断的区分。