关于nvic优先级分组在网上找了很长时间都没找到有人讲明白分组的用处和必要性,正点原子在此处讲的也挺含糊(新版hal教程视频也是如此)。
于是我只好去研究下官方文档,做做试验,现在说说我得到的理解。
讲解视频:
【stm32的NVIC优先级分组有什么用?】 https://www.bilibili.com/video/BV1kX4y1H7ng/?share_source=copy_web&vd_source=a1f0d022ae3796a551c3b3d60965160d
先说两个优先级的区别
一、抢占优先级和响应优先级
- 较高抢占优先级是可以打断正在进行的低抢占优先级中断的。
- 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
- 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
- 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。
二、中断优先级分组
- 优先级分组是确定一个分组规则,每个中断都会按照这个规则分组,每个中断都有自己的用于保存分组的四个位。
- 中断优先级分组可以在任何时候配置,即使是在各个中断开启前。
- 一个工程同一时间只能设置一种分组,也就是说配置一次,所有中断全局生效。程序中可配置多次,每次配置后全局为最新的配置。
- 在系统复位初始化之后,默认使用的是第0组优先级分组。
分组的理解:
先看官方文档:(STM32F10xxx Cortex-M3编程手册.pdf)
这是NVIC的IPR寄存器的文档,IPR寄存器有很多个,一个IPR寄存器划分4个区域(如上图表19中IPR0的4个区域分别为IP[0]、IP[1]、IP[2]、IP[3]),每个区域大小1个字节,一个区域对应一个中断。对于Stm32F10x,每个区域只有高4位可用,低4位一直为0,4位可以分成5组,也就是我们耳熟能详的下图所示:
中断数量超过1后,因为处理器同时只能处理一个中断,故需要判断先执行哪个中断,所以中断抢占优先级和响应优先级必有其一。
如组0,4个位全为响应优先级,即(16)个响应优先等级,也就是说如果开启的中断的数目超过16个,则它们的响应优先级必有重复。而由于0位抢占优先级,且优先级分组配置是全局统一,所以此种情况下所有中断不考虑抢占优先级(即所有中断不可出现抢占现象),当2个以上中断同时触发时,比较两个中断的响应优先级来决定谁先执行。
2.1做试验验证组0和组4的禁止行为
2.1.1试验1验证组0禁止抢占
我开启了两个定时器(TIM3和TIM4)。
TIM3每0.5s中断一次,中断服务函数中延时0.5s,延时前后分别通过串口打印信息;TIM4每0.8s中断一次,中断内打印信息。
如下定时器配置
中断服务函数
如下分组为0,即不允许抢占。TIM3抢占优先级为3(比TIM4),而由于0.5s中断一次的TIM3先进入中断,且中断内延时0.5s,所以0.8s中断一次的TIM4在触发中断瞬间,TIM3的中断服务函数必处于执行状态。
若此时考虑抢占的话,由于TIM4抢占优先级高于TIM3,故串口打印tim3 interrupt start后,必会接着打印tim4 interrupt;若tim3 interrupt start后跟tim3 interrupt over,且tim4 interrupt没有被打印,则可证明抢占行为已被禁止。
试验结果:(即证抢占行为被禁止)
2.1.2试验2验证组4禁止响应
设置分组4,抢占优先级相等,不可互相抢占。
若tim4进入中断,则证明响应行为正常进行;
若只有tim3进入中断,则证明响应被禁止。
串口打印如下:(即证响应行为被禁止)
2.2做试验验证优先级数值超过分组允许值的情况
试验1:如下图是使用按键的外部中断控制led的亮灭的中断配置。
分组为0,响应优先级占4位,即=16,我若设置响应优先级0x15(即十进制21,超出16),程序能正常编译,下载到板子上的运行也正常。
猜测有两种可能:超出自动截断为最大值、溢出部分为其实际优先级
于是需要继续试验
试验2:将上面两个定时器的实验的优先级部分修改一下:
分组2,抢占优先级有4个等级(0、1、2、3)。
若只有tim3进入中断,则证明规则是超出部分截断为最大值(即tim4的抢占优先级最终为0x03,优先级低于tim3);
若tim4也可以进入中断,则证明溢出部分为实际优先级(即0x04对3求余得0x01,优先级高于tim3)
试验2结果:(即规则是溢出部分为实际优先级)