首页 » 智能 » 11. 基于ARM Cortex-A9中断详解_优先级_存放器

11. 基于ARM Cortex-A9中断详解_优先级_存放器

萌界大人物 2025-01-05 01:25:25 0

扫一扫用手机浏览

文章目录 [+]

有了中断系统才可以不用一贯轮询(polling)是否有事宜发生,系统效率才得以提高。

一样平常在系统中,中断掌握分为三个部分:「模块、中断掌握器和处理器」。

11. 基于ARM Cortex-A9中断详解_优先级_存放器 11. 基于ARM Cortex-A9中断详解_优先级_存放器 智能

个中模块常日由寄存器掌握是否使能中断和中断触发条件等;中断掌握器可以管理中断的优先级等,而处理器则由寄存器设置用来相应中断。

11. 基于ARM Cortex-A9中断详解_优先级_存放器 11. 基于ARM Cortex-A9中断详解_优先级_存放器 智能
(图片来自网络侵删)
二、GIC

作为 ARM 系统中通用中断掌握器的是 GIC(Generic Interrupt Controller),目前有四个版本,V1~V4(V2最多支持8个ARM core,V3/V4支持更多的ARM core,紧张用于ARM64系统构造)。

【把稳】对付一些老的ARM处理器,比如ARM11,Cortex-A8,中断掌握器一样平常是VIC(向量中断掌握器)。

1. GIC-400

下面以GIC-400为例,它更适宜嵌入式系统,符合v2版本的GIC architecture specification。
GIC-400通过AMBA(Advanced Microcontroller Bus Architecture)片上总线连接到一个或者多个ARM处理器上。

GIC中断掌握器全局图

从上图可以看出, GIC 是联系外设中断和 CPU 的桥梁,也是各 CPU 之间中断互联的通道(也带有管理功能),它卖力检测、管理、分发中断,可以做到:

使能或禁止中断;把中断分组到Group0还是Group1(Group0作为安全模式利用连接FIQ ,Group1 作为非安全模式利用,连接IRQ );多核系统中将中断分配到不同处理器上;设置电平触发还是边沿触发办法(不即是外设的触发办法);虚拟化扩展。

ARM CPU 对外的连接只有2 个中断: 「IRQ和FIQ」 ,相对应的处理模式分别是一样平常中断(IRQ )处理模式和快速中断(FIQ )处理模式。
以是GIC 末了要把中断搜集成2 条线,与CPU 对接。

GIC中断掌握器构造

分发器:卖力各个子中断使能,设置触发办法,优先级排序,分发到哪个 CPU 上; 接口:卖力总的中断的使能,状态的掩护。

2. 分发器功能

分发器的紧张的浸染是检测各个中断源的状态,掌握各个中断源的行为,分发各个中断源产生的中断事宜到指定的一个或者多个CPU接口上。
虽然分发器可以管理多个中断源,但是它总是把优先级最高的那个中断要求送往CPU接口。
分发器对中断的掌握包括:

(a)中断使能或禁能掌握。
分发器对中断的掌握分成两个级别,一个是全局中断的掌握(GIC_DIST_CTRL),一旦禁能了全局的中断,那么任何的中断源产生的中断事宜都不会被通报到CPU接口;其余一个级别是对针对各个中断源进行掌握(GIC_DIST_ENABLE_CLEAR),禁能某一个中断源会导致该中断事宜不会分发到CPU接口,但不影响其他中断源产生中断事宜的分发。
(b)掌握将当前优先级最高的中断事宜分发到一个或者一组CPU接口。
(c)优先级掌握。
(d)中断属性设定,例如是电平触发还是边沿触发。
(e)中断的设定。

分发器可以管理多少个中断源,这些中断源用ID来标识,我们称之interrupt ID。

3. CPU接口功能

CPU接口紧张用于和CPU进行接口。

紧张功能包括:

