STM32及ARM中断详解
ARM体系的中断和异常
当一个中断或者异常触发时,先看到这个中断源有没有被启动,以及它的优先级如何,然后进入中断向量表,如果允许进行中断或者异常的处理,就会根据中断向量表进入中断服务程序。
在中断服务程序中进行关中断、保存现场、开中断、处理中断和异常、关中断、恢复现场、开中断
在ARM体系中和异常统一由中断向量表管理。
中断向量表
中断向量表有低端和高端向量表两种,低端向量表就是从0x00000000开始,高端向量表处在0xFFFF0000位置。
下图中的中断向量表基本对应着ArmV7-A架构,而CortexM架构都可以使用自定义的中断向量表,不用遵循下表。如果是更新的Arm指令集版本,和下表也有较大区别
中断向量表和ResetHandler
ARM中断向量表的位置默认为0x00000000,中断向量表如下。
1 | _start: |
当机器上电启动时会从这个代码开始,先进入ResetHandler进行系统的初始化。当进入中断时,会从中断向量表的起始地址(也就是上面_start)开始,根据中断的类型进行偏移,例如如果偏移量为0x08则会执行SVC中断的语句,pc寄存器直接被装入中断向量的地址,跳转到对应的中断处理。
如果要防止中断嵌套,需要在中断服务程序中加入屏蔽中断的代码。
ResetHandler中是机器上电启动后或者复位后进行初始化的代码,初始化后会进入**_main**函数最后才进入main函数。
可以手动设置中断向量表的地址,一般的做法是在ResetHandler中设置。
STM32(Cortex-M)的中断服务程序
对Cortex-M系列来说,并不遵循arm所规定的普通的中断向量表。
1 | __Vectors DCD __initial_sp ; Top of Stack |
可以看到,中断向量表的第一行规定着栈初始化的地址,也就是说开机后会先初始化栈,然后才进行ResetHandler。
中断和异常触发流程(Cortex-M)
- 保存现场(硬件):将一些寄存器的值自动的保存到SP指向的栈中。
- 分辨异常/中断(硬件):根据异常/中断号在中断向量表中找到中断服务程序的地址并进行跳转。
- 中断服务程序结束后,从栈中恢复现场(软件)
1. 保存现场
不管是触发中断还是异常,硬件都会自动保存R0到R3、R12、LR、xPSR寄存器。
剩下的寄存器将在中断服务程序中进行保存。
根据ATPCS标准,被调用的函数如果要是用R4到R11寄存器,则需要在被调用函数的内部进行压栈。
- 调用C语言的中断服务程序:编译器会自动生成保存现场的汇编代码,不需要程序员手动的保存。
- 调用汇编编写的中断服务程序:需要在中断服务程序中手动编写保存现场的程序。
2. 根据中断号进入中断
寻找中断向量表,再根据中断号,在中断向量表中进行偏移。
3. 恢复现场。。。。
NVIC中断优先级
不同系列的芯片有不同位数的中断优先级,这个中断优先级一般是在BASEPRI寄存器的最高几位。比如CortexM系列的CPU,中断优先级位数有4位,就是BASEPRI寄存器的高四位。
优先级数字越小,中断越优先。
中断优先级又被NVIC分成抢占优先级和响应优先级,可以配置对应的优先级分组。比如4位优先级里面,有两位是抢占优先级,有两位是响应优先级。我们发现如果中断优先级的设置只有4位的话,也就是只有16个不同的优先级,注定了一些中断必须要在同一个优先级中。对抢占优先级和响应优先级的处理是NVIC负责的,抢占优先级更高的可以中断嵌套其他更低的中断,而相同的抢占优先级的任务里,顺序执行响应优先级更高的。而对于整个优先级都完全一样的中断,则会通过自然优先级,也就是在中断向量表中的位置来判断。越靠前的自然优先级就越高。
本身抢占优先级和响应优先级这两个东西配合在一起,才是BASEPRI看到的真正的任务优先级,但是NVIC把他们拆成了两部分来使用。对BASEPRI寄存器来说,对优先级进行屏蔽,不在乎抢占还是响应,会直接屏蔽掉比寄存器的数值更大的那些中断。
NVIC可以管理的是中断,一般来源于外设或者内核异常。而有一些异常,比如HardFault或者NMI,他们在中断向量表的最前面,但是不通过NVIC进行中断的管理,并且其优先级也不能够被配置。他们的优先级默认被配置为最高,任何情况下发生这几个异常都是最先进行处理。而在这之后的MemManage和BusFault等等异常,包括操作系统常用到的SysTick和PenSV都是NVIC管理的内核异常。再往后,就是NVIC管理的外设的中断。
在操作系统中,一般使用到的中断就是SysTick和PendSV。SysTick用于提供操作系统时钟,并且在合适的时候进行唤起任务的切换。PendSV则用于进行任务的切换。PendSV的可配置优先级一般为最低,然后SysTick为其次。
- Title: STM32及ARM中断详解
- Author: HarderHeng
- Created at : 2024-05-08 15:59:41
- Updated at : 2025-03-21 16:56:19
- Link: https://harderheng.life/2024/05/08/STM32及ARM中断详解/
- License: This work is licensed under CC BY-NC-SA 4.0.