Chinaunix首页 | 论坛 | 博客
  • 博客访问: 218115
  • 博文数量: 58
  • 博客积分: 1420
  • 博客等级: 上尉
  • 技术积分: 662
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-01 11:56
文章分类

全部博文(58)

文章存档

2009年(50)

2008年(8)

我的朋友

分类: LINUX

2009-02-04 14:54:02

具体的讨论我放在这里了:

 

大家当然也可以在我的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设置了:

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

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

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

翻译出来是这样:

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

过程这样:当中断源请求服务后, SRCPND对应set 1 , 经过仲裁后, 对应的INTPND的bit 会被被置 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-bit和I-bit了, 如果都被set成0了, 那么显然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=1,I-bit=1)了。

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

 

 

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

 

一般的原理都是这样的:

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

知道这些就足够了。

当中断源触发了一个中断的时候, 中断控制器要提供一个寄存器来标志哪个源产生中断, 类似2410 就提供INTPND(32个bit,bit置1 就表示对应的source产生了中断) ,  那么CPU就会读取这个寄存器,以确定中断号(get_irqnr_and_base这是个汇编宏)。 问题在于CPU怎么知道要去读呢? 显然要中断控制器给CPU发一个IRQ的request , 这样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

阅读(1284) | 评论(0) | 转发(0) |
0

上一篇:8259A中断控制器

下一篇:看门狗

给主人留下些什么吧!~~