(a)使能或者禁能CPU接口向连接的CPU提交中断事宜。
对付ARM,CPU接口和CPU之间的中断旗子暗记线是nIRQCPU和nFIQCPU。
如果禁能了中断,那么即便是分发器分发了一个中断事宜到CPU接口,但是也不会提交指定的nIRQ或者nFIQ关照CPU。
(b)ackowledging中断。
CPU会向CPU接口应答中断,中断一旦被应答,分发器就会把该中断的状态从pending状态修正成active,如果没有后续pending的中断,那么CPU 接口就会deassert nIRQCPU和nFIQCPU旗子暗记线。
如果在这个过程中又产生了新的中断,那么分发器就会把该中断的状态从pending状态修正成pending and active。
此时,CPU接口仍旧会保持nIRQ或者nFIQ旗子暗记的asserted状态,也便是向CPU关照下一个中断。
(c)中断处理完毕的关照。
当中断处理器处理完了一个中断的时候,会向写CPU 接口的寄存器从而关照GIC已经处理完该中断。
做这个动作一方面是关照分发器将中断状态修正为deactive,其余一方面,可以许可其他的pending的中断向CPU接口提交。
(d)设定优先级掩码。
通过优先级掩码可以mask掉一些优先级比较低的中断,这些中断不会关照到CPU。
(e)设定中断抢占的策略。
(f)在多个中断事宜同时到来的时候,选择一个优先级最高的关照CPU。

key中断管理模块图

以上图为例,该图是按键产生的中断旗子暗记要到达cpu所要经由的路径。

外设中断源有很多,常日芯片厂商会设计多少个第一级中断掌握器,进行第一次处理,key连接的是GPX1中断掌握器,寄存器EXT_INT41_MASK用于使能该中断;GIC紧张包括分排气和cpu interface;ICDISER用于使能分派器,ICDIPTR用于将中断旗子暗记分发给对应的cpu interface;ICCICR用于使能CPU interface;CPU上有两个引脚irq、fiq,gic终极会连接到CPU的irq,所有寄存器配置完毕后,按键一旦按下,那么就会给CPU的irq发送一个中断旗子暗记,cpu紧接着就会实行“4大步3小步”,进入中断非常处理流程。
三、中断分类1. 中断源硬件中断(Hardware Interrupt)可屏蔽中断(maskable interrupt)。
硬件中断的一类,可通过在中断屏蔽寄存器中设定位掩码来关闭。
非可屏蔽中断(non-maskable interrupt,NMI)。
硬件中断的一类,无法通过在中断屏蔽寄存器中设定位掩码来关闭。
范例例子是时钟中断(一个硬件时钟以恒定频率—如50Hz—发出的中断)。
处理器间中断(interprocessor interrupt)。
一种分外的硬件中断。
由处理器发出,被其它处理器吸收。
仅见于多处理器系统,以便于处理器间通信或同步。
伪中断(spurious interrupt)。
一类不肯望被产生的硬件中断。
发生的缘故原由有很多种,如中断线路上电气旗子暗记非常,或是中断要求设备本身有问题。
软件中断(Software Interrupt)

软件中断SWI,是一条CPU指令,用以自陷一个中断。
由于软中断指令常日要运行一个切换CPU至内核态的子例程,它常被用作实现系统调用(System call)。

外部中断I/O设备:如显示器、键盘、打印机、A / D转换器等。
数据通道:软盘、硬盘、光盘等。
数据通道中断也称直接存储器存取(DMA)操作中断,如磁盘、磁带机或CRT等直接与存储器交流数据所哀求的中断。
实时时钟:如外部的定时电路等。
在掌握中碰着定时检测和掌握,为此常采取一个外部时钟电路(可编程)掌握其时间间隔。
须要定时时,CPU发出命令使时钟电路开始事情,一旦到达规定韶光,时钟电路发出中断要求,由CPU转去完成检测和掌握事情。
用户故障源:如掉电、奇偶校验缺点、外部设备故障等。
产生于CPU内部的中断源由CPU的运行结果产生:如除数为0、结果溢出、断点中断、单步中断、存储器读出出错等。
实行中断指令swi造孽操作或指令引起非常处理。
2. 中断类型

