STM32 - 中断
1. 中断定义(Event)
中断 (Interrupt):指当出现需要时,CPU暂时暂停当前程序的执行,转而执行处理新情况的程序的处理过程。
即在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个新的情况的过程。
2. 中断分类
现代处理器的中断概念变得越来越广泛,已经不仅仅局限于外部设备中断。
中断存在的意义是CPU控制外部设备的同时,外部设备也可以高效的“控制CPU”
。
发展至今,这种设计思想扩展到了外部硬件控制CPU、软件控制CPU、CPU运行管理
等三个方面。
因此,使用event 事件
来表示则更加贴切实际,但在平时描述中,基本上仍然采用了中断
这个词。
产生中断请求的设备或者事件被称为 中断源
Event
的分类如下图,主要包括中断和异常:
Hardware Interupt
:外部硬件控制CPUSoftware Interrupt
:软件控制CPUException
:CPU运行管理
2.1 硬中断
&emsp当设备有某种事件发生时,它就会产生中断,通过总线把电信号发送给
中断控制器信号
,当设备有某种事件发生时,它就会产生中断,通过总线把电信号发送给中断控制器
。
如果中断的线是激活的,中断控制器就把电信号发送给处理器的某个特定引脚。处理器于是立即停止自己正在做的事,跳到中断处理程序的入口点,进行中断处理。
硬中断是 由与系统相连 外设
(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包的时候,就会发出一个中断。我们通常所说的中断指的是硬中断(hardirq)。
硬件中断可分为
- NMI(Nonmaskable Interrupt,不可屏蔽中断): 用于紧急情况的故障处理,如RAM奇偶校验错等
不可屏蔽中断源一旦提出请求,cpu必须无条件响应
- INTR(Interrupt Require,可屏蔽中断): 用于外部依靠中断来工作的硬件设备。网卡使用的就是INTR,
可屏蔽中断源的请求,cpu可以响应,也可以不响应
2.2 软中断
为什么要使用软中断?
①. 为了满足实时系统的要求
为了满足实时系统的要求,中断处理应该是越快越好。
编写驱动程序的时候,一个中断产生之后,内核在中断处理函数中可能需要完成很多工作。
但是中断处理函数的处理是关闭了中断的。也就是说在响应中断时,系统不能再次响应外部的其它中断。这样的后果会造成有可能丢失外部中断。
于是,linux内核设计出了一种架构,中断函数需要处理的任务分为两部分,一部分在中断处理函数中执行,这时系统关闭中断。另外一部分在软件中断中执行,这个时候开启中断,系统可以响应外部中断。
linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断来完成。
②. 访问受保护的系统资源
当一个应用软件终止或者它向操作系统请求一些服务时,软件中断就会发生。如果说在软件代码中包含了系统调用,那么可以将software interrupt理解为同步事件。
当CPU接收到一个软件中断信号时,它可能会暂时将控制切换到一个中断处理程序程序,并且内核中被中断挂起的进程(例如,一个程序的运行实例)将在中断被接受后恢复。
2.3 异常
CPU异常发生在各种错误的情况下,例如当访问无效的内存地址或除零时,为了对它们作出反应,产生了异常处理机制。
不同架构的处理器对异常类型的定义有所不同,但核心思想是CPU工作过程遇到了不被允许的错误或者强制停止指令
①. Fault
通常不影响软件代码的继续运行,此类异常主要包括:
- 除0操作
- 无效操作码
- 设备不可用
②. Trap
比较常见的就是JTAG debug。
当CPU收到了debug指令后,会进入到异常模式。此类异常主要包括:
- 断点
- 溢出
- 调试指令
③. Abort
比较常见的就是取指异常
当我们从RAM中没有正确的获取到待执行指令时,CPU进入到Abort异常。此类异常主要包括:
- 访存错误
- 总线错误
- cache错误
3. 中断向量表
3.1 向量表
STM32F4xx的中断向量表如下
Notice:
灰底色部分:CPU运行时候的内部异常
白底色部分:外部中断
3.2 NVIC
中断由NVIC这个外设来控制。
NVIC:(Nested Vector Interrupt Controller, 嵌套向量中断控制器) 属于内核外设管理着包括部分内核和片上所有外设的中断相关的功能。
两个重要的库文件:`core_cm4.h`(定义所有内核上面的寄存器,NVIC寄存器就在这里面)和 `misc.h`(相关的函数)。
4. 中断流程
4.1 中断响应过程
- 中断源发出中断请求
- 判断处理器是否允许中断,以及该中断源是否被屏蔽
- 中断优先级排队
- 处理器暂停当前程序,保护断点地址和处理器的当前状态,根据中断类型号,查找中断向量表,转到对应的中断服务程序
- 执行中断服务程序
- 恢复被保护的状态,执行中断返回指令,回到被中断的程
4.2 中断嵌套
- 多个中断同时出现时,处理器先响应高优先级的中断
- 低优先级中断的ISR(Interrupt Service Request,中断服务请求)执行时,可以被高优先级中断再次打断
- ISR比App Code拥有更高的执行优先级
5. EXTI - 外部中断/事件控制器
EXTI可以监测指定GPIO口的电平信号
,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC
发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序.
- 支持的触发方式:上升沿/下降沿/双边沿/软件触发
- 支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断(因为AFIO的设计)
- 通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、ETH以太网唤醒【外部中断的功能就是从低功耗的停止模式下唤醒STM32】
- 触发响应方式:中断响应【外设申请中断,CPU执行中断函数】/事件响应【外部中断信号不会通向CPU,而是通过总线到其他外设,也就是不会触发中断而是触发别的外设操作】
Notice:以上图并非特别准确,连接EXTI的应该是23个通道
- 线 0~15:对应外部 IO 口的输入中断。
- 线 16:连接到 PVD 输出。
- 线 17:连接到 RTC 闹钟事件。
- 线 18:连接到 USB OTG FS 唤醒事件。
- 线 19:连接到以太网唤醒事件。
- 线 20:连接到 USB OTG HS 唤醒事件。
- 线 21:连接到 RTC 入侵和时间戳事件。
- 线 22:连接到 RTC 唤醒事件。
5.1 AFIO
- AFIO (Alternate Function I/O,复用IO)需要完成两个任务
- 复用功能I/O重映射
- 中断引脚选择
- 相同的PIN不能同时触发中断:AFIO内部有16个数据选择器,相同的PIN在一组
外部中断/事件 GPIO映射如下:
5.2 EXTI 框图
- 外部中断/事件控制器包含多达 23 个用于产生事件/中断请求的边沿检测器。
- 每根输入线都可单独进行配置:以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发)。
- 每根输入线还可单独屏蔽
- 挂起寄存器用于保持中断请求的状态线
上图解释:
- 边沿检测电路:可以设置支持的触发方式:上升沿/下降沿/双边沿(边沿检测可以两个都触发)
- 软件中断事件寄存器:内部软中断
- 或门(带弧线):选择
上升沿/下降沿/双边沿/软件触发
中的一种- 与门(半圆的):开关控制
- 请求挂起寄存器:
挂起寄存器相当于中断标志位
,读取寄存器判断哪个通道触发中断- 中断屏蔽寄存器:屏蔽掉对应的中断请求
5.3 寄存器
1)中断屏蔽寄存器 (EXTI_IMR)
- 偏移地址:0x00
2)事件屏蔽寄存器 (EXTI_EMR)
- 偏移地址:0x04
3)上升沿触发选择寄存器 (EXTI_RTSR)
- 偏移地址:0x08
4)下降沿触发选择寄存器 (EXTI_FTSR)
- 偏移地址:0x0C
5)软件中断事件寄存器 (EXTI_SWIER)
- 偏移地址:0x10
6)挂起寄存器 (EXTI_PR)
- 偏移地址:0x14
6. 代码示例
本代码不讲实验,只做配置说明。
STM32F4 的每个 IO 口都可以作为中断输入,要把 IO 口作为外部中断输入,有以下几个步骤(可以借助下图进行配置讲解):
1)初始化 IO 口为输入
2)开启 SYSCFG 时钟,设置 IO 口与中断线的映射关系
- 开启 SYSCFG 的时钟
- 后配置 IO 口与中断线的对应关系(通过 EXTICR 寄存器设置)
总共4个SYSCFG_EXTICR (1-4),分别代表 PA-PI[3:0]/[7:4]/[11:8]/[15:12]
3)开启与该 IO 口相对的线上中断,设置触发条件
根据【5.3 寄存器配置】进行如下设置:
- 配置中断产生的条件:上升沿/下降沿/边沿/电平
- 开启该线上的中断
4)配置中断分组(NVIC),并使能中断
- 配置中断的分组
- 设置优先级,使能该中断
以上配置,皆在NVIC中进行配置
5)编写中断服务函数
在中断服务函数里面编写你要执行的中断后的操作