
1、STM32 CM3 中断阐述, Z! v6 i! X5 t x- T" F h ARM Cortex M3内核支持256个中断(16个内核中断+240个外部中断),与其相关的中断控制寄存器和中断优先级控制寄存器(NVIC、SYSTICK)也都属于Cortex M3内核的一部分。1 V- A5 n7 v1 ?2 U 16分内部中断如下图:% ?5 @+ f$ @8 M2 c, v 3 h. i* W* W4 a; y6 R7 c( m9 J/ ^ ![]() STM32使用了ARM Cortex M3内核并对其进行了裁减,使之在原本支持240个外部中断裁减变成了68个外部中断,外加内部的16个中断,一共16+68=84个中断。# i1 v0 w- N w7 g; @) O: Z: H 现在知道了STM32一共84个中断,那么在实际使用的时候怎么对它进行管理的呢?. J3 ~% t8 Z C' r( P ( t" y" W! C% D' I 这就引入了中断优先级的概念。 2、优先级的定义 名词:NVIC(Nested vectored interrupt controller),嵌套向量中断控制器。. W/ S& o( ?8 d8 G w CM3内核使用NVIC来管理中断; CM3中优先级的数值越小,优先级越高,支持256级中断(所以CM3配置中断优先级的寄存器是8bit的);# U1 `, |6 N9 i2 g& N, r1 Z CM3 支持中断嵌套,使得高优先级异常会抢(preempt)低优先级异常。5 l. [" `" c7 n+ p1 e: Z/ _ CM3有3个系统异常:复位,NMI 以及硬 fault,它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常。除了这三个,其它异常的优先级则都是可编程的(但不能编程为负数)。 CM3最大支持到了256个等级的中断优先级但是实际上用不到这么多,所以大多数采用了M3内核的芯片会对其进行精简设计,ST就是裁掉了这个寄存器的低4bit,只用高4bit来表示优先级,以达到减少优先级数的目的,而4bit所能代表的最大数就是16,所以说STM32支持16级的可编程中断。 + `# O( i, A: G$ n& V CM3的240个外部中断都有自己的中断优先级配置寄存器PRI_n,这个寄存器是8位的,每4个相邻的中断优先级寄存器拼成一个32位的寄存器。这是NVIC的重要组成部分。& }* F- R7 H7 _ $ x- ]6 v/ n4 Y; F ![]() ' ^" B" `9 m! {6 Q 而STM32只支持68个外部中断,在NVIC控制结构中虽然体现了240个,但是实际用不到这么多,如下图是STM32的NVIC控制结构(STM32裁掉了这个寄存器的低4bit,只用高4bit来表示优先级等级)。 3 W% g1 x+ o @ ![]() 所以你可以看到在STM32标准库函数NVIC_Init函数内配置外设的优先级的时候,这里对优先级进行了左移4位的操作: P2 P, a- t& x $ ^1 d) C0 ?4 V1 o ![]() : u5 l+ \% X7 G 3、中断优先级分组 NVIC中有一个寄存器是“应用程序中断及复位控制寄存器“(AIRCR),它里面有一个位段名为“优先级组”。该位段的值对每一个优先级可配置的异常都有影响——把其优先级分为个位段: MSB 所在的位段(左边的)对应抢占优先级,而 LSB 所在的位段(右边的)8 [0 E. L( R/ E8 o1 z( b 对应亚优先级,如下图: ![]() ![]() SCB->AIRCR寄存器的[10:8]位是用来设置中断优先级分组的,通过这3位的配置,可以对IP(中断优先级)寄存器的[7:4]进行优先级的管理,例如:. S4 M% }* n! ^/ | c1 }$ a4 s 将AIRCR的10:8位写成101,那么IP寄存器的[7:4]这四个bit,[7:6]用来表示抢占优先级,[5:4]用来表示响应优先级。$ C3 |! P2 C7 E$ D 将AIRCR的10:8位写成011,那么IP寄存器的[7:4]这四个bit都用来表示抢占优先级,无响应优先级,4bit做能代表的范围是0~15,所以优先级的设置就是0-15级,这个分组模式通常用于RTOS,例如FreeRTOS。! F7 ~( o9 ?& X/ J ![]() 4、特殊寄存器(PRIMASK、FAULTMASK、BASEPRI)开关中断设置 这三个寄存器用来开关中断用,只能在特权模式下进行访问,不过CMSIS提供了函数能够在C环境中进行调用。这三个寄存器描述如表(摘自CM3权威指南): ![]() 6 t4 a8 v/ N" P3 H# P PRIMASK(优先级屏蔽寄存器) 这个寄存器只有1bit,如果设置为1,除了NMI和Hard Fault中断被允许外,其他中断全部被屏蔽,默认为0;1 r& M7 r6 `; j6 E CMSIS提供的C环境中操作该寄存器:
FAULTMASK(断层屏蔽寄存器) }+ x; [. f/ N* h: C 这个寄存器也是只有1bit,如果设置为1,除了NMI中断被允许,其他全部中断包括Hard Fault中断也被屏蔽,默认为0;: x, v& e6 B8 q CMSIS提供的C环境中操作该寄存器:
BASEPRI(基本优先级屏蔽寄存器):这个寄存器能够提供更精细化的中断屏蔽,往这个寄存器里写一个值,可以屏蔽比该优先级值低的中断,在CM3中,这个寄存器只用到了[7:4]这四个位,这与IP寄存器是一致的;(下图摘自PM0056-STM32编程手册) ![]() 9 {6 }3 E1 K- P# o( I CMSIS提供的C环境接口如下:
FreeRTOS就是使用了该寄存器来管理中断,屏蔽相应的中断进行临界区资源保护,而不是关全部中断。$ z7 b9 A1 t2 _( `! k, p8 s 2 y9 q& R" c* M: d5 O+ S2 P 补充①:除了使用以上寄存器开关中断,CMSIS还提供了另外的开关中断的接口: " [0 k- p4 W/ }. V
补充②:ARM的汇编指令CPS,全称Change Processor State,改变处理器状态。. X0 V, G) K' n8 z C+ y V IE:Interrupt or abort enable. 中断使能 ; m0 g8 D# N) w; H* M7 R) f& L/ y6 h ID: Interrupt or abort disable. 关闭中断 利用该指令来快速开关中断: cpsid i,关闭中断,实际操作的是PRIMASK5 ~ Q( x6 x% B. n cpsie i,开启中断,实际操作的是PRIMASK, w8 P# k& _7 M cpsid f,关闭中断,实际操作的是FAULTMASK ) o- R' _% B( D* g! [3 c8 @ cpsie f,开启中断,实际操作的是FAULTMASK- n) Q& e% J* L8 z' q3 r9 J% ` ————————————————) e& _- h" X" H 版权转载自:雍正不秃头1 y2 F2 P6 c' ~* }0 d# @ & {$ j/ y! K1 V7 }/ A1 g" e$ Q/ p |