中断机制基础:中断向量、优先级、使能与屏蔽、嵌套

各位同学,咱们今天聊聊中断机制的四大支柱。说白了,这四样东西就像中断系统的“四肢”,缺了谁都会出问题。我做了十几年嵌入式,每次遇到奇怪的中断延迟问题,回来一查,十有八九是这四个地方没搞对。

中断向量:CPU识别中断源的“门牌号”

中断向量是什么?就是一张表,CPU一查就知道哪个外设喊它。每个中断源对应一个固定的向量号,CPU拿到这个号,跳转到对应的服务函数(ISR)。

中断源向量号(ARM Cortex-M)典型优先级
复位1最高(-3)
NMI2-2
DMA完成中断16+n(依MCU)可配置
定时器......

我个人习惯,启动时就把向量表基址配好。千万别在主循环里改它——我见过有人在运行期动态改向量表,结果中断一来CPU直接跑飞,那叫一个惨。

注意:中断向量表必须对齐到MCU要求的边界(通常256字节或512字节)。我曾经在STM32上因为忘了4字节对齐,调试了整整一下午。

中断优先级:谁更紧急,谁先跑

优先级这个事儿吧,很多同学以为“数值越小优先级越高”就是一切。其实背后还有分组、抢占、子优先级等等坑。你想想看,如果两个中断同时来,谁的优先级高谁先执行。可如果高优先级的中断正在跑,低优先级的来了怎么办?——这就是抢占(即中断嵌套)。

我建议你画一张表,把项目中所有中断优先级提前规划好。不要让DMA中断和定时器中断抢优先级,否则你的DMA完成响应可能被卡死。

// 以STM32为例,设置优先级分组为4位抢占 + 0位子优先级
NVIC_SetPriorityGrouping(3);           // 4 bits for pre-emption priority

NVIC_SetPriority(DMA1_Stream0_IRQn, 0); // 最高抢占优先级
NVIC_SetPriority(TIM2_IRQn, 1);         // 次高
NVIC_SetPriority(USART1_IRQn, 2);       // 最低

中断使能与屏蔽:开关控制与临界区

使能中断很简单:设置对应的寄存器位。但屏蔽呢?我见过不少人把全局中断一关就是几十微秒,结果DMA完成中断错过了死等。这里有个技巧:用局部屏蔽而不是全局屏蔽。比如你只想屏蔽定时器中断,那就操作NVIC的对应清除使能位,别动PRIMASK。

  • 全局屏蔽:__disable_irq() / __enable_irq() —— 慎用,时间尽量短
  • 局部屏蔽:NVIC_DisableIRQ() / NVIC_EnableIRQ() —— 只关某个中断
  • 优先级屏蔽:BASEPRI寄存器 —— 屏蔽低于某优先级的中断,高于的继续跑
经验:如果你的DMA中断延迟要求严格,我建议用BASEPRI来屏蔽低优中断,而不是关全局。这样高优中断(包括DMA)照常响应,低优任务被堵住而已。

中断嵌套:高优打断低优

嵌套就是正在处理一个中断时,来了更高优先级的中断,CPU暂停当前ISR去处理新的。等新的处理完,再回来继续老的ISR。这本身是好特性,但处理不好会导致堆栈溢出或者优先级反转。

嗯,这里要注意:嵌套深度不要太深。我曾经在一个项目里嵌套了5层,结果堆栈只有512字节,直接溢出。从那以后我规定嵌套不超过3层,且每个ISR都静态检测堆栈余量。

// 嵌套流程示例(伪代码)
ISR_LowPriority:
    save context
    enable higher priority interrupts     // 允许嵌套
    handle interrupt
    disable higher priority interrupts
    restore context
    return from interrupt

ISR_HighPriority:
    // 直接执行,因为优先级高,CPU已自动关嵌套
    handle interrupt
    return from interrupt

SVG:中断处理流程全景图

我把这四者的关系画在一张图里,你一看就明白。

中断机制核心流程与四要素 中断源(DMA等) 中断向量表 中断优先级判定 使能/屏蔽检查 中断嵌套处理 ISR执行 中断返回 未使能则忽略 ⚠️ 嵌套时注意堆栈 深度和优先级反转 使用BASEPRI优化

你看这条线:从DMA触发中断,先查向量表找到ISR入口,接着优先级判定决定它能不能立即执行,然后使能/屏蔽检查——如果没使能就丢掉。接下来是嵌套检查,最后才执行ISR。这每一步都影响延迟。

关键总结:
  • 向量表表项必须正确、对齐
  • 优先级分组和数值提前规划
  • 全局屏蔽时间要极短,多用BASEPRI
  • 嵌套深度设上限,并监控栈使用

好了,中断机制这四样东西,搞清楚了,DMA响应延迟就有了基础保障。下一步我们来看具体怎么测延迟、找瓶颈。