ARM中断 - ARM内核(五)

ARM内核中断是ARM异常的一种,用来实现外部数据和外部硬件之间进行通信。内核每次执行完一条指令都会查询其硬件中断情况,如果此时硬件硬件中断信号被拉起来,就会触发中断异常,跳转到异常向量表处理。作为SOC复杂片上系统管理众多外部硬件设备,不可能在内核中开发众多的硬件信号给各个外设。一次在SOC设计时会在ARM内核外增加一道多层辅助的中断控制网络,这种中断网络针对不同SOC设计或者不同公司是的不同系列产品其中断IP是不一致的。前面提到内核转到中断向量表进行进行代码执行,结合复杂的外部硬件控制器网络(类似GIC),在这部分代码处理中会读取中断控制网络器中的数据进行复杂的中断网络处理。对于内核的中断异常,很难使用独立的代码出发硬件类型中断让内核处于中断异常,都是需要结合外部中断网络来完成的。但其实中断异常内核的异常基本处理流程和其他类型的异常没有本质差别,核心差别在于内容处理这里需要获取SOC上面的中断控制器来配合完成整个中断体系的管理。基于如上两点,我们这里不专门针对ARM内核的中断异常进行实验,而是主要针对外部中断控制器来完成整体的工作。本篇文章实际上不属于ARM内核部分内容,更应该是SOC的内容。

本篇主要是针对SOC硬件中断控制器内容进行讲解,讲解中断硬件配置和使用,对于中断软件的处理只是给定了简单的串口打印。关于复杂的软件处理中断流程,看Linux的中断体系架构文章。

1. 中断体系

在SOC中包含了ARM内核,ARM内核其他的异常模式功能相应默认是打开的,但是ARM内核是否响应外部中断控制器通给其的硬件中断信号是需要对ARM的CPSR状态寄存器中断使能控制为配置的。正常情况下,对齐配置1为使能外部中断响应,这个时候整个外部的中断网络中的中断信息才可能被ARM内核响应。

1.1 中断硬件架构

中断是一种特殊的异常模式,用来实现外部器件打断CPU内核的运行。中断基本的硬件框架如下:

  • 中断源。中断源多种多样,比如GPIO、定时器、UART、DMA等等。它们都有自己的寄存器,可以进行相关设置:使能中断、中断状态、中断类型等等。

  • 中断控制器。各种中断源发出的中断信号,汇聚到中断控制器进行统一管理。可以在中断控制器中设置各个中断的优先级。中断控制器会向CPU发出中断信号,CPU可以读取中断控制器的寄存器,判断当前处理的是哪个中断。中断控制器有多种实现,比如:

    • STM32F103中被称为NVIC:Nested vectored interrupt controller(嵌套向量中断控制器)

    • ARM9中一般是芯片厂家自己实现的,没有统一标准

    • Cortex A7中使用GIC(Generic Interrupt Controller)

  • CPU。CPU每执行完一条指令,都会按照设计的扫描优先级依次判断一下是否有中断发生了。CPU也有自己的寄存器,可以设置它来使能/禁止中断,这是中断处理的总开关。

    • 对于低端的芯片可能直接是打开状态,或者某一个内部寄存器

    • 对于高端的ARM芯片通过设置程序状态寄存器中IRQ使能标识来打开

1.2 实例 - TM32F103

ARM中断 - ARM内核(五)_第1张图片

对于GPIO中断,STM32F103又引入了External interrupt/event controller (EXTI)。用来设置GPIO的中断类型并进行GPIO的管理。对于串口或者网口相关的额中断直接链接在NVIC中断控制器上面进行管理。EXTI可以给NVIC提供16个中断信号:EXTI0~EXTI15。那么某个EXTIx,它来自哪些GPIO呢?这需要设置GPIO控制器完成这种映射关系的对应。

1.3 实例 - imx6ull

对于imx6ull这种A7类型开发板外部所有中断都是统一通过General Interrupt Control来控制管理,如果中断已经触发,就将CPU与GIC对应的中断硬件拉高触发相关的中断。当然CPU处理中断过程中也可以将中断控制器的屏蔽寄存器打开或者直接去使能中断触发,这个时候GIC就没有办法像CPU汇报自己中断处理以后的结果。

ARM中断 - ARM内核(五)_第2张图片

 需要另外注意的一个点是对于高端的芯片GIC可以针对多核CPU进行管理,也就是说GIC可以配置某种类型的中断只发给某个CPU核,同时CPU核之间也可以通过GIC完成互相通信。另外加上CPU内部的一些定时器触发自身中断。也即是说高端CPU核一般有三张类型的中断。