GIC 中断类型有3种:SGI(Software-generated interrupt)、PPI(Private peripheral interrupt )、SPI(Shared peripheral interrupt)。

SGI: SGI为软件可以触发的中断,统一编号为0~15(ID0-ID7是不屈安中断,ID8-ID15是安全中断),用于各个core之间的通信。
该类中断通过干系联的中断号和产生该中断的处理器的CPUID来标识。
常日为边沿触发。
PPI: PPI为每个 core 的私有外设中断,统一编号为 16-31 。
例如每个 CPU 的 local timer 即 Arch Timer 产生的中断便是通过 PPI 发送给 CPU 的(安全为29,非安全为30)。

常日为边沿触发和电平触发。

SPI: SPI 是系统的外设产生的中断,为各个 core 公用的中断,统一编号为 32~1019 ,如 global timer 、uart 、gpio 产生的中断。
常日为边沿触发和电平触发。

Note:电平触发是在高或低电平保持的韶光内触发, 而边沿触发是由高到低或由低到高这一瞬间触发;在GIC中PPI和SGI类型的中断可以有相同的中断ID。

3. 中断分派模式1-N mode (SPIs using the GIC 1-N model) 表示中断可以发给所有的CPU,但只能由一个CPU来处理中断;换句话说,这种类型的中断有N个目标CPU,但只能由个中一个来处理;当某一个处理器应答了该中断,便会打消在所有目标处理器上该中断的挂起状态。
N-N mode (PPIs and SGIs using the GIC N-N model) 表示中断可以发给所有CPU,每个CPU可以同时处理该中断。
当该中断被某一个处理器应答了,这不会影响该中断在其他CPU接口上的状态。

举两个例子解释:

1)UART 吸收到一包数据,产生了一个中断给GIC,GIC可以将该中断分配给CPU0-7中任何一个处理;假设该中断分配给CPU0处理了,那么在中断处理函数里面会把吸收到的数据从UART FIFO读出。
可以想象一下,如果CPU0在读数据时,其余一个CPU也在处理该中断,适值也在读数据,那么CPU0读到的数据是不全的。
这便是1-N model中断,或者说SPI中断。

2)比如CPU0给CPU1-7发送中断,想奉告对方自己正在处理某个进程A。
这种场景下,CPU1-7都吸收到中断,都进入中断处理函数,CPU1-7获取到CPU0的信息后,在进程调度时,就可以绕开进程A,而自己调度其他进程。

注:这个例子只是解释N-N model,实际上进程调度不都全是这样的。

4. 通用中断处理

当GIC吸收到一个中断要求,将其状态设置为Pending。
重新产生一个挂起状态的中断不影响该中断状态。
中断处理顺序: ① GIC决定该中断是否使能,若没有被使能对GIC没有影响; ② 对付每个Pending中断,GIC决定目标处理器; ③ 对付每个处理器 ,Distributor根据它拥有的每个中断优先级信息决定最高优先级的挂起中断,将该中断通报给目标CPU Interface; ④ GIC Distributor将一个中断通报给CPU Interface后,该CPU Interface决定该中断是否有足够的优先级将中断要求发给CPU; ⑤ 当CPU开始处理该非常中断,它读取GICC_IAR应答中断。
读取的GICC_IAR获取到中断ID,对付SGI,还有源处理器ID。
中断ID被用来查找精确的中断处理程序。

GIC识别读过程后,将改变该中断的状态: a) 当中断状态变为active时,如果该中断挂起状态持续存在或者中断再次产生,中断状态将从Pending转化为pending & active b) 否则,中断状态将从pending状态变为active

⑥ 当中断完成中断处理后,它须要关照GIC处理已经完成。
这个过程称为 priority drop and interrupt deactivation: a) 总是须要向EOIR寄存器写入一个有效的值(end of interrupt register) b) 也须要接着向GICC_DIR写入值(deactivate interrupt register)

5. 中断优先级

