32.中断优先级.md 7.1 KB

中断优先级(NVIC)

判别规则(核心,唯一要记的)

  1. 打断看抢占:抢占优先级数字小的能打断数字大的;抢占级相同 → 永不互相打断(子优先级再高也不行)
  2. 排队看子:谁先执行 = 先比抢占(小先),抢占相同再比子(小先)
  3. 数字越小越优先:0 最高、15 最低,和 FreeRTOS 正好相反;分组 4 位只在初始化配置一次,之后不再改

一句话:"数字小优先;能不能打断只看抢占级,同抢占级永不互相打断;子优先级只排先后、不打断;分组初始化一次定死。"

抽象描述(一句话本质)

把中断想成银行柜台:抢占优先级 = 能不能把正在办的人顶下来子优先级 = 同样级别的人谁先办。抢座位(打断)和排队(先后)是两回事——VIP 卡再高级,也不能把已经坐下的人撵走。

分组干的事:把优先级那 4 个二进制位劈成两半,一半管打断、一半管排队。

优先级分组表(4 位怎么劈)

分组 分配 抢占位数 子优先位数
NVIC_PriorityGroup_0 0 位抢占 + 4 位子优先 0 4(无打断)
NVIC_PriorityGroup_1 1 位抢占 + 3 位子优先 2 级 8 级
NVIC_PriorityGroup_2 2 位抢占 + 2 位子优先 4 级 4 级
NVIC_PriorityGroup_3 3 位抢占 + 1 位子优先 8 级 2 级
NVIC_PriorityGroup_4 4 位抢占 + 0 位子优先 16 级 0(全抢占)

例子(Group_2):优先级值 10 = 二进制 10 10 → 抢占 2、子 2。

大白话:Group_0 谁也不能打断谁,全靠排队;Group_4 反过来,谁都能打断别人(16 级随便嵌套),没有"排队"这回事。

正反例(建立直觉)

  • 正例1:A 抢占 2,B 抢占 3 → A 能打断正在执行的 B(数字小 = 抢占高,可嵌套)
  • 正例2:Group_2 下 A(抢占2,子1)、B(抢占2,子0)同时挂起 → B 先执行(子 0 先),但 A 不能打断正在跑的 B(同抢占级不嵌套)
  • 反例1:"B 子优先级比 A 高,所以 B 能打断正在执行的 A" → 错,打断只看抢占级,子级只排先后
  • 反例2:"优先级数值越大越优先" → 错,那是 FreeRTOS 的规则;NVIC 0 最高 15 最低
  • 反例3:"Group_4 下所有中断只能排队、无法打断" → 错,Group_4 反而全抢占(子位 0 → 没排队);无打断的是 Group_0

易混对比

抢占 vs 子优先级

抢占优先级 子优先级
作用 决定能否打断(嵌套) 同抢占级内谁先执行
数字规则 小 = 高,可打断大的 小 = 先,不打断
生效时机 任何时刻 只在同抢占级、都还没执行时
生活类比 抢座位 排队顺序

NVIC vs EXTI

NVIC EXTI
职责 排优先级、使能/屏蔽中断 检测引脚边沿、发中断请求
生活类比 裁判(谁先/能不能插队) 哨兵(发现情况喊一声)

STM32 vs FreeRTOS 优先级方向

STM32/NVIC FreeRTOS
方向 0 最高、15 最低 0 最低,数值大 = 高
原因 ARM 硬件约定,比较器按数值比 就绪列表用数组/位图当下标,大数方便从高位找最高就绪任务
教训 写代码/答题前先说清在哪个体系 同左

变体验证(3 题,全过=学会)

  1. Group_2 下 A(抢占1,子0)、B(抢占2,子1),A 正跑时 B 发生 → B 不能打断 A,A 继续执行(抢占 1 < 2,A 更高;B 等 A 跑完)
  2. 陷阱题:Group_2 下 A(抢占2,子3)、B(抢占2,子0),B 正跑时 A 发生 → A 不能打断 B(同抢占级永不互相打断),若都排队则 B 先(子 0 < 子 3)
  3. 陷阱题:"Group_4 下所有中断只能排队不能打断" → ,Group_4 是 4 位全抢占(16 级)可嵌套,无子级排队;不能打断的是 Group_0

口述要点(面试怎么讲)

  • 结论先行:数字小优先;打断只看抢占级;子级只排队不打断;分组初始化一次定死
  • 为什么 STM32 与 FreeRTOS 相反:NVIC 是 ARM 硬件约定(比较器按数值比),FreeRTOS 是为了位图索引方便——两套独立体系,别互相套
  • 为什么子优先级不能打断同抢占级:能打断的话抢占级就没意义了,还会无限嵌套;每嵌套一层就往栈里压一次异常帧 → 栈深不可控 = 溢出风险。子级的设计本意就是"同时到了谁先响应"的仲裁,不是打断。类比:抢座位(抢占)vs 排队顺序(子级),排队靠前的人不能把已经坐下的撵走
  • 为什么 ISR 要短:ISR 越长 → 压着后面其他中断和调度 → 延迟不可预测、错过 deadline(不是"会跑飞")。快进快出:只读数据/清标志/发通知,重活丢给任务——和 FreeRTOS FromISR 规则闭环
  • HAL 回调流程:外部中断 → HAL_GPIO_EXTI_IRQHandler()(清标志)→ HAL_GPIO_EXTI_Callback()(用户重写)。共享入口 EXTI15_10 要在 ISR 里判哪根线。核心 API:HAL_NVIC_SetPriorityGrouping / HAL_NVIC_SetPriority / HAL_NVIC_EnableIRQ(寄存器版 NVIC_SetPriorityGrouping 等)
  • 易错点:数值方向搞反;子优先级想打断同抢占级;以为每个中断能单独设分组;ISR 里写重活

关系网络

相邻概念 关系 孤立理解会犯的错
EXTI NVIC 排优先级,EXTI 检测边沿,两步分工 以为中断配置全在 NVIC,漏掉 EXTI 边沿/屏蔽
FreeRTOS 优先级 数值方向相反(0 高 vs 0 低) 拿 FreeRTOS 习惯配 NVIC
FreeRTOS 中断阈值 高于阈值的中断不能调用 FreeRTOS API 在最高优先级中断里乱调 FreeRTOS API
ISR 通信(主题 30) ISR 要短、不阻塞、用 FromISR 版——两主题同一原则 ISR 里写重活/阻塞
实时性 优先级配置错误 → 延迟不可预测、错过 deadline 以为分组随便改

学习日期

2026-08-18


每主题一页,复习时只翻本目录。