中断
中断定义
中断是计算机系统中的一种事件,它打断了正常的程序执行流程,用于响应需要优先处理的事件或请求。
中断是计算机系统中的一种机制,用于在当前执行的程序或任务被中断处理程序(Interrupt Service Routine
,ISR)中断执行时,响应和处理发生的事件或信号。
中断源
中断源可以是硬件或软件触发的事件。
硬件中断源通常来自外部设备,如定时器、传感器、外部IO口、通信接口等。软件中断源一般是由程序内的特定指令(如INT
指令)或系统调用触发。
硬件中断源:
- 定时器溢出:当定时器计数值溢出时,可以触发一个中断。
- 外部事件:如外部按键被按下、外部通信接口收到数据等。
**软件中断源:
- 系统调用:操作系统的内核代码可能会通过中断机制处理系统级功能。
- 程序中的故障(如除零错误)也可能触发中断。
中断向量表
每个中断源通常有一个唯一的中断向量号或类型号,该号码在中断向量表中作为索引,用于定位对应的中断处理程序的入口地址。
中断向量表是一个存储中断处理程序入口地址的表格或数组,其中每个中断源或中断类型都对应着一个中断处理程序的入口地址。
在嵌入式系统(如STM32)中,中断向量表(Interrupt Vector Table,IVT)是一个存储中断处理函数入口地址的表。这个表在系统启动时会被加载到内存中,CPU根据中断请求跳转到相应的中断服务程序(ISR)。
中断向量表元素组成
- 第一个元素:复位向量,也就是系统复位时CPU跳转的入口地址。在STM32中,复位向量通常指向一个复位处理程序,通常是一个启动代码(Startup Code),它会初始化堆栈、系统时钟、外设等,并最终跳转到
main()
函数。 - NMI(非掩码中断)处理程序:通常是第2个元素。
- 硬故障处理程序:通常是第3个元素。
- 其他异常和中断服务程序:接下来是各种异常处理程序、外部中断、定时器中断等的入口地址。
中断向量表通常由启动文件(startup.s
或 system_stm32f4xx.c
)和链接器脚本(如.ld
)定义。在链接器脚本中,会指定中断向量表的位置和大小。
.section .isr_vector, "a", %progbits
.global g_pfnVectors
g_pfnVectors:
.word __StackTop /* 堆栈顶地址 */
.word Reset_Handler /* 复位向量 */
.word NMI_Handler /* NMI */
.word HardFault_Handler /* 硬故障 */
.word MemManage_Handler /* 内存管理 */
.word BusFault_Handler /* 总线故障 */
.word UsageFault_Handler /* 使用故障 */
/* 其他中断服务程序... */
存储区域
通常存储在系统的特定内存区域,如RAM
或 ROM
。在系统初始化期间,中断向量表会被填充或初始化为相应的中断处理程序的入口地址。
在STM32
等基于ARM Cortex-M处理器的系统中,中断向量表通常存储在Flash
内存的起始地址(0x00000000
)处。链接器会将中断服务程序的入口地址按顺序存储在中断向量表中。
作用
- 中断发生时,硬件或操作系统会根据中断号查询中断向量表。
- 每个中断号对应一个函数入口,处理器跳转到该入口执行中断服务程序。
中断向量表在嵌入式系统中起着至关重要的作用,它是实现中断处理机制的核心组成部分。通过中断向量表,系统能够快速、准确地响应和处理各种中断事件,提高系统的实时性和可靠性。
外部中断触发模式有哪些⭐⭐⭐
触发模式 | 特点 | 应用场景 |
---|---|---|
上升沿触发 | 信号从低电平到高电平时触发中断 | 检测按钮按下或传感器触发等高电平信号变化的场合 |
下降沿触发 | 信号从高电平到低电平时触发中断 | 检测按钮释放或传感器复位等低电平信号变化的场合 |
双边沿触发 | 信号的上升沿和下降沿均触发中断 | 需要同时检测上升沿和下降沿的场合,如通信协议的时钟信号 |
电平触发 | 信号维持相应电平期间持续触发中断 | 持续性信号的检测,如通信协议的数据线 |
中断分类
硬件和软件中断
- 硬件中断:由外部硬件设备发送给处理器的信号,表示需要处理器执行某种操作。例如,键盘输入、鼠标点击、定时器溢出等。
- 软件中断:由软件程序主动发送给处理器的信号,引发某种操作或请求。软件中断通常是通过特殊的指令或系统调用来触发。例如,操作系统的系统调用、异常处理等。
中断作用
使处理器能够及时响应和处理各种事件,提高系统的实时性和并发处理能力。
- 当系统发生中断时,处理器会立即暂停当前正在执行的任务,并跳转到中断处理程序的入口地址,执行相应的中断处理程序。
- 处理程序完成后,处理器会返回原来的执行状态,继续执行被中断的任务。
实时响应
:嵌入式系统通常需要实时响应外部事件,如传感器输入、通信数据到达等。中断允许系统立即中断当前任务的执行,转而处理紧急事件,从而满足实时性要求。异步处理
:中断机制可以处理异步事件,这些事件无法通过程序的顺序执行来预测。通过中断,系统可以立即响应和处理这些事件,而无需等待主程序轮询或检查。多任务处理
:中断机制使得多个任务能够并发地运行。当一个任务被中断时,系统可以立即切换到另一个任务,并在中断处理完成后返回到中断之前的执行状态。事件驱动
:嵌入式系统通常是事件驱动的,即通过检测和处理事件来触发特定的操作。中断机制使得系统能够及时响应和处理这些事件,从而实现事件驱动的功能。
中断的坏处
中断占用CPU时间
- 每次中断都会中断当前的CPU执行流程,跳转到ISR中执行中断服务程序,ISR的执行会占用CPU时间。如果ISR执行时间较长,或者有多个中断频繁发生,就会影响CPU执行其他任务的时间。
- 中断占用率是指系统CPU被中断处理程序占用的时间比例。中断占用率过高会导致主任务无法及时执行,甚至可能引发系统的性能瓶颈。
中断优先级和嵌套的复杂性
- 优先级配置复杂:中断优先级配置不当可能导致低优先级的中断被高优先级中断长时间抢占,从而造成延迟,影响实时性要求较高的应用。
- 嵌套中断的管理复杂:嵌套中断使得中断的执行更加复杂。例如,某些中断在处理中可能会触发其他中断,导致中断堆栈深度增加,从而影响系统的稳定性,甚至发生栈溢出。
- 调度问题:当中断频繁发生时,系统可能无法有效调度其他任务,尤其是在没有实时操作系统(RTOS)的情况下。
中断延迟
- 中断延迟是指从中断请求产生到中断服务程序开始执行之间的时间间隔。在多任务和中断频繁的系统中,可能会有一定的中断延迟,尤其是如果中断优先级管理不当,低优先级中断可能被高优先级中断长时间阻塞。
上下文切换的开销
- 中断服务程序的执行会导致上下文切换,保存当前执行状态(如寄存器值)并加载中断处理程序的状态。这种上下文切换虽然对大多数嵌入式系统来说代价较小,但在中断频繁发生的系统中,频繁的上下文切换会导致性能损失,尤其是在没有操作系统的情况下。
实时性问题
- 不可预测的中断源:如果中断的发生没有严格的优先级管理或被过多的低优先级中断所打断,可能会导致系统的实时性无法保证。某些重要的定时任务可能会因为中断的处理而错过时机,影响系统的预定行为。
- 中断屏蔽问题:在某些场景下,为了避免中断的干扰,需要禁用全局中断或某些中断。这可能会导致一些事件不能及时处理,影响系统的响应性和稳定性。
中断服务程序(ISR)
中断服务程序是处理特定中断事件的代码。当中断发生时,控制权会转移到ISR,ISR会执行处理相应事件的任务,通常会处理硬件状态、清除中断标志等。
ISR的特性
- ISR通常应该尽量简短,以免阻塞其他中断的响应。
- 需要注意在ISR中避免使用可能引起死锁的操作,如延时操作、复杂的IO操作等。
中断处理和中断服务程序的概念
- 中断:是计算机系统中的一种机制,用于向CPU发出异步信号,以通知操作系统发生了某种事件,例如外部设备完成了输入/输出操作或发生了错误。中断可以打断正在执行的程序,并立即转移到相应的中断服务程序中进行处理。
- 中断处理:是指操作系统对中断事件的响应和处理过程。当发生中断时,CPU会立即中断当前正在执行的任务,并转到与中断事件相关的中断服务程序。中断处理程序负责处理中断事件,保存当前任务的上下文,执行中断服务程序,处理中断事件后恢复上下文并返回到原任务。
- 中断服务程序:是与特定中断事件相关联的程序,它负责处理特定的中断事件。每个中断事件都有一个唯一的中断向量或中断号,操作系统根据中断号找到对应的中断服务程序。中断服务程序通常是预先定义好的,它们执行特定的操作来处理中断事件,例如读取设备数据、响应用户输入等。
中断优先级
用于确定中断响应顺序的概念。当多个中断同时发生时,中断控制器会根据中断优先级来确定哪个中断被优先处理。较高优先级的中断将中断较低优先级的中断,并立即处理该中断。
中断优先级通常由硬件或操作系统设定,并可以根据需要进行配置和调整。
- 硬件优先级:硬件级的中断控制器会根据中断号设定优先级,决定中断响应的顺序。
- 软件优先级:操作系统(如RTOS)也可能在软件中设定中断的优先级,通过调度算法来控制哪些中断优先处理。
中断嵌套和屏蔽
- 中断嵌套:一个中断处理程序在执行时,如果发生更高优先级的中断,处理器会暂停当前的
ISR
,转而执行高优先级的ISR
。这种机制允许多级中断处理。 - 中断屏蔽:当处理某个中断时,处理器可以暂时禁用其他中断的响应,防止中断在处理中断时发生。中断屏蔽通常会在
ISR
中进行,防止中断嵌套过深或产生不必要的中断。
中断响应流程
- 保存现场:处理器首先保存当前程序计数器(
PC
)等寄存器值,确保中断处理结束后能恢复到中断前的状态。 - 查找中断向量表:处理器根据中断号从中断向量表中查找对应的中断服务程序入口。
- 执行中断服务程序:执行
ISR
来处理相应的中断事件。 - 恢复现场:中断处理完成后,恢复保存的寄存器值,返回到中断发生前的程序执行状态。
中断的屏蔽与使能
中断控制器一般提供使能和屏蔽功能来控制中断的响应:
- 使能中断:当一个中断源被使能后,处理器会在中断事件发生时响应并跳转到相应的
ISR
。 - 屏蔽中断:可以临时禁用中断,常见的方式是通过设置特定的寄存器位来屏蔽某个或某些中断。操作系统或应用程序通常会在合适的时机屏蔽或使能中断。
中断延迟和实时性
中断延迟(Interrupt Latency
)是指从中断发生到中断服务程序开始执行的时间间隔。对于实时嵌入式系统来说,控制中断延迟至关重要。通常采用以下几种策略来减少中断延迟:
- 使用快速中断处理程序,避免在
ISR
中做复杂处理。 - 硬件中断控制器优化中断的响应时间。
中断与多任务调度
在实时操作系统(RTOS
)中,中断通常会与任务调度结合使用。中断发生时,操作系统会判断是否需要将当前任务挂起并调度一个优先级更高的任务执行。
中断上下文切换
在中断处理期间,ISR
可能会修改一些寄存器的值。为了保证中断处理完后能正确恢复到中断发生前的状态,必须保存当前任务的所有关键寄存器。
- 保存现场:保存当前执行任务的寄存器、程序计数器(PC)、堆栈指针(SP)、处理器状态寄存器(PSR)等。
- 执行ISR:跳转到中断服务程序并执行中断处理逻辑。
- 恢复现场:恢复之前保存的上下文,确保任务能够在中断结束后从中断发生前的状态继续执行。
- 任务调度(如果需要):检查是否需要进行任务切换,若需要,则保存当前任务的上下文,调度新的任务执行。
STM32中断流程
中断到达后判断优先级以及是否使能,之后中断向量表查找并跳转到ISR,执行后返回中断现场
- 中断源触发:硬件设备或外部事件产生中断信号。
- 中断请求:中断信号通过NVIC传递给CPU。
- 中断响应:CPU保存当前上下文(程序计数器、寄存器等)。
- 执行中断服务程序:跳转到ISR并执行相应的处理逻辑。
- 中断结束:恢复现场,恢复中断前的程序执行状态。
- 任务调度(如果需要):如果在ISR中需要任务调度,RTOS调度器会选择下一个任务执行。
- 清除中断标志:ISR结束时清除中断标志,准备响应下一次中断。
main函数和中断函数修改共享变量的注意事项
- 禁用中断:确保访问共享变量时不会被打断,但可能影响系统的实时性。
- 使用
volatile
:避免编译器优化,但不提供线程安全。 - 使用临界区:禁止中断或调度,保护共享变量,但会影响实时性。
- 使用互斥锁或信号量:适用于RTOS中,提供可靠的同步,但有额外开销。
- 原子操作:适用于简单的共享变量操作,在Cortex-M中一般是原子性的。
- 双缓冲:适用于多个事件更新共享数据的情况,避免数据竞争。
中断过多的影响
- 阻塞主任务执行:中断服务程序是 阻塞 的——它会使得CPU无法继续执行主程序(或其他任务)。
- 中断占用率过高,系统响应下降:频繁中断可能导致中断延迟。
- 过多中断嵌套:嵌套过多可能导致堆栈深度增加,引起栈溢出。
- 调试与维护困难。
中断的注意事项
- 中断服务例程(ISR)应该尽量简短
- 中断嵌套和优先级管理:避免高优先级长期阻塞低优先级的中断。
- 禁止中断时应尽量短暂。
- 使用
volatile
关键字处理共享变量 - 避免在中断中使用阻塞操作。
- 数据同步与互斥:使用临界区保护共享资源的访问。
- 避免长时间占用硬件资源和禁用中断。
中断和异常的区别
中断通常用于处理外部事件,而异常则用于处理程序内部错误或特殊情况。
特性 | 中断 (Interrupt) | 异常 (Exception) |
---|---|---|
触发原因 | 外部事件或硬件请求 | 程序内部错误或特殊事件 |
触发方式 | 外部硬件或软件指令 | CPU检测到错误或程序状态异常 |
可恢复性 | 通常可恢复 | 可能不可恢复(如非法指令、除零错误) |
响应方式 | 跳转到中断处理程序(ISR) | 跳转到异常处理程序 |
优先级 | 中断有优先级 | 异常没有优先级(取决于异常类型) |
类型 | 硬件中断、软件中断、可屏蔽中断、不可屏蔽中断 | 同步异常、异步异常 |
影响范围 | 主要影响外设响应和程序执行流 | 主要影响程序的执行和错误处理 |
需要操作系统支持 | 不一定,硬件直接处理 | 通常需要操作系统支持 |
DMA中断
DMA中断机制通过在数据传输完成或发生错误时中断CPU,使得CPU可以及时处理DMA传输结果或异常,从而提高系统效率。
DMA传输完成中断
当DMA传输完成(例如从外设读取数据到内存,或者从内存写入外设数据)时,DMA控制器会触发一个中断。CPU通过此中断获知数据传输已完成,可以继续处理数据。
DMA传输错误中断
如果在DMA传输过程中发生错误(如传输失败、数据越界等),DMA控制器会触发错误中断,CPU能够捕获并处理这个错误。
DMA中断的响应
- 中断使能:在DMA配置时,需要启用DMA的中断功能,这通常通过设置DMA控制寄存器来完成。
- 中断处理:当DMA中断触发时,CPU中断当前执行的程序,跳转到DMA中断处理程序。处理中断后,通常需要清除中断标志位,并根据需要继续后续的任务。
NVIC
NVIC(Nested Vectored Interrupt Controller
) 是 ARM Cortex-M
系列处理器中的一个关键组件,负责管理和控制中断请求(IRQ
)的处理。
NVIC的主要作用
-
中断管理
- NVIC 负责接收、响应和管理来自外部设备和内部模块的中断请求(
IRQ
)。 - NVIC 可以使处理器能够响应多个并行的中断事件,而无需每个中断都占用单独的处理器资源。
- NVIC 负责接收、响应和管理来自外部设备和内部模块的中断请求(
-
优先级控制
- NVIC 提供了中断优先级管理机制。每个中断源都可以设置一个优先级,优先级较高的中断会被优先处理,优先级低的中断则需要等较高优先级的中断处理完成后才能被响应。
- 优先级的设置通常是基于数值,较小的数值表示较高的优先级。
-
嵌套中断
- NVIC 支持嵌套中断,即高优先级的中断可以打断低优先级的中断服务程序。这使得系统能够及时响应关键事件,如硬件故障、中断请求等。
- 低优先级的中断如果在高优先级中断的处理中断发生,它将在高优先级中断处理完成后执行。
-
中断屏蔽
- NVIC 可以屏蔽或禁止特定的中断,使得在特定的情况下,不处理某些中断请求。例如,在进入关键代码段时,可以临时禁止中断,以避免中断干扰。
-
中断向量表管理
- NVIC 与中断向量表密切配合。当发生中断时,NVIC 根据中断号(IRQ)查找中断向量表中的对应地址,并将控制权转交给对应的中断服务例程(ISR)。
-
延迟中断处理
- NVIC 允许中断请求被延迟处理。这意味着在高优先级中断被处理时,低优先级中断请求会被保留,等到高优先级中断处理完成后,再去响应低优先级中断。
-
中断优先级分组
- 在一些 Cortex-M 系列处理器中,NVIC 允许将优先级分为多个分组(如抢占优先级和子优先级)。这为复杂的系统提供了更加灵活的中断优先级配置。
NVIC的具体功能
- 中断使能与禁用:通过设置和清除特定的寄存器位,
NVIC
可以启用或禁用特定的中断。 - 中断优先级设置:通过配置
NVIC
中的优先级寄存器,可以为每个中断设置不同的优先级。 - 中断触发:
NVIC
可以通过外部事件(如硬件中断)、软件触发或系统异常来触发中断请求。 - 向量表管理:
NVIC
会根据向量表中的地址来定位中断处理程序。
NVIC常用寄存器
-
ISER(Interrupt Set Enable Register):启用中断。通过设置对应位来启用特定中断。
-
ICER(Interrupt Clear Enable Register):用于禁用中断。通过清除对应位来禁用特定中断。
-
IPR(Interrupt Priority Register):用于设置中断优先级。每个中断源都有一个优先级设置,优先级越高,数值越小。
-
ISPR(Interrupt Set Pending Register): 用于设置某个中断为待处理状态。可以通过设置此寄存器的相应位来产生一个软件中断。
-
ICPR(Interrupt Clear Pending Register):用于清除待处理状态。通过清除该寄存器的相应位来消除中断请求。
-
IABR(Interrupt Active Bit Register): 用于查看中断是否处于活动状态。