软件可以通过给每一个中断源分配优先级值来配置中断优先级。
优先级的值是个8位的无符号二进制数,GIC支持最小16和最大256的优先级级别。
如果GIC实现的优先级少于256,那么优先级字段的低阶位为RAZ/WI。
这就意味其实现的优先级字段个数范围是4~8,如下图所示:

Effect of not implementing some priority field bits

Note: 1)、如何确定优先级字段所支持的优先级位? 通过软件往可写GICD_IPRIORITYn优先级字段写入0XFF,然后回读出该字段的值便可以确定优先级字段所支持的优先级位(由于有些位没实现是RAZ/WI) 2)、ARM 推举在检讨中断优先级范围之前先: • 对付外设中断,软件先禁用该中断 • 对付SGI,软件先检讨该中断确定为inactive

6. 中断抢占

在一个active中断处理完之前,CPU interface支持发送更高优先级的挂起中断到目标处理器。
这种情形必要条件如下:

该中断的优先级高于当前CPU interface 被屏蔽的优先级该中断的组优先级高于正在当前CPU interface处理的中断优先级7. 中断屏蔽

CPU interface的GICC_PMR寄存器定义了目标处理器的优先级阀值,GIC仅上报优先级高于阀值的pending中断给目标处理器。
寄存器初始值为0,屏蔽所有的中断。

四、FS4412中断外设-key

下面我们来剖析FS4412开拓板的第一个中断设备按键。

1. 电路图

key

由该电路图可得:

按键k2 连接在GPX1_1引脚掌握逻辑 k2 按下 ---- K2闭合 ---- GPX1_1 低电压 k2 常态 ---- K2打开 ---- GPX1_1 高电压

以下是key2与soc的连接,

key与soc的连接

可以看到key2复用了GPIX1_1这个引脚,同时该引脚还可以作为中断【XEINT9】利用。

顺便看下GPXCON寄存器的配置

GPX1CON

由上图所示,

GPX1CON地址为0x1100C20;key2如果要做为输入设备,只须要将GPX1CON[7:4]设置为0x0;key2如果要做为中断旗子暗记,只须要将GPX1CON[7:4]设置为0xf。
2. key中断处理中断配置

key与soc的关系图如下图所示:

按键中断寄存器配置流程

由上图所示:

按键是直接连到GPIO掌握器的EXT_INT_CON用来设置按键中断的触发办法,低落沿触发GPX1CON寄存器用于设置该GPIO位中断旗子暗记输入EXT_INT_MASK用于使能该中断ICDISER用于使能相应中断到分配器ICDDCR分配器开关ICDIPTR选择CPU接口ICCPMR设置中断屏蔽优先级ICCICR打开CPU开关,把CPU接口内的中断能够送到相应的CPU清中断

CPU处理完中断,须要打消中断,对付按键来说,有3个寄存器须要操作:

清中断

由上图所示:

EXT_INT41_PEND清相应的中断源ICDICPR中断结束后,清相应中断标志位,此标志位由硬件置位ICCEOIR中断实行结束,清cpu内相应的中断号,由硬件添补3. 寄存器汇总

前面剖析了按键连接的是GPX1_1,现在我们来看下对应的寄存器该当如何配置

【1】、GPIO掌握器GPX1PUD

将GPX1_1引脚的上拉和下拉禁止

GPX1PUD[3:2]=0b00;GPX1CON

GPX1CON

将GPX1_1引脚功能设置为中断功能

GPX1CON[7:4]=0xfEXT_INT41CON

EXT_INT41CON

配置成成低落沿触发:

EXT_INT41CON[6:4]=0x2EXT_INT41_MASK

EXT_INT41_MASK

中断使能寄存器

EXT_INT41_MASK[1]=0b0EXT_INT41_PEND 中断状态寄存器

EXT_INT41_PEND

当GPX1_1引脚吸收到中断旗子暗记,中断发生,中断状态寄存器EXT_INT41_PEND 相应位会自动置1 把稳:中断处理完成的时候,须要打消相应状态位。
置1清0.

EXT_INT41_PEND[1]=0b1【2】GIC

根据外设中断名称EINT9来查看该中断对应的GIC中掩护的HW id。
【所有的中断源在芯片厂商设计的时候都分配了唯一的一个ID,GIC通过该ID来驱动中断源】

查看芯片手册(datasheet -- 9.2表)

GIC中断源表

通过【9.2中断源表】找到和外设中断标示对应的中断掌握器中断标识(GPIO有32个可被唤醒寄存器)其对应「EINT[9],中断ID为57」,这是非常主要的,在后面的寄存器设置中起很大浸染;

1) ICDISER使能相应中断到分配器

ICDISER

ICDISER用于使能相应中断到分配器,一个bit掌握一个中断源,一个ICDISER可以掌握32个中断源,这里INT[9] 对应的中断ID为57,以是在ICDSER1中进行设置,57/32 =1余25,以是这里在ICDISER1第25位置一。

ICDISER.ICDISER1|=(0x1<<25);//57/32=1...25取整数(那个寄存器)和余数(哪位)ICDIPTR选择CPU接口

ICDIPTR

ICDIPTR

选择cpu

ICDIPTR寄存器每8个bit 掌握一个中断源,个中CPU0可以处理160个中断源,以是须要40个寄存器。
要选择cpu0第一个bit必须是1。

设置SPI[25]/ID[57]由cpu0处理,57/4=16余1 以是选择寄存器ICDIPTR14的第2个字节[15:8]。

//SPI25interruptsaresenttoprocessor0//57/4=14..114号寄存器的[15:8]ICDIPTR.ICDIPTR14|=0x01<<8;ICDDCR使能分配器

还寄存器用于使能分配器。

ICDDCR=1;ICCPMR 优先级屏蔽寄存器,设置cpu0能处理所有的中断。
比如中断屏蔽优先级为255,该值表示优先级最低,所有的中断都能相应。

ICCPMR

CPU0.ICCPMR=0xFF;//设置cpu0中断屏蔽优先级为255最低,所有中断都能相应)ICCICR 全局使能cpu0中断处理

ICCICR

EXYNOS 4412一共有4个cpu,用4个寄存器分别来掌握4个cpu,每个寄存器的bit[0]用于全局掌握对应的cpu。
我们选择cpu0处理中断,将bit[0]置1即可。

CPU0.ICCICR|=0x1;使能中断到CPU。
ICCIAR

ICCIAR

当中断发生之后,中断的HW id值会由硬件写入到寄存器ICCIAR[9:0]中;对付SGIs来说,多处理器环境下,CPU的interface值写入到[12:10]中。

读取HW id:

intirq_num;irq_num=CPU0.ICCIAR&0x3ff;//获取中断号五、代码实现

要处理中断非常,必须安装非常向量表,非常的处理流程可以参考前面的文章《6. 从0开始学ARM-非常、非常向量表、swi》

1. 非常向量表基址

非常向量表地址是可以修正的,比如uboot在启动的时候,会从flash中搬运代码到RAM中,而flash的非常向量表地址和ram的地址肯定不一样,以是搬运完代码后,就必须要修正对应的非常向量表地址。

修正非常向量表的地址的须要借助协处理器指令mcr:

ldrr0,=0x40008000mcrp15,0,r0,c12,c0,0@VectorBaseAddressRegister

上述命令是将地址0x40008000设置为非常向量表的地址,关于mcr指令,我们没有必要穷究,知道即可。

RAM中非常向量表地址我们选用的是0x40008000,以下是exynos4412 地址空间分布。

exynos4412 地址分布

2. 非常向量表安装

.text.global_start_start:bresetldrpc,_undefined_instructionldrpc,_software_interruptldrpc,_prefetch_abortldrpc,_data_abortldrpc,_not_usedldrpc,=irq_handlerldrpc,_fiqreset:ldrr0,=0x40008000mcrp15,0,r0,c12,c0,0@VectorBaseAddressRegisterinit_stack://初始化栈……bmain//跳转至c的main函数irq_handler://中断入口函数sublr,lr,#4stmfdsp!,{r0-r12,lr}.weakdo_irqbldo_irqldmfdsp!,{r0-r12,pc}^stacktop:.wordstack+4512//栈顶.datastack:.space4512//栈空间

中断入口函数do_irq()

voiddo_irq(void){staticinta=1;intirq_num;irq_num=CPU0.ICCIAR&0x3ff;//获取中断号switch(irq_num){case57:printf("intheirq_handler\n");//清GPIO中断标志位EXT_INT41_PEND=EXT_INT41_PEND|((0x1<<1));//清GIC中断标志位ICDICPR.ICDICPR1=ICDICPR.ICDICPR1|(0x1<<25);break;}//清cpu中断标志CPU0.ICCEOIR=CPU0.ICCEOIR&(~(0x3ff))|irq_num;位}

实现按键中断的初始化函数key_init():

voidkey_init(void){GPX1.CON=GPX1.CON&(~(0xf<<4))|(0xf<<4);//配置引脚功能为外部中断GPX1.PUD=GPX1.PUD&(~(0x3<<2));//关闭高下拉电阻EXT_INT41_CON=EXT_INT41_CON&(~(0xf<<4))|(0x2<<4);//外部中断触发办法EXT_INT41_MASK=EXT_INT41_MASK&(~(0x1<<1));//使能中断ICDDCR=1;//使能分配器ICDISER.ICDISER1=ICDISER.ICDISER1|(0x1<<25);//使能相应中断到分配器ICDIPTR.ICDIPTR14=ICDIPTR.ICDIPTR14&(~(0xff<<8))|(0x1<<8);//选择CPU接口CPU0.ICCPMR=255;//中断屏蔽优先级CPU0.ICCICR=1;//使能中断到CPUreturn;}六、轮询办法

除了中断办法之外我们还可以通过轮询办法读取按键的信息,事理如下:

循环检测GPX1_1引脚输入的电平,为低电压时,按键按下,为高电平时,按键抬起。
配置GPX1_1引脚功能为输入,设置内部上拉下拉禁止。

GPX1.CON=GPX1.CON&(~(0xf<<4));GPX1.PUD=GPX1.PUD&~(0x3<<2);按键消抖: 按键按下后由于机器特性,会在极短的韶光内涌现电平忽0忽1,以是我们检测到按键按下后,须要给一个延时,然后再判断按键是不是仍旧按下。
代码实现

intmain(void){led_init();pwm_init();GPX1.CON=GPX1.CON&(~(0xf<<4))|0x0<<4;while(1){if(!(GPX1.DAT&(0x1<<1)))//返回为真,按键按下{delay_ms(10);if(!(GPX1.DAT&(0x1<<1)))//二次检测,去抖{GPX2.DAT|=0x1<<7;//TurnonLED2delay_ms(500);beep_on();GPX2.DAT&=~(0x1<<7);//TurnoffLED2delay_ms(500);while(!(GPX1.DAT&(0x1<<1)));beep_off();}}}return0;}

更多 ARM Linux干货,请关注 一口Linux

相关文章

B3卫星协议,开启卫星通信新纪元

随着科技的飞速发展,卫星通信已成为全球信息传输的重要手段。B3卫星协议作为一项重要的通信协议,为卫星通信领域带来了新的突破。本文将...

智能 2025-01-06 阅读1 评论0

Bonn语言,探索多元文化交融的桥梁

随着全球化进程的不断推进,各国文化之间的交流与融合日益加深。在这个多元文化交融的时代,语言作为一种重要的沟通工具,扮演着桥梁的角色...

智能 2025-01-06 阅读0 评论0

CF编程语言,新时代编程技术的璀璨明珠

在信息科技飞速发展的今天,编程语言作为信息时代的核心技术之一,已经成为了全球范围内热门的研究方向。而在众多编程语言中,CF(Col...

智能 2025-01-06 阅读0 评论0