01. 概述8 D Y! u7 t& U2 d% v/ X 中断是微控制器一个很常见的特性,中断由硬件产生,当中断产生以后CPU就会中断当前的流程转而去处理中断服务,Cortex-M内核的MCU提供了一个用于中断管理的嵌套向量中断控制器(NVIC)。 Cortex-M3和M4的NVIC最多支持240个IRQ中断请求,1个不可屏蔽中断NMI、1个Systick滴答定时器中断和多个异常。 6 g& |- ?, o3 t5 h: r4 C( | d 02. 中断管理 Cortex-M处理器有多个用于管理中断和异常的可编程寄存器,这些寄存器大多数都在NVIC和系统控制块SCB中,CMSIS将这些寄存器定义为结构体。以STM32F407为例,打开core_cm4.h,有以下两个结构体。' d/ U, T2 Z# h$ ?7 \& Z9 |+ T3 O/ _ NVIC_Type类型 B8 ?& z, Q6 U& T1 ]) e2 T
SCB_Type类型 , h# x5 a' }) l+ v0 V6 F
NVIC和SCB都位于系统控制空间SCS内,SCS的地址从0xe000e000开始,scb和NVIC的地址也在core_cm4.h中有定义0 F6 f- k+ i0 D3 [
03. 优先级分组) L7 l( C, g/ e A( ?# E1 @ 当多个中断来临的时候处理器应该响应哪一个中断是由中断的优先级决定的,高优先级的中断(优先级编号小)肯定是首先得到响应,而且高优先级的中断可以抢占低优先级的中断,这个就是中断嵌套。Cortex-M处理器的有些中断是具有固定的优先级的,比如复位、NMI、HardFault,这些中断的优先级都是负数,优先级也是最高的。1 Z$ X- `6 l. b# P. F$ Y Cortex-M处理器有是三个固定优先级和256个可编程的优先级,最多有128个抢占等级,但是实际的优先级数量是有芯片厂商来决定的。但是绝大多数的芯片都会精简设计的,导致实际上支持的优先级会更少,如8级、16级、32级等等。比如stm32就只有16级优先级。在设计芯片的时候会裁掉表达优先级的几个低端有效位,以减少优先级数,所以不管用多少位来表示优先级,都是MSB对齐的。下图都是用三位来表示优先级。 % p2 f: I: g& Q/ Z 优先级配置寄存器是位宽的,为什么只有128个抢占等级?8位不应该是256个抢占等级吗?为了是抢占机能变得更可控,cortex-M处理器还把256个优先级按位分为高低两段:抢占优先级(分组优先级)和亚优先级(子优先级),NVIC中有一个寄存器是“应用程序中断及复位控制寄存器(AIRCR)”,AIRCR寄存器里面有个位段名为“优先级组”。8 e. M& e) l r, d( b, t6 v: L# | % @& d# U* y- Z$ _) L8 j STM32使用了4位,因此最多有5组优先级分组设置,在msic.h中有定义:
04. 优先级设置4 c" o, U1 T) t$ q9 ^" [ 每个外部中断都有一个对应的优先级寄存器,每个寄存器占8位,因此最大宽度是8位,但是最小为3位。4个相邻的优先级寄存器拼成1个32位寄存器。如前所述,根据优先级组的设置,优先级又可以分为高低两个位段,分别是抢占优先级和亚优先级。STM32我们已经设置位组4,所以就只有抢占优先级了。优先级就餐器都可以按字节访问,当然也可以按半字、字来访问,有意义的优先级寄存器数目由芯片厂商来实现。 _6 ^7 W/ s4 H% } ! Y) ?1 o- V. |3 {7 k! K& Y; L 05. 特殊寄存器 5.1 PRIMASK和FAULTMASK寄存器2 g0 l. u2 G! L( Z' v1 b' M; N4 E 5.2 BASEPRI寄存器 3 O3 N" j0 c8 K/ P2 v 06. FreeRTOS中断配置宏 6.1 configPRIO_BITS y8 q! K) [3 w8 U5 D. D 此宏用来设置MCU使用几位优先级,STM32使用的是4位,因此该宏为4。 u) k, N6 ^" m
6.2 configLIBRARY_LOWEST_INTERRUPT_PRIORITY ! l6 N) X. n4 k+ T2 f9 k, T X8 C
该宏用来设置最低优先级,STM32优先级使用了4位,而且STM32配置的使用组4,也就是4位都是抢占优先级。因此优先级数数就是16个,最低优先级就是15。所以该值为15。不同的MCU,此值不同,具体是多少要看所使用的MCU的架构。 % ^& ~3 B! d# z! C8 [ G 6.3 configKERNEL_INTERRUPT_PRIORITY
该宏用来设置内核中断优先级。 % c) F7 ]* i/ I4 Z% ?) N 6.4 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
此宏用来设置FreeRTOS系统可管理的最大优先级,就是我们之前讲解的BASEPRI寄存器说的那个阈值优先级,这个可以自由设置,我们这里设置为5.也就是高于5的优先级(优先级小于5)不归FreeRTOS管理。1 W S5 o' t/ j5 x 0 N! ~! d: M5 Y1 p 6.5 configMAX_SYSCALL_INTERRUPT_PRIORITY
此宏设置好以后,低于此优先级的中断可以安全的调用FreeRTOS的API函数,高于此优先级的中断FreeRTOS是不能禁止的。中断服务函数也不能调用FreeRTOS的API函数。 % U3 V) x& R$ }2 x6 k+ ~. \2 f 07. FreeRTOS开关中断 FreeRTOS开关中断函数为portDISABLE_INTERRUPTS()和portENABLE_INTERRUPTS(),这两个函数在portmacro.h文件中有定义。; V2 K+ q6 `' T+ ? 5 ^- y# h4 J& z) w7 G
可以看出开关中断实际上是通过函数vPortSetBASEPRI( 0 )和vPortRaiseBASEPRI()来实现的,这两个函数如下:- F' P$ I6 t: Z& N$ Q# I + Y9 G0 D5 S. H0 t- m
|
【经验分享】STM32 FreeRTOS中断配置-转载自st论坛侵删
最新推荐文章于 2024-07-16 19:52:31 发布