深入理解 Cortex-M3 的异常与中断系统:从概念到实现

#Technomous

在嵌入式系统开发中,我们经常听到“中断”和“异常”这两个术语。虽然日常交流中常常混用,但从处理器架构的角度来看,它们有着明确的定义和分工。本文将带你深入理解 ARM Cortex-M3 处理器的异常与中断机制,涵盖其分类、优先级、响应流程以及在实际开发中的意义。

什么是异常与中断?

在计算机系统中,所有能够打断程序正常执行流的事件,统称为“异常”(Exception)

虽然“中断”(Interrupt)常被用来泛指这类事件,但严格来说:

在 Cortex-M3 架构中,这两类事件都被统一纳入“异常系统”进行管理,由同一个 NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器)进行调度和响应。

Cortex-M3 的异常系统架构

Cortex-M3 内建了一个强大的异常响应系统,支持多种系统异常和外部中断。所有异常都有唯一的编号和对应的中断向量地址,存储在中断向量表中(通常位于内存起始位置 0x0000_0000)。

异常编号与分类

编号 类型 名称
1–15 系统异常 Reset, NMI, HardFault 等
≥16 外部中断 IRQ #0 ~ IRQ #239

📌 注意:异常编号越小,优先级默认越高(但可通过 NVIC 配置修改)。

系统异常详解

下表列出了 Cortex-M3 中主要的系统异常及其作用:

异常编号 优先级 类型 名称 说明
保留 保留未使用
1 –3 固定 Reset 系统复位,程序从初始地址开始执行
2 –2 固定 NMI(不可屏蔽中断) 不可被关闭的中断,常用于紧急事件,如 RCC 时钟安全系统(CSS)检测到时钟失效
3 –1 固定 HardFault 所有未被其他异常处理的错误都会升级为此异常,是调试崩溃问题的关键入口
4 0 可编程 MemManage Fault 内存管理错误,如访问受保护的内存区域
5 1 可编程 BusFault 总线错误,如预取指失败、数据访问失败
6 2 可编程 UsageFault 使用错误,如执行未定义指令、未对齐访问(视配置而定)
保留 保留
11 3 可编程 SVCall 通过 SVC 指令触发的系统调用,常用于操作系统中实现特权服务
12 4 可编程 Debug Monitor 调试监控异常,用于在调试模式下监控程序行为
保留 保留
14 5 可编程 PendSV 可挂起的系统调用,常用于 RTOS 的上下文切换
15 6 可编程 SysTick 系统滴答定时器中断,为操作系统提供周期性时基

💡 提示:HardFault 是嵌入式开发中最常见的“崩溃”异常,通常由空指针解引用、栈溢出、非法地址访问等引起,掌握其调试方法至关重要。

外部中断(IRQ)

编号从 16 开始的异常均为外部中断,也称为 IRQ(Interrupt Request)。这些中断来源于处理器外部的硬件模块,例如:

这些中断是可屏蔽的,可以通过 NVIC 进行使能、关闭、优先级设置和挂起控制。

编号范围 类型 描述
16–255 IRQ #0–#239 共 240 个可编程中断

在实际开发中,每个外设的中断请求线都会连接到 NVIC,开发者通过配置 NVIC 来决定是否响应、以何种优先级响应。

异常与中断的关键区别

特性 异常(Exception) 中断(Interrupt)
触发源 处理器内部(指令执行、访存等) 处理器外部(外设、GPIO等)
同步性 同步(与指令流相关) 异步(与主程序无关)
是否可屏蔽 部分可屏蔽(如 UsageFault) 大多数可屏蔽(通过 NVIC 控制)
常见类型 HardFault, SVCall, SysTick TIM, USART, EXTI 等外设中断

✅ 举例说明:

中断向量表(Vector Table)

Cortex-M3 在启动时会从内存地址 0x0000_0000 读取中断向量表,其结构如下:

地址(偏移) 内容
0x0000_0000 初始栈指针(MSP)值
0x0000_0004 Reset 处理函数地址
0x0000_0008 NMI 处理函数地址
0x0000_000C HardFault 处理函数地址
... 其他异常/中断处理函数地址

该表在启动文件(如 startup_stm32f103xb.s)中定义,开发者需为每个中断编写对应的中断服务程序(ISR)。

优先级与嵌套机制

Cortex-M3 支持可编程优先级,除 Reset、NMI 和 HardFault 优先级固定外,其余异常和中断的优先级均可通过 NVIC 配置。

总结

Cortex-M3 的异常与中断系统是嵌入式实时系统的核心机制之一。理解其工作原理,有助于:

掌握异常与中断的区别与联系,是迈向高级嵌入式开发的必经之路。

延伸学习建议