Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1613636
  • 博文数量: 197
  • 博客积分: 10046
  • 博客等级: 上将
  • 技术积分: 1983
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-07 12:36
个人简介

在外企做服务器开发, 目前是项目经理, 管理两个server开发的项目。不做嵌入式好久了。

文章分类
文章存档

2011年(2)

2010年(6)

2009年(18)

2008年(30)

2007年(100)

2006年(41)

分类: LINUX

2008-01-23 17:58:10

文件: Kernel里面的中断代码分析.rar
大小: 723KB          (把rar改成doc 即可了
下载: 下载
具体的讨论我放在这里了:

 

大家当然也可以在我的blog里面讨论。

 

 

本来是用word写的, 粘了一些图, 可是弄到这里面有些麻烦, 还是看完整的pdf吧 。 

 

未完待续。

我真是天才, 想到了两个比方, 实在太恰当了:

 

打个比方: 一个傻子让妈妈喂饭: “妈妈, 我饿了”(SRCPND 对应bit 1 但是啥子不知道吃多少才能饱(脑子毁掉了,要不怎么啥呢?) 妈妈知道喂两碗就行了 所以当妈妈喂了两碗之后, 不再喂了(相当于中断处理完毕)

然后告诉啥子, 行了 ,饱了(相当于SRCPND 0 ,啥子相信妈妈的话, only相信妈妈的话

否则 ,如果妈妈不说“行了, 吃饱了,不要再吃了”这样的话, 啥子就一个劲的问问“ 妈妈, 我饿,俄” ,结果妈妈(也是个傻妈妈,难怪啥子是遗传的) ,一个劲的喂 结果什么活也干不了了,同时也把傻子儿子撑死了。

 

我怎么会突然想到这么一个比喻, 我真是个天才啊!   --bob

 

 最后一稿了:

文件: Kernel里面的中断代码分析-最终版.pdf
大小: 495KB
下载: 下载

word档案:

 

  

 

1.3 s3c2410 里面的中断控制器的细节分析:

从这里:

可以看出: s3c2410a 可以接收56个中断源的请求。

这些中断源来自来自两部分:内部外设,比如DMA 控制器,uart i2c

第二部分是外部中断请求的pin脚。

流程是这样:

当中断控制器接收到中断请求后, 经过仲裁过程后(选择了一个优先级高的IRQ或者FIQ),然后才向CPU发出 IRQ或者FIQ的请求。

 

至于到底这个中断源产生的IRQ还是FIQ , 这个要根据interrupt mode register设置了:

从这里我们也可以看出, IRQFIQ只是两种模式而已。 也就是说 , 当一个中断源被配置成IRQ或者FIQ的时候 , 中断控制器处理她的request的方式是不同的。

那是不是每个中断源可以随便设置自己的模式呢?显然不行。(想想, 如果发给大家的都是VIP卡, 那这个VIP卡显然就是普通的卡,被少数人拥有的才是VIP卡)

显然,只有紧急的中断才可以配置成FIQ , 也就是只有一个中断源才可以配置成FIQ模式,也就是VIP只有一个。

翻译出来是这样:

过程很简单, 2410a两个中断未决寄存器 SRCPND INTPND

过程这样:当中断源请求服务后, SRCPND对应set 1 , 经过仲裁后, 对应的INTPNDbit 会被被置 1 (前提是没有mask这个中断源) , 如果mask 了, INTPND的对应的bit就不会自动set 1 

接下来,就取决于CPSR F-bit I-bit了,如果他们置1 了,INTPND 也置1 , 那么就调用中断服务routine , 否则如果F-bit或者I-bit 0 ,那么就不会调用中断服务routine 了。

所以 ,从这里就可以看出 SRCPND INTPND 的 关系了: SRCPND set 1 表示中断源产生了request

INTPND 仅仅表示这个中断源没有被mask掉 ,中断控制器可以向CPU发出request了,以上这些都是从interrupt controller的角度来说的, 至于CPU 处不处理(也就是是否调用中断处理routine)就得 看 CPSR 寄存器里面F-bitI-bit了, 如果都被set0了, 那么显然CPU是不会鸟 中断控制器的(从英文来看:(If the F-bit of PSR in ARM920T CPU is set to 1, the CPU does not accept the Fast Interrupt Request (FIQ) from the

interrupt controller. Likewise, If I-bit of the PSR is set to 1, the CPU does not accept the Interrupt Request (IRQ) from the interrupt controller. So, the interrupt controller can receive interrupts by clearing F-bit or I-bit of the PSR to 0 and setting the corresponding bit of INTMSK to 0 这里用了 accept ,那就是说 interrupt发了request ,可是CPU 不能accept

 

 

 

可以看出, 2410a的中断控制器 ,总共有5个寄存器 SRCPND INTMR MR PRI   INTPND

 

可以看出 FIQ是不需要仲裁的, 显然从这点可以看出 FIQ 的效率肯定比IRQ ,因为FIQ必须要仲裁。

来自中断源的中断请求必须首先在SRCPND 寄存器里面注册一下(即对应的bit 1

 

这些请求又分为两组, 至于怎么分,就得看 中断模式寄存器了。

 

关于SRCPND 这里面说的很明确了, 就是 只要触发了中断, SRCPND对应的bit就会被自动置1 仅仅表示产生了中断, 等待着被服务(kernel调用interrupt service 而无论INTMASK对应的bit 是否是1 SRCPND都会被自动置1

这一点 ,上面已经说的很清楚了。

 

 

 

这个说的就是 关于如何清除 SRCPND 以及何时清除的问题了, 还有就是如果 你不clear SRCPND相应的bit会导致什么后果:

显然上面说的很清楚了, SRCPND 仅仅表示 中断请求的状态, 如果 kernel都处理了这个中断(调用了中断处理函数) ,就应该告诉 中断控制器(我已经处理完了, tmd别烦了) 

如果没有清除会有什么样的后果: 我想, 中断控制器可不知道kernel已经处理完了这个中断, 还在那里等着kernel去处理呢, 这样kernel也傻了, 就会去反复的处理的这个中断)。

 

打个比方: 一个傻子让妈妈喂饭: “妈妈, 我饿了”(SRCPND 对应bit 1 但是啥子不知道吃多少才能饱(脑子毁掉了,要不怎么啥呢?) 妈妈知道喂两碗就行了 所以当妈妈喂了两碗之后, 不再喂了(相当于中断处理完毕)

然后告诉啥子, 行了 ,饱了(相当于SRCPND 0 ,啥子相信妈妈的话, only相信妈妈的话

否则 ,如果妈妈不说“行了, 吃饱了,不要再吃了”这样的话, 啥子就一个劲的问问“ 妈妈, 我饿,俄” ,结果妈妈(也是个傻妈妈,难怪啥子是遗传的) ,一个劲的喂 结果什么活也干不了了,同时也把傻子儿子撑死了。

 

我怎么会突然想到这么一个比喻, 我真是个天才啊!   --bob

 

 

?对于CPU都是这样的吗? 就是 interrupt service routine 里面必须清楚中断的标志bit吗?

 

 

又想到一个比喻: 古代奸臣误国,好多正直大臣的奏折并不能被直接传递到皇帝手中 ,比如大奸臣魏忠贤。

魏忠贤好比是中断控制器   皇帝好比是CPU

奏章要首先经过魏忠贤的手, 如果魏忠贤屏蔽掉某个大臣的奏章(mask),那么皇帝肯定没有机会看了。

但是假使奏章通过魏忠贤(interrupt controller)传给皇帝了, 可是皇帝是个糊涂蛋, 只知玩乐,误了朝政, 奏折堆积如山(就相当于 F-bit=1I-bit=1)了。

所以封建国家, 既要有好大臣(狄仁杰,什么奏章都敢上奏,不管是否是弹劾自己的), 又要有好皇帝(唐太宗,勤于政事)啊。

 

 

当一个中断控制器连接了128个中断源的时候, CPU怎么知道哪个中断源产生了中断呢?继而调用对应的中断处理函数呢?

 

一般的原理都是这样的:

显然,要回答这个问题, 必须要搞清楚, CPU是肯定不知道哪个中断源产生了中断的, 谁知道呢?只有中断控制器才知道的, 那么,CPU就要查询中断控制器就好了。 问题是中断控制器的那个register 的标志bit 被置1 肯定是硬件做的,

知道这些就足够了。

当中断源触发了一个中断的时候, 中断控制器要提供一个寄存器来标志哪个源产生中断, 类似2410 就提供INTPND32bitbit1 就表示对应的source产生了中断)  那么CPU就会读取这个寄存器,以确定中断号(get_irqnr_and_base这是个汇编宏) 问题在于CPU怎么知道要去读呢? 显然要中断控制器给CPU发一个IRQrequest 这样CPU才会去读(实际上是一段汇编代码) 

 继而才会调用asm_do_IRQ(irq_number)来处理中断, 继而可以通过irq号找到对应中断的中断描述符(irq descriptor),找到了中断描述符,就找到了,handler 然后 调用 ->handler() 就可以处理中断了。

 

 

-------------------未决的疑问  ------------------------
最后 ,回到最开始还有两个问题没搞明白:

2410 的interrupt controller:
1>
这句话“In these interrupt sources,
the UARTn and EINTn interrupts are 'OR'ed to the interrupt controller” 什么意思呢?

另外, 2410 的中断控制器里面提到了外部中断(通过GPIO的pin脚连进去的, 内部的一些peripherals 也产生interrupt , 比如DMA controller, the UART, IIC, and others , 这里的others 指什么呢?

熟悉硬件的朋友, 这里简单说说, 内部的interrupt 外部的interrupt具体区别在哪里呢?

2>
这怎么还分 有sub-register 和没有sub-register的情况呢? 具体懂硬件的人讲讲啊。


 
 

1.2 中断处理函数是如何被called

 

[自己的分析bob]

中断首先是一个硬件行为, 而处理中断呢, 显然又是一个软件行为,作为driver writer only 实现中断处理函数, 并与中断号进行关联也就ok了。那么就引出一个问题? 当硬件触发中断的时候,怎么调用到中断处理函数的呢?

 

要搞清楚这个问题,就要搞清楚,发生中断的时候 CPU做了什么

 

arm为例,当产生IRQ请求的时候, CPU做了什么:

1>     处理器切换到特定的中断请求模式(IRQ模式),表明产生了中断。

2>     前一个模式的cpsr被保存到新的模式下的spsr

3>     PC 指针被保存到新的模式的lr 寄存器

4>     关中断----cpsr中禁止I-bit ,会立即阻止其他的IRQ产生。

5>     处理器跳转到异常向量表中相应的入口(对于IRQ 显然pc=0x18

 

说道这里,就涉及到了异常向量表,这个异常向量表就是软件和CPU的接口 CPU知道一个source触发了中断,怎么调用执行一些函数(汇编,或者c语言),就是靠异常向量表(事实上,exception vector table 也是由汇编组成的)

 

异常

模式

向量表偏移

复位(reset

SVC

+0x00

未定义指令

UND

+0x04

软件中断(SWI

SVC

+0x08

欲取指终止

ABT

+0x0c

数据终止

ABT

+0x10

未分配

--

+0x14

IRQ

IRQ

+0x18

FIQ

FIQ

+0x1c

 

arm异常,对应模式及向量表偏移(摘自arm体系结构与编程一书)

 

从这表中, 我们很清楚了, 当触发IRQ的时候, CPU会最后跳入0x18 这个入口 那我们做kernel的人, 只需在这个入口填入自己的指令(当然是汇编语句) 来调用 中断处理函数,可能这样。

 

中断-à cpu jump 0x18 ,同时要把irqno传入相应的寄存器  à  调用一个中断通用处理函数比如叫 asm_do_IRQ(unsigned int irqno)  à asm_do_IRQ() 这个函数根据irqno 就可以找到对应的中断描述符  à 然后调用中断描述符里面的handler()

 

 

 

那具体的kernel里面的细节是什么样的呢? 具体看下面这篇转载的文章即可。代码分析的就比较透彻了, 事实上我们只要上面说的流程,对于driver writer已经足够了。

 

【转载】

那么 当硬件触发中断的时候,  kernel里面的 asm_do_IRQ() 是如何被调用到呢?  

遭到一篇很好的文章:

http://hi.baidu.com/wudx05/blog/item/5314935c834f4e41fbf2c0dc.html

阅读(5333) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

bob_zhang20042008-01-25 13:20:46

有没有愿意一起研究的啊? 愿意研究就所取word档案, 咱们一起完善啊。