您的位置:首页 > 其它

中断号与芯片管脚关系

2009-10-31 01:13 176 查看
一直以来搞不懂这个中断号的来历,总以为是中断控制器自己规定的一个号,但是最近在看了
s3c2440的中断控制后才发现不是这么一回事.2440的中断处理只能处理32个中断,但是其在内核中出现的中断号却有51,58等.而且它的外部中
断INT4~7共享一个中断控制寄存器的一位,INT8~23也是共享控制寄存器的一位.我就好奇了,它怎么区分这些中断呢?而且在内核代码中它又很清楚
的区分了这些中断.如下面的代码(2.6.13).

"
include/asm-arm/arch-s3c2410/irqs.h
"

.....

/* interrupts generated from the external interrupts sources */

#
define

IRQ_EINT4

S3C2410_IRQ
(
32
)

/* 48 */

#
define

IRQ_EINT5

S3C2410_IRQ
(
33
)

#
define

IRQ_EINT6

S3C2410_IRQ
(
34
)

#
define

IRQ_EINT7

S3C2410_IRQ
(
35
)

#
define

IRQ_EINT8

S3C2410_IRQ
(
36
)

#
define

IRQ_EINT9

S3C2410_IRQ
(
37
)

#
define

IRQ_EINT10

S3C2410_IRQ
(
38
)

#
define

IRQ_EINT11

S3C2410_IRQ
(
39
)

#
define

IRQ_EINT12

S3C2410_IRQ
(
40
)

#
define

IRQ_EINT13

S3C2410_IRQ
(
41
)

#
define

IRQ_EINT14

S3C2410_IRQ
(
42
)

#
define

IRQ_EINT15

S3C2410_IRQ
(
43
)

#
define

IRQ_EINT16

S3C2410_IRQ
(
44
)

....

在看了N久之后才发现了其中的缘由:

在初始化的时候,在相关的启动代码中将这些中断源和中断号进行了一一的映射,然后再初始化irq_desc.而在执行中断的时候就根据中断控制器的一些状
态和控制寄存器来进行转换,将相应的中断源转换成中断号,再进行中断例程的执行.这里针对于2440的进行简单分析一下:

在”arch/arm/kernel/entry-armv.S” 的 irq_handler宏就是处理中断的,代码如下:

/*

* Interrupt handling. Preserves r7, r8, r9

*/

.
macro

irq_handler

1
:
get_irqnr_and_base

r0
,
r6
,
r5
,
lr

//而这里就是将中断源转换成相应中断号的一个宏,最后将中断号放到r0中

movne

r1
,
sp

@

@
routine

called

with

r0
=
irq

number
,
r1
=
struct

pt_regs
*

@

adrne

lr
,
1
b

bne

asm_do_IRQ

//执行一般中断,函数原型:"arch/arm/kernel/irq.c"

// asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)

//可以看出这里需要的参数有中断号和CPU发生中断时需要保存的寄存器



#
ifdef

CONFIG_SMP

/*

* XXX

*

* this macro assumes that irqstat (r6) and base (r5) are

* preserved from get_irqnr_and_base above

*/

test_for_ipi

r0
,
r6
,
r5
,
lr

movne

r0
,
sp

adrne

lr
,
1
b

bne

do_IPI

//执行CPU内部中断或是异常

#
endif



.
endm

而对于中断源到中断号的转换宏get_irqnr_and_base这里要分析一下:

在”include/asm/arch/entry-macro.S” 中定义:

.
macro

get_irqnr_and_base
,
irqnr
,
irqstat
,
base
,
tmp

//irqnr: 是用来存放最后的中断号的,也就是上面传递过来的r0

//irqstat: 用来存放中断状态的,即上面的r6

//base: 这个在这宏当中没有使用

//tmp:这个是用来存放中断控制器基地址的,

//下面在获取个个控制寄存器值的时候都是在这个地址的基础之上加相应的值

mov
/
tmp
, #
S3C24XX_VA_IRQ

//获取中断控制器基地址(是虚地址)

ldr
/
irqnr
,
[
/
tmp
, #
0x14

]
@
get

irq

no

30000
:

teq
/
irqnr
, #
4

teqne
/
irqnr
, #
5

beq

1002
f
@
external

irq

reg

.....

//这里即是对EINT4~EINT23的中断号的映射,

//RQ_EINT4是一个基本号,就是这个号和前面的中断号是断开的,其间这些中断号是预留给其它一些总线下的设备使用的.

//而之后的中断号都是在这个号的基础上不断+1的,这里是其代码.

mov
/
irqnr
, #
IRQ_EINT4
@
start

extint

nos

mov
/
irqstat
, /
irqstat
,
lsr
#
4
@
ignore

bottom

4

bits

10021
:

movs
/
irqstat
, /
irqstat
,
lsr
#
1

//这里是根据起中断状态再判断到底是那一个中断发生了

bcs

1004
f

add
/
irqnr
, /
irqnr
, #
1

cmp
/
irqnr
, #
IRQ_EINT23

ble

10021
b

.....

这里就完成了中断引脚和中断号的对应关系,哎,终于搞明白了!!!但是个个体系结构和中断控制器的映射方式应该是不一样的,这个只是真对于s3c2440来说的

这里就完成了中断
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: