一、S3C2440上的中断
1.1 中断概述
S3C2440A 中的中断控制器接受来自60 个中断源的请求。提供这些中断源的是内部外设,如DMA 控制器、 UART、IIC 等等。在这些中断源中,UARTn、AC97 和EINTn 中断对于中断控制器而言是“或”关系。
当从内部外设和外部中断请求引脚收到多个中断请求时,中断控制器在仲裁步骤后请求ARM920T 内核的FIQ 或IRQ。
1.2 中断过程
(1) 如果是不带子中断的内部中断
如果是不带子中断的内部中断发生后,中断发生后SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理
(2) 如果是带子中断的内部中断
如果是带子中断的内部中断,中断发生后SUBSRCPND相应位置1,如果没有被INTSUBMSK屏蔽,那么SRCPND相应位置1,等待进一步处理。
几个SUBSRCPND可能对应同一个SRCPND,SRCPND和SUBSRCPND对应关系:
SRCPND | SUBSRCPND |
INT_UART0 | INT_RXD0,INT_TXD0,INT_ERR0 |
INT_UART1 | INT_RXD1,INT_TXD1,INT_ERR1 |
INT_UART2 | INT_RXD2,INT_TXD2,INT_ERR2 |
INT_ADC | INT_ADC_S, INT_TC |
INT_CAM | INT_CAM_C, INT_CAM_P |
INT_WDT_AC97 | INT_WDT, INT_AC97 |
(3) 如果是外部中断
EINT0-EINT3发生后SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理。
EINT4-EINT23发生后EINTPEND相应位置1,如果没有被EINTMASK屏蔽,那么SRCPND相应位EINT4-7或EINT8-23置1,如果没有被INTMSK屏蔽,等待进一步处理。
几个EINTPEND对应同一个SRCPND,对应表如下:
SRCPND | EINTPEND |
EINT0 | EINT0 |
EINT1 | EINT1 |
EINT2 | EINT2 |
EINT3 | EINT3 |
EINT4~7 | EINT4-EINT7 |
EINT8~23 | EINT8-EINT23 |
1.3 中断处理逻辑
三种中断都等待进一步处理了。接下来从SRCPND往下看,看INTMSK。如果中断被屏蔽了,就不用说了(注意:快中断也能被屏蔽)。如果没有被屏蔽,那看一下中断模式:
- 如果中断模式是快中断,那么直接 出来进入FIQ;
- 如果是普通中断,那么SRCPND可以有多位置1(FIQ 只能有一个),这时就会经过PRIORITY选出一个优先级高的,然后把根据选 出的中断把INTPND相应位置1(注意:只能选出一个),进入IRQ,让CPU处理。
1.4 中断开启
- 如果是不带子中断的内部中断,只需设置INTMSK,让它不屏蔽中断就可以了;
- 如果是带子中断的内部中断,需设置INTSUBMSK和INTMSK,让它门不屏蔽中断就可以了;
- 如果是外部中断,对于EINT8-23需要设置EINTMASK和INTMSK。对于EINT0-EINT3只需设置INTMSK;
1.5 中断清除
- 如果是不带子中断的内部中断,只需清除SRCPND、INTPND,注意清除需位置1。
- 如果是带子中断的内部中断,需清除SRCPND和SUBSRCPND、INTPND,注意先清除SUBSRCPND,再清除SRCPND。 因为,如果你先清除SRCPND的话,然后在清除SUBSRCPND的过程中,SRCPND会以为又有中断发生, 又会置1,也就是说一次中断会响应两次。所以必须先掐断源头。
- 如果是外部中断,对于EINT8-23需要清除EINTPEND和SRCPND、INTPND(同样注意顺序)。对于EINT0-EINT3只需清除SRCPND。
二、中断寄存器
2.1 程序状态寄存器(PSR)的F位和I位
如果ARM920T CPU 中的PSR 的F位被置位为1,CPU 不会接受来自中断控制器的快中断请求(FIQ)。同 样的如果PSR 的I 位被置位为1,CPU 不会接受来自中断控制器的中断请求(IRQ)。因此,中断控制器可以通过清除PSR 的F位和I位为0,并且设置INTMSK 的相应位为0来接收中断。同理我们关中断也包含两步:
(1) 我们可以开启SVC模式,关闭fiq,irq中断,如下:
set_svcmode: mrs r0,cpsr /* r0 = cpsr */ bic r0,r0,#0x1f /* M[4:0]清0 */ orr r0,r0,#0xd3 /* 设置为SVC模式,并关闭fiq,irq中断 */ msr cpsr,r0 /* cpsr = r0 */ mov pc,lr /* bl指令将下一条指令地址复制到了lr,子程序返回 */
我们先用bit指令将处理器模式为[4:0]请零,然后采用ORR或指定将模式位设置位10011,即SVC模式,同时将[7:6]位置1,关闭fiq、irq中断。
(2) 设置INTMASK屏蔽中断
disable_interrupt: mvn r1,#0x00 /* 取反赋值 r1 = 0xffffffff */ ldr r0,=0X4A000008 str r1,[r0] /* INTMASK每一位均写1 屏蔽中断 mov pc,lr
2.2 中断模式(INTMOD)
ARM920T有两种中断模式的类型:FIQ 或IRQ。所有中断源在中断请求时决定使用哪种类型。
INTMOD寄存器由32 位组成,其每一位都都涉及一个中断源。如果某个指定为被设置为1,则在FIQ(快中断)模式 中处理相应中断。否则则在IRQ 模式中处理。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTMOD | 0X4A000004 | R/W |
中断模式寄存器 0:IRQ模式 1:FIQ模式 |
0x00 |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
注意:如果中断模式在INTMOD 寄存器中设置为FIQ 模式,则FIQ 中断将不会影响INTPND 和INTOFFSET 寄存 器。这种情况下,这2 个寄存器只对IRQ 中断源有效。
2.3 中断挂起寄存器(SRCPND、INTPND)
S3C2440A 有两个中断挂起寄存器:源挂起寄存器(SRCPND)和中断挂起寄存器(INTPND)。这些挂起寄存器表明一个中断请求是否为挂起。当中断源请求中断服务,SRCPND 寄存器的相应位被置位为1,并且同时在仲 裁步骤后INTPND 寄存器仅有1 位自动置位为1。如果屏蔽了中断,则SRCPND 寄存器的相应位被置位为1。这 并不会引起INTPND 寄存器的位的改变。当INTPND 寄存器的挂起位为置位,每当I 标志或F 标志被清除为0 中 断服务程序将开始。SRCPND 和INTPND 寄存器可以被读取和写入,因此服务程序必须首先通过写1 到SRCPND寄存器的相应位来清除挂起状态并且通过相同方法来清除INTPND 寄存器中挂起状态。
寄存器 | 地址 | R/W | 描述 | 复位值 |
SRCPND | 0X4A000000 | R/W |
指示中断请求状态 0:中断未被请求 1:中断源声明了中断请求 |
0x00 |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
中断挂起寄存器中32 位的每一位都表明了是否相应未屏蔽并且正在等待中断服务的中断请求具有最高的优先 级。当INTPND 寄存器在优先级逻辑后被定位了,只有1 位可以设置为1 并且产生中断请求IRQ 给CPU。IRQ 的 中断服务程序中可以读取此寄存器来决定服务32 个中断源的哪个源。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTPND | 0X4A000010 | R/W |
指示中断请求状态 0:中断未被请求 1:中断源声明了中断请求 |
0x7F |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
注意:如果FIQ 模式中断发生,则INTPND 的相应位将不会打开因为INTPND 寄存器只对IRQ 模式中断可见。
2.4 中断屏蔽寄存器(INTMASK)
此寄存器表明如果中断相应的屏蔽位被置位为1 则禁止该中断。如果某个INTMSK 的中断屏蔽位为0,将正常 服务中断。如果INTMSK 的中断屏蔽位为1 并且产生了中断,将置位源挂起位。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTMASK | 0X4A000008 | R/W |
决定屏蔽哪个中断源。被屏蔽的中断源将不会服务 0:中断服务可用 1:屏蔽中断服务 |
0xFFFFFFFF |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
2.5 中断源
中断控制器支持60个(EINT4~8、EINT8~23算多个)中断源,并分为6个仲裁组ARB5、ARB4、ARB3、ARB2、ARB1、ARB0。
2.6 中断优先级
每个仲裁器可以处理基于1 位仲裁器模式控制(ARB_MODE)和选择控制信号(ARB_SEL)的2 位的6 个中断请求,如下:
- 如果ARB_SEL 位为00b,优先级顺序为REQ0、REQ1、REQ2、REQ3、REQ4 和REQ5。
- 如果ARB_SEL 位为01b,优先级顺序为REQ0、REQ2、REQ3、REQ4、REQ1 和REQ5。
- 如果ARB_SEL 位为10b,优先级顺序为REQ0、REQ3、REQ4、REQ1、REQ2 和REQ5。
- 如果ARB_SEL 位为11b,优先级顺序为REQ0、REQ4、REQ1、REQ2、REQ3 和REQ5。
请注意仲裁器的REQ0 的优先级总是最高并且REQ5 的优先级总是最低。此外,通过改变ARB_SEL 位,可以轮换REQ1 到REQ4 的顺序。
此处,如果ARB_MODE 位被设置为0,ARB_SEL 位不能自动改变,这使得仲裁器操作在固定优先级模式中 (注意即使在此模式中,也不能通过手动改变ARB_SEL 位来重新配制优先级)。另一方面,如果ARB_MODE 为 1,ARB_SEL 位会被轮换方式而改变,例如如果REQ1 被服务,ARB_SEL 位被自动改为01b 以便REQ1 进入到 最低的优先级。ARB_SEL 改变的详细结果如下:
- 如果REQ0 或REQ5 被服务,ARB_SEL 位不会改变 ;
- 如果REQ1 被服务,ARB_SEL 位被改为01b;
- 如果REQ2 被服务,ARB_SEL 位被改为10b;
- 如果REQ3 被服务,ARB_SEL 位被改为11b;
- 如果REQ4 被服务,ARB_SEL 位被改为00b。
寄存器 | 地址 | R/W | 描述 | 复位值 |
PRIORITY | 0X4A00000C | R/W |
IRQ 优先级控制寄存器 |
0x7F |
寄存器位信息:
PRIORITY | 位 | 描述 | 初始状态 |
ARB_SEL6 | [20:19] |
仲裁器组6 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL5 | [18:17] |
仲裁器组5 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL4 | [16:15] |
仲裁器组4 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL3 | [14:13] |
仲裁器组3 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL2 | [12:11] |
仲裁器组2 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL1 | [10:9] |
仲裁器组1 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL0 | [8:7] |
仲裁器组0 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_MODE6 | [6] |
仲裁器组6 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE5 | [5] |
仲裁器组5 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE4 | [4] |
仲裁器组4 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE3 | [3] |
仲裁器组3 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE2 | [2] |
仲裁器组2 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE1 | [1] |
仲裁器组1 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE0 | [0] |
仲裁器组0 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
2.7 中断便宜寄存器(INTOFFSET)
中断偏移寄存器中的值表明了是哪个IRQ 模式的中断请求在INTPND 寄存器中。此位可以通过清除SRCPND 和INTPND 自动清除。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTOFFSET | 0x4A000014 | R |
指示IRQ 中断请求源 |
0x00 |
寄存器值和2.5节每一个中断源偏移量对应,比如31:INT_ADC、30:INT_RTC。
2.8 次级源挂起寄存器(SUBSRCPND)
可以通过写入数据到此寄存器来清除SUBSRCPND 寄存器的指定位。只有数据中那些被设置为1 的相应 SUBSRCPND 寄存器的位的位置才能被清除。数据中那些被设置为0 的相应位的位置则保持不变。
寄存器 | 地址 | R/W | 描述 | 复位值 |
SUBSRCPND | 0X4A000018 | R/W |
指示中断请求状态 0:中断未被请求 1:中断源声明了中断请求 |
0x00 |
寄存器位信息:
SUBSRCPND | 位 | 描述 | 初始状态 |
保留 | [31:15] | 未使用 | 0 |
INT_AC97 | [14] | 0:未请求 1:请求 | 0 |
INT_WDT | [13] | 0:未请求 1:请求 | 0 |
INT_CAM_P | [12] | 0:未请求 1:请求 | 0 |
INT_CAM_C | [11] | 0:未请求 1:请求 | 0 |
INT_ADC_S | [10] | 0:未请求 1:请求 | 0 |
INT_TC | [9] | 0:未请求 1:请求 | 0 |
INT_ERR2 | [8] | 0:未请求 1:请求 | 0 |
INT_TXD2 | [7] | 0:未请求 1:请求 | 0 |
INT_RXD2 | [6] | 0:未请求 1:请求 | 0 |
INT_ERR1 | [5] | 0:未请求 1:请求 | 0 |
INT_TXD1 | [4] | 0:未请求 1:请求 | 0 |
INT_RXD1 | [3] | 0:未请求 1:请求 | 0 |
INT_ERR0 | [2] | 0:未请求 1:请求 | 0 |
INT_TXD0 | [1] | 0:未请求 1:请求 | 0 |
INT_RXD0 | [0] | 0:未请求 1:请求 | 0 |
映射到SRCPND:
SRCPND | SUBSRCPND |
INT_UART0 | INT_RXD0,INT_TXD0,INT_ERR0 |
INT_UART1 | INT_RXD1,INT_TXD1,INT_ERR1 |
INT_UART2 | INT_RXD2,INT_TXD2,INT_ERR2 |
INT_ADC | INT_ADC_S, INT_TC |
INT_CAM | INT_CAM_C, INT_CAM_P |
INT_WDT_AC97 | INT_WDT, INT_AC97 |
2.9 中断次级屏蔽寄存器(INTSUBMSK)
此寄存器有11 位,其每一位都与一个中断源相联系。如果某个指定位被设置为1,则相应中断源的中断请求 不会被CPU 所服务(请注意即使在这种情况中,SRCPND 寄存器的相应位也设置为1)。如果屏蔽位为0,则可以 服务中断请求。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTSUBMSK | 0X4A00001C | R/W |
决定屏蔽哪个中断源。被屏蔽的中断源将不会服务 0:中断服务可用 1:屏蔽中断服务 |
0xFFFF |
寄存器每一位和2.8节中寄存器位信息一致。
INTSUBMSK | 位 | 描述 | 初始状态 |
保留 | [31:15] | 未使用 | 0 |
INT_AC97 | [14] | 0:可服务 1:屏蔽 | 0 |
INT_WDT | [13] | 0:可服务 1:屏蔽 | 0 |
INT_CAM_P | [12] | 0:可服务 1:屏蔽 | 0 |
INT_CAM_C | [11] | 0:可服务 1:屏蔽 | 0 |
INT_ADC_S | [10] | 0:可服务 1:屏蔽 | 0 |
INT_TC | [9] | 0:可服务 1:屏蔽 | 0 |
INT_ERR2 | [8] | 0:可服务 1:屏蔽 | 0 |
INT_TXD2 | [7] | 0:可服务 1:屏蔽 | 0 |
INT_RXD2 | [6] | 0:可服务 1:屏蔽 | 0 |
INT_ERR1 | [5] | 0:可服务 1:屏蔽 | 0 |
INT_TXD1 | [4] | 0:可服务 1:屏蔽 | 0 |
INT_RXD1 | [3] | 0:可服务 1:屏蔽 | 0 |
INT_ERR0 | [2] | 0:可服务 1:屏蔽 | 0 |
INT_TXD0 | [1] | 0:可服务 1:屏蔽 | 0 |
INT_RXD0 | [0] | 0:可服务 1:屏蔽 | 0 |