进来讨论一下,NVIC寄存器组中的中断挂起SETPEND与消除CLRPEND,与外部中断挂起寄存器EXTI_PR有何关系?

2019-07-21 04:17发布

本帖最后由 warship 于 2018-7-27 19:32 编辑

如题,讨论一下
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
34条回答
warship
1楼-- · 2019-07-21 04:35
本帖最后由 warship 于 2018-7-28 10:42 编辑

没有人对此感兴趣,我自己研究理解了一下,
贴出来供参考。
warship
2楼-- · 2019-07-21 08:55
本帖最后由 warship 于 2018-7-28 11:11 编辑

先说结论,STM32的中断控制是分级管理的,CM3内核中的NVIC是顶层,对每个通道都设有1BIT的中断挂起位,
但每个通道可能不止一个中断源,比如EXTI5_9_IRQn,对NVIC而言,只算一个通道,但实际包含有5个中断源,
因此,下层就必须实现对这多个中断源的独立监控,这就是EXTI->PR中的挂起位了。
warship
3楼-- · 2019-07-21 13:46
本帖最后由 warship 于 2018-7-28 14:51 编辑

STM32的中断系统可以理解为分两级管理,
顶层当然是CM3内核强大的NVIC,下层就是形形 {MOD} {MOD}的片上外设了,
对于NVIC来说,它最大可以管理256个不同的中断通道,
这256个中断,内核自留了16个,剩下的通称为外部中断(注意与EXTI不要混淆,EXTI是外部中断中的一小部分,全称为外部线中断),外部中断可以多达240个(具体的芯片只实现了约60多个)。
这240个中断通道,在CM3的内核中,每一个中断都标配如下的控制:


1、中断优先级寄存器IP:8位(一般芯片只具体实现了高4位可表达16个优先级)


2、中断使能SETENA:1位,写1使能,写0无效
3、中断禁能CLRENA:1位,写1禁能,写0无效。 以上二者是联动的,实际只相当于1位,要使能就置SETENA位,要禁能就置CLRENA


4、中断挂起SETPEND:1位,写1挂起,写0无效,中断请求收到但暂不能服务时,置1,进入中断服务后由硬件清除
5、中断解挂CLRPEND:1位,写1解挂,写0无效。以上二者是联动的,实际只相当于1位,要挂起就置SETPEND位,要解挂就置CLRPEND


6、中断活动状态ACTIVE:1位,用于指示该中断是否处于活动状态,只读,从进入中断服务程序开始由硬件置位,直到中断服务返回由硬件清除。

以上几个内核寄存器(位)中,用户编程经常用到是主要是前3项,我们需要用到某个中断的时候,首先就是设置优先级,ENABLE中断,库函数所执行的就是对这前3项的设置,使用寄存器编程的同学也经常会直接操作;
后3项,用户编程基本用不到,包括使用寄存器编程的同学,甚至都感觉不到它们的存在,没有特殊需求的都任由硬件自由操作了。

NVIC是如何访问这些众多的寄存器或控制位的呢?  靠的就是中断通道号。
NVIC唯一认识的ID,也就是中断通道号,说白了就是0-239的号码牌IRQn,
NVIC就根据此号码去找相应的控制位(或寄存器),达到管理这240个中断通道的目的。
根据这个号码也可以从向量表中找到对应的中断服务程序入口(地址偏移量=0x0000 0040+IRQn*4)


warship
4楼-- · 2019-07-21 17:57
本帖最后由 warship 于 2018-7-28 12:06 编辑

其实虽说NVIC强大,但也可以说傻得可以,它其实根本不知道中断的具体来头,只须照章办事。
来了IRQ后,根据IRQn编号值去查相应的控制位(或寄存器),严格走下述流程:
1、首先是看该IRQ是否使能,只有使能位为1,才能受理申请,如果是禁能状态,则直接无视;
2、然后查看优先级寄存器IP[IRQn],该IRQ的优先级;
3、再通过查看ACTIVE可知,目前处于活动状态的所有中断;
4、如果有正在活动状态的中断(即正在服务中),则进行中断优先级比较。如果活动的中断优先级高,则先挂起这个IRQ。
    反复此步,直到没有更高优先级的中断需要服务;
5、轮到这个IRQ享受服务(由编号查向量表进入对应的中断服务程序,服务开始后置位它对应的中断活动状态位),解挂。


第5步里,就是NVIC对挂起和解挂的操作,这算是CM3内核的硬件自动完成的。
但它也允许软件来手动干预,手动挂起相当于来一次软件IRQ申请,手动解挂相当于软件撤消IRQ申请。

warship
5楼-- · 2019-07-21 23:37
 精彩回答 2  元偷偷看……
warship
6楼-- · 2019-07-22 00:02
本帖最后由 warship 于 2018-7-30 08:58 编辑

比如EXTI5_9_IRQn对于NVIC来说,只是一个中断,编号为23
但实际却包括了5个中断源,这一点NVIC根本是不知情的。EXTI5_9_IRQn是我们编的一个符号,实际就是一个常数,值为23(本文称为编号)
这5个中断源就具体由下级机构来管理了,每个都必须要有:
中断屏蔽位:是否受理该中断请求(在EXTI->IMR中)
中断挂起位:是否发生了该中断请求(在EXTI->PR中)
只要这5个中任一个或多个触发了中断条件(上升沿/下降沿等),相应的中断挂起就会被硬件置位,如果对应的一个或多个中断屏蔽是开放的,都会产生向NVIC发出EXTI5_9_IRQn号中断请求
至于这个EXTI5_9_IRQn是谁发的,是EXTI5、EXTI6、EXTI7、EXTI8还是EXTI9申请了中断? NVIC是无从知道的,它也管不了那么多。
软件如果需要的话,可以通过调阅监控记录来了解细节,而这个监控记录就是在外设中实现的中断挂起位。
在STM32的外部线中断EXTI系统中,共有19条外部中断线,每一条都有相应的中断挂起位,即EXTI->PR的BIT18:0,满足中断条件后,由硬件置位,并一直保持(随便等待调阅监控),直到由软件手动清除。
注:19条是目前常用芯片具体实现的数目,有些互联型的是20条,EXTI各用一个字来设置中断屏蔽位和中断挂起位,理论上最大可扩展能力为可以表达32条外部中断线

一周热门 更多>