ARM架构异常和中断
@TOC
前言
本篇文章将带大家学习ARM架构中的异常和中断,中断是大家都比较熟悉的,异常大家可能不是那么熟悉,那么这篇文章将会以ARM架构出发给大家介绍这些内容。
一、异常和中断的概念
异常(Exception):
概念:在嵌入式系统中,异常是指发生在 CPU 执行指令期间的不寻常情况或错误情况。这些情况可能包括除零错误、内存访问错误、非法指令执行等。异常可能由软件错误、硬件故障或外部干扰引起。
处理方式:当异常发生时,CPU 会暂停当前任务的执行,并跳转到异常处理程序。在嵌入式系统中,异常处理程序通常由操作系统或者硬件提供,用于识别异常的原因并采取相应的措施,例如记录日志、重启系统、恢复到安全状态等。
中断(Interrupt):
概念:在嵌入式系统中,中断是由外部事件触发的一种机制,用于打断 CPU 的正常执行流程,以响应特定的事件或请求。这些外部事件可能包括定时器溢出、硬件设备状态变化、外部信号输入等。
处理方式:当外部事件发生时,相关的中断信号会发送到 CPU,CPU 立即中断当前执行的任务,并跳转到中断服务程序(ISR,Interrupt Service Routine)。中断服务程序是预先定义好的,用于处理特定中断的代码段。一旦中断服务程序执行完成,CPU 将恢复到之前中断前的状态,继续执行之前的任务。
中断是一种特殊的异常:
关系:在某种程度上,中断可以被视为异常的一种特殊情况。它们都是处理系统中非正常事件的机制,都会导致 CPU 的执行流程被打断。但与通常的异常不同,中断通常是由外部事件触发的,而异常则可能是由于程序错误、硬件故障或其他内部原因而引发的。
特点:中断是一种更具体的异常,因为它们与特定的外部事件相关联,而异常可能包括更广泛范围的问题。同时,中断通常具有更高的优先级,因为它们需要及时响应外部事件,保证系统的实时性和可靠性。
在嵌入式系统中,异常和中断都是为了处理非正常情况和外部事件而设计的机制,它们共同确保了系统能够有效地响应各种情况下的事件,并保持稳定和可靠的运行状态。
二、NVIC中断控制器
1.中断优先级管理: NVIC允许每个中断源分配优先级,这样可以确保在多个中断同时发生时,处理器可以按照优先级顺序处理中断请求。优先级编码通常是由最高优先级 0 到最低优先级 n(取决于架构)。
2.中断向量表(Interrupt Vector Table): NVIC使用中断向量表来确定每个中断源的入口地址。在ARM Cortex-M架构中,这个表是在特定的内存位置上,通常是在程序的起始地址处。当发生中断时,NVIC使用中断编号作为索引来检索中断向量表中的入口地址,并将处理器的执行流程转移到相应的中断服务程序(ISR)。
3.中断使能和禁用: NVIC允许开发者通过配置来使能或禁用特定的中断源。这样可以根据应用程序的需要,选择性地启用或禁用中断。
4.中断处理器: NVIC还负责中断请求的管理和响应。当一个中断请求发生时,NVIC会检查相应中断的使能状态和优先级,并根据这些信息决定是否立即响应中断。
5.中断嵌套: NVIC支持中断的嵌套处理。这意味着当一个中断服务程序正在执行时,如果发生了更高优先级的中断请求,处理器会暂停当前的中断服务程序,转而执行更高优先级的中断服务程序。这样可以确保处理器能够及时地响应重要的中断请求。
NVIC是ARM Cortex-M处理器中非常重要的一个组件,它负责管理系统中的中断请求,包括优先级管理、中断使能和禁用、中断向量表管理等功能,确保系统能够高效地响应和处理各种中断事件。
NVIC接收多个中断源的请求:
三、ARM架构中对中断的处理流程
1.初始化:
设置中断源: 在开始处理中断之前,需要明确定义哪些事件或条件会触发中断,这些就是中断源。中断源可以是外部事件(例如GPIO引脚的状态改变)、定时器溢出、外设传输完成等。
设置中断控制器(NVIC): 中断控制器是负责管理和处理中断的硬件模块。在初始化阶段,需要配置中断控制器,包括设置中断优先级、使能或禁用特定中断等。
设置CPU总开关: 在开始执行程序之前,需要确保CPU的中断总开关是开启的。这样,CPU才会响应和处理中断事件。
2.执行程序:
当CPU开始执行程序时,它会按照指令序列逐条执行程序代码。
3.产生中断:
当某个设置的中断源触发时,例如外部引脚状态改变、定时器溢出等,会产生中断请求信号。
4.CPU检查中断:
当CPU执行完当前指令后,会检查中断总开关是否开启以及是否有中断请求发生。如果没有中断请求,CPU将继续执行下一条指令;如果有中断请求,则进入中断处理流程。
5.异常产生:
除了中断外,还有可能发生异常,例如除零、未定义指令等。当这些异常发生时,CPU也会进入异常处理流程。
6.开始处理中断或异常:
当CPU发现有中断或异常发生时,会按照一定的优先级和逻辑开始处理中断或异常。
如果是中断,首先会根据中断优先级判断是否需要暂时挂起当前任务,然后根据中断号查找中断向量表,跳转到相应的中断服务程序(ISR)执行中断处理代码。
如果是异常,CPU会根据异常类型和优先级进入相应的异常处理程序,处理异常情况。
四、中断处理流程的三个关键步骤
中断处理流程是处理器在响应中断事件时执行的一系列步骤,包括保存当前执行环境(现场)、执行中断服务程序(处理现场)以及恢复之前的执行环境。以下是中断处理流程的详细解释:
1.保存现场:
当外部设备产生中断信号并被处理器接收到时,处理器会立即暂停正在执行的程序,并将当前的执行状态保存到内存中。这包括处理器的寄存器内容、程序计数器(PC)以及其他与执行环境相关的信息。保存现场的目的是为了确保在处理完中断后,程序能够恢复到中断发生前的状态,继续执行。
2.处理现场:
一旦现场被保存,处理器会根据中断类型和优先级,从中断向量表中找到对应的中断服务程序(Interrupt Service Routine,ISR),并开始执行该程序。ISR是用来处理特定中断事件的代码块,通常由系统开发人员编写。
在ISR中,处理器会执行与中断相关的处理操作,可能包括读取外部设备的数据、处理数据、更新系统状态等。ISR的执行时间应尽量短,以确保系统的响应速度和效率。
3.恢复现场:
当ISR执行完成后,处理器需要恢复到中断发生前的执行状态,继续执行被中断的程序或其他任务。为此,处理器会从之前保存的现场中恢复寄存器的内容、程序计数器等执行环境信息。
一旦执行环境恢复完毕,处理器会继续执行被中断打断的程序,从中断发生的地方或者中断返回地址处继续执行。这样,程序的执行就能够无缝地继续下去,就好像中断事件从未发生过一样。
五、调用者寄存器和被调用者寄存器
调用者保存寄存器(Caller-Saved Registers)
定义:调用者保存寄存器是指在函数调用过程中,如果调用者(即函数调用前的代码)希望保留这些寄存器中的值,那么它需要在调用另一个函数之前自行保存这些寄存器的值。这是因为被调用的函数(callee)可能会修改这些寄存器的内容。
目的:这种规定使得被调用的函数不需要在进入和退出时保存和恢复所有寄存器的状态,从而减少了不必要的操作,提高了效率。
例子:在ARM架构中,通常 R0-R3(用于参数传递和返回值)和 R12(内部临时寄存器)被认为是调用者保存寄存器。
被调用者保存寄存器(Callee-Saved Registers)
定义:被调用者保存寄存器是指在函数调用过程中,如果这些寄存器的值被修改了,那么在函数返回前,被调用的函数(callee)负责恢复这些寄存器的原始值。这样做的目的是保证调用者在函数调用后,这些寄存器的值不会发生变化。
目的:通过要求被调用者保存和恢复这些寄存器的值,可以确保函数调用不会影响调用者的执行环境,从而简化了函数调用的复杂性。
例子:在ARM架构中,通常 R4-R11 和 R13(堆栈指针,SP)被认为是被调用者保存寄存器。
总结
本篇文章主要讲解了ARM中架构异常和中断的基础概念,下篇文章我们将开始写代码。
- 点赞
- 收藏
- 关注作者
评论(0)