硬核NVIC:抢占优先级“一刀切”,急停按钮秒杀所有中断
硬核NVIC抢占优先级“一刀切”急停按钮秒杀所有中断很多工程师设置中断优先级时随手填个数字对抢占与子优先级的区别一知半解。书稿5.6节用一个“保大人还是保小孩”的灵魂拷问点破本质抢占优先级高的中断可以打断正在执行的低抢占中断——这好比急诊室里的危重病人插队若抢占优先级相同则无论子优先级如何都不能相互打断只能按自然优先级排队。这一刀切下去决定了你的系统是“遇险即停”还是“拖延误事”。1. 5种分组方式的“权力分配”书稿5.11节给出Group0~4的划分表但未用一个生活化类比解释。我的补充Group44位抢占0位子优先全部4个位用于抢占优先级支持16级抢占——这好比医院有16个急诊通道危重程度分16级高等级随时插队低等级。适合实时性要求极高的系统如飞行器控制、心脏起搏器。Group00位抢占4位子优先无抢占所有中断按子优先级排队——这好比普通门诊先来后到不插队。适合中断处理简单、无需嵌套的系统如环境数据采集。Group33位抢占1位子优先常用配置8级抢占2级子优先——中庸之道适合绝大多数工业控制场景书稿5.7节的RS485按钮串口调试组合。2. 抢占相同“和平共处”子优先级只决定“谁先发言”书稿5.11节指出抢占优先级相同的两个中断高子优先级的中断不能打断低子优先级的中断——它们只是排队顺序不同。我的补充场景假设USART1_IRQn和EXTI0_IRQn抢占优先级均为1Group3下但USART1子优先级0EXTI0子优先级1。若EXTI0正在执行USART1中断到来——USART1不会打断EXTI0必须等EXTI0跑完再执行。这打破了“子优先级高就能抢占”的常见误解。书稿中“组内中断不能抢占”的结论正是基于此规则。3. 自然优先级最后的“仲裁官”若两个中断抢占优先级和子优先级完全相同如都设0,0此时NVIC会看中断向量表中的自然优先级书稿5.8节的IVT表。例如EXTI0位置6自然优先级高于USART1位置37——所以即使USART1后触发EXTI0也先响应。这好比两个病人病情完全一样同分同秒挂号急诊室按“登记顺序”处理。4. 实战三级中断体系设计我的补充基于书稿5.7节的7项功能紧迫度分析我给出实战配置Group38级抢占2级子优先规则检验若急停按钮按下抢占0立即打断所有中断包括正在执行的USART2——符合书稿5.6节“数据比设备更重要”的哲学。若RS485正在接收数据抢占2子0用户按钮同时按下抢占2子1——不打断RS485等接收完成再处理按钮避免数据丢帧。5. 一个冷知识我的补充书稿5.11节提到HAL_NVIC_SetPriority()的第二个参数是抢占优先级第三个是子优先级。但不同Group下有效位数不同——若设Group33位抢占1位子优先则抢占优先级有效范围0~7子优先级有效范围0~1。若传入8,0实际会被截断为0,0——因为8的二进制1000低3位全0。这就是很多工程师“明明设了高优先级却不生效”的根源。结语NVIC优先级分组是ARM32的“交通调度中心”——抢占优先级决定“谁能插队”子优先级决定“排队顺序”自然优先级是“最后一道仲裁”。理解这三层你就能设计出“急事急办、缓事排队”的中断体系让系统在“千军万马”的中断请求中从容不迫。