一句话:"数字小优先;能不能打断只看抢占级,同抢占级永不互相打断;子优先级只排先后、不打断;分组初始化一次定死。"
把中断想成银行柜台:抢占优先级 = 能不能把正在办的人顶下来;子优先级 = 同样级别的人谁先办。抢座位(打断)和排队(先后)是两回事——VIP 卡再高级,也不能把已经坐下的人撵走。
分组干的事:把优先级那 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 级随便嵌套),没有"排队"这回事。
| 抢占优先级 | 子优先级 | |
|---|---|---|
| 作用 | 决定能否打断(嵌套) | 同抢占级内谁先执行 |
| 数字规则 | 小 = 高,可打断大的 | 小 = 先,不打断 |
| 生效时机 | 任何时刻 | 只在同抢占级、都还没执行时 |
| 生活类比 | 抢座位 | 排队顺序 |
| NVIC | EXTI | |
|---|---|---|
| 职责 | 排优先级、使能/屏蔽中断 | 检测引脚边沿、发中断请求 |
| 生活类比 | 裁判(谁先/能不能插队) | 哨兵(发现情况喊一声) |
| STM32/NVIC | FreeRTOS | |
|---|---|---|
| 方向 | 0 最高、15 最低 | 0 最低,数值大 = 高 |
| 原因 | ARM 硬件约定,比较器按数值比 | 就绪列表用数组/位图当下标,大数方便从高位找最高就绪任务 |
| 教训 | 写代码/答题前先说清在哪个体系 | 同左 |
HAL_GPIO_EXTI_IRQHandler()(清标志)→ HAL_GPIO_EXTI_Callback()(用户重写)。共享入口 EXTI15_10 要在 ISR 里判哪根线。核心 API:HAL_NVIC_SetPriorityGrouping / HAL_NVIC_SetPriority / HAL_NVIC_EnableIRQ(寄存器版 NVIC_SetPriorityGrouping 等)| 相邻概念 | 关系 | 孤立理解会犯的错 |
|---|---|---|
| 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
每主题一页,复习时只翻本目录。