免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1244 | 回复: 0
打印 上一主题 下一主题

Kernel里面的中断代码分析[2] -- 重点分析2410的datasheet里面的interr [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-04 14:54 |只看该作者 |倒序浏览
具体的讨论我放在这里了:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=driver&Number=672049&page=0&view=collapsed&sb=5&o=31&fpart=1&vc=1

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


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/58463/showart_1812684.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP