文章目录
-
- [一. 抢占优先级与子优先级概念](#一. 抢占优先级与子优先级概念)
-
- [抢占优先级(Preemption Priority)------ 决定能否"强行插队(打断)"](#抢占优先级(Preemption Priority)—— 决定能否“强行插队(打断)”)
- [子优先级(Subpriority)------ 决定共同等待时"谁先被宠幸"](#子优先级(Subpriority)—— 决定共同等待时“谁先被宠幸”)
- [二. IRQ与NVIC](#二. IRQ与NVIC)
-
- [1. 什么是 IRQ(Interrupt Request - 中断请求)?](#1. 什么是 IRQ(Interrupt Request - 中断请求)?)
- [2. 什么是 NVIC(Nested Vectored Interrupt Controller - 嵌套向量中断控制器)?](#2. 什么是 NVIC(Nested Vectored Interrupt Controller - 嵌套向量中断控制器)?)
- [三. 严格的硬件划分:系统异常 vs IRQ](#三. 严格的硬件划分:系统异常 vs IRQ)
-
- [① 编号 1 ~ 15:系统异常(System Exceptions)](#① 编号 1 ~ 15:系统异常(System Exceptions))
- [② 编号 16 及以上:外部中断(External Interrupts)](#② 编号 16 及以上:外部中断(External Interrupts))
- [四. 补充高级知识:软件能触发 IRQ 吗?](#四. 补充高级知识:软件能触发 IRQ 吗?)
- [五. ARM Cortex-M 内核异常管理的核心](#五. ARM Cortex-M 内核异常管理的核心)
一. 抢占优先级与子优先级概念
在 ARM Cortex-M 内核中,只要是可配置的异常(包括 SVC、PendSV 和所有的外设中断 IRQ),它们对应的优先级寄存器(通常是 8 位,很多芯片只使用了高 4 位)都会被划分成两部分:抢占优先级和子优先级。
抢占优先级(Preemption Priority)------ 决定能否"强行插队(打断)"
本质:它是真正的"武力值"。如果 A 的抢占优先级比 B 高,当 B 正在执行时,A 来了,A 可以强行把 B 掐断,自己先运行(这叫中断嵌套)。
子优先级(Subpriority)------ 决定共同等待时"谁先被宠幸"
本质:它只是一个"排队序号",没有任何打断别人的能力。只有当 A 和 B 的抢占优先级完全一样,并且它们同时向 CPU 发出请求时,CPU 才会看一眼子优先级,谁的子优先级高,谁就先执行。
二. IRQ与NVIC
1. 什么是 IRQ(Interrupt Request - 中断请求)?
IRQ 是一个"信号"或"事件"。
字面意思:中断请求。
它是谁发出的:由芯片上的各大硬件外设(如 UART 串口、TIM 定时器、ADC 模数转换器、GPIO 外部引脚)发出来的。
它的本质:当外设完成了某项工作,或者发生了突发状况,它就会拉高或拉低一根内部信号线,向 CPU 喊一句:"我这边有紧急情况,请求处理!"这个发出的信号,就叫做一个 IRQ。
数量:一款芯片通常有几十甚至上百个 IRQ(例如:UART1_IRQ、TIM3_IRQ 等),每个外设都有自己专属的 IRQ 编号。
2. 什么是 NVIC(Nested Vectored Interrupt Controller - 嵌套向量中断控制器)?
NVIC 是一个"硬件管理机构"。
字面意思:嵌套向量中断控制器。它不是软件代码,而是直接做在 ARM Cortex-M 内核里面的一个极其强大的硬件外设电路。
它的职责:CPU 总经理只有一个人,面对几十个外设同时发来的 IRQ 请求,根本应付不过来。NVIC 就是挡在 CPU 前面的"金牌秘书",所有外设的 IRQ 信号必须先送到 NVIC 这里,由 NVIC 统一盘点、筛选、排序后,再决定要不要递给 CPU。
[外设:GPIO引脚被按下]
│
▼ 产生一个
[ IRQ 信号 (例如 EXTI0_IRQ) ]
│
▼ 顺着走线流入
[ NVIC (中断控制器) ] ─── 秘书检查:1. 该IRQ开启了吗? 2. 优先级够高吗?
│
▼ 如果通关,NVIC 敲响 CPU 的门
[ CPU 内核 ] ─── 硬件自动压栈,并根据 NVIC 提供的"向量地址"直奔中断函数!
三. 严格的硬件划分:系统异常 vs IRQ
在 Cortex-M 内核中,所有打断 CPU 的事件都被统称为"异常(Exception)"。内核给这些异常编了号(1 到 240+):
① 编号 1 ~ 15:系统异常(System Exceptions)
这些是由 CPU 内核内部触发的,其中就包括了软件中断。
编号 11:SVC(纯软件指令触发,属于系统异常,不是 IRQ)
编号 14:PendSV(写寄存器触发,属于系统异常,不是 IRQ)
编号 15:SysTick(滴答定时器,属于内核自带的系统异常)
② 编号 16 及以上:外部中断(External Interrupts)
这些是由内核外边的外设(如串口、定时器、GPIO)触发的。只有这部分异常,在 ARM 的官方术语里才被称为 IRQ(Interrupt Request)。
编号 16:IRQ0(比如 WWDG 窗口看门狗中断)
编号 17:IRQ1(比如 PVD 电源电压检测中断)
......以此类推。
所以,从严格的硬件定义来看:SVC 和 PendSV 是"系统异常",不是 "IRQ"。
四. 补充高级知识:软件能触发 IRQ 吗?
虽然 SVC/PendSV 自身不是 IRQ,但你提的这个问题在另一种层面上是成立的:在内核中,软件确实可以手动触发一个真正的 IRQ。
ARM NVIC 控制器中提供了一个非常特殊的寄存器,叫做 STIR(Software Trigger Interrupt Register,软件触发中断寄存器)。
它的好玩之处在于:哪怕外部硬件没有任何动静(比如串口没收到数据),你在代码里往 STIR 寄存器里写入串口中断的 IRQ 编号(比如 NVIC->STIR = UART1_IRQn;)。
结果:NVIC 硬件电路会瞬间被欺骗,它会以为硬件串口真的来数据了,从而立刻向 CPU 发出中断信号,让 CPU 跳进 UART1_IRQHandler 去执行。
这种行为,在行业内通常被称为"软件触发的硬件中断(Software-triggered Hardware Interrupt)"。
五. ARM Cortex-M 内核异常管理的核心
硬件中断(IRQ)、SVC 指令和 PendSV