2. 中断优先级与嵌套

2.1 中断优先级

中断优先级的管理都是在中断控制器(GIC或NVIC)中管理完成完成。在说到中断之前,我先来定义一下优先级,明白了什么是优先级,后面的阐述就容易明白了。实际上很多人都是混淆了优先级的含义,所以才觉得糊里糊涂。中断的优先级有两个:查询优先级和执行优先级。

  •  什么是查询优级呢?我们从datasheet或书上看到的默认(IP寄存器不做设置,上电复位后为00H)的优先级:外部中断0 > 定时/计数器0 > 外部中断1 > 定时/计数器1 > 串行中断。或 int0,timer0,int1,timer1,serial port 或 INT0、T0、INT1、T1、UART。或 PX0>PT0>PX1>PT1>PS>......

其实都是查询优级。首先查询优先级是不可以更改和设置的,这个是硬件设计中断控制器这种中断控制状态机的时候固定下来的。这是一个中断优先权排队的问题。是指多个中断源同时产生中断信号时,中断仲裁器选择对哪个中断源优先处理的顺序。而这与是否发生中断服务程序的嵌套毫不相干。当CPU查询各个中断标志位的时候,会依照上述5个查询优先级顺序依次查询,当数个中断同时请求的时候,会优先查询到高优查询先级的中断标志位,但并不代表高查询优先级的中断可以打断已经并且正在执行的低查询优先级的中断服务。

例如:当计数器0中断和外部中断1(按查询优先级,计数器0中断>外部中断1)同时到达时,会进入计时器0的中断服务函数;但是在外部中断1的中断服务函数正在服务的情况下,这时候任何中断都是打断不了它的,包括逻辑优先级比它高的外部中断0计数器0中断。

  • 中断的执行优先级就是你对IP寄存器的设置了。在2个优先级的情况下,某位为1,则相应的中断源为高优先级;为0,则为低优先级。对于ARM系统存在多个优先级,数字越小优先级越高,也即是说0号中断优先级最高。

关于中断的优先级有三条原则:

1、CPU同时接收到几个中断时,首先响应优先级最高的中断请求;但如果优先级序列最高的存在多个中断,这个时候按照查询优先级(中断向量表的前后顺序)来执行中断处理程序;

2、正在进行的中断过程不能被新的同级或低行优优先级的中断请求所中断(实际硬件细节是中断控制器进行判定,它会记录当前自己发送给CPU的中断是什么以及优先级,如果新来的优先级比这个优先级低,中断控制器就直接拦下来,不会拉中断消息传输引脚告知CPU);

3、正在进行的低行优优先级中断服务,能被高行优优先级中断请求中断;

若:同一执行优先级中的中断申请不止一个时,则有一个中断优先权排队问题。同一执行优先级的中断优先权排队,由中断系统硬件确定的自然优先级形成,优先权自高到低的顺序即:

外部中断0>定时/计数0>外部中断1>定时/计数1>串行接口

例如:设置IP = 0x10,即设置串口中断为最高优先级,则串口中断可以打断任何其他的中断服务函数实现嵌套,且只有串口中断能打断其他中断的服务函数。若串口中断没有触发,则其他几个中断之间还是保持逻辑优先级,相互之间无法嵌套。

2.2. 中断嵌套

中断嵌套是中断发生的一种情况,这种情况条件是中断优先级高的中断在中断优先级低的中断处理过程中发生,这个时候中断控制器会通过硬件接口传递信息给CPU新的中断发生。中断嵌套过程中断控制器工作如前所讲是比较简单的,但是中断嵌套现场保存合计恢复过程确实复杂的,这个复杂过程可以CPU自己硬件设计做(M3),也可以软件完成(A7)。现场保存过程实际是将CPU内部相关的寄存器保存到一个不会被改写的存储器位置,至于这种存储器类型根据不同的处理器内容可能不一样(SDRAM或者ERAM)。实际较大的系统当中中断嵌套发生的概率是非常大的。中断现场保存于恢复相比于函数栈的调用过程信息保存两者极为类似,差别是函数调用过程由于函数形式确定,函数保存和恢复的现场都是确定的。但是对于中断发生时机不确定,保存的数据自然也是尽可能多,进而保证数据不被丢失。中断过程相比于函数会多保存过个普通寄存器An,同时还会保存程序状态寄存器。

3. 代码实例

你可能感兴趣的:(ARM与裸机开发,ARM,汇编,中断)