您的位置:首页 > 其它

深入理解wince7中断处理过程

2015-03-02 16:01 232 查看
wince中断处理过程一文中我们知道在驱动中如何申请系统中断号、如何将中断和事件关联起来等,但是并不知道这些操作更底层的实现方式。在这里我们来对wince中断机制做一个稍微深入的理解,以zc702运行的wince7为例。

1、wince是如何通过物理中断号来申请系统中断号?

物理中断号(irq)是处理器为设备模块分配的具有唯一性的id,如zynq中uart0和gpio的物理中断号分别为59和52。在驱动程序中我们需要先通过KernelIoControl函数动态申请一个与irq相映射的系统中断号(sysIntr)。所谓的映射,在wince中就是通过数组实现的。在C:\WINCE700\platform\common\src\common\intr\base\map.c文件中主要有如下几个函数:



其中OALIntrMapInit()函数用来初始化g_oalSysIntr2Irq[]数组和g_oalIrq2SysIntr[]数组(初始化为UNDEFINED),这两个数组就是用来存放irq和sysIntr之间的映射关系。当我们在驱动中使用KernelIoControl函数动态申请sysIntr时,系统就会调用OALIntrRequestSysIntr()函数来对g_oalSysIntr2Irq[]数组做操作。如下图所示:(比如现在要为irq是59的uart0申请一个sysIntr,OALIntrRequestSysIntr()函数就会遍历g_oalSysIntr2Irq[]数组来获取空闲的sysIntr。假设现在g_oalSysIntr2Irq[30]的值为UNDEFINED,系统就认为id为30的sysIntr是空闲的。此时就会将59这个值赋给g_oalSysIntr2Irq[30],并将30赋给g_oalIrq2SysIntr[59],这样就将59
irq和30 sysIntr相互映射起来。)



在驱动中使用KernelIoControl函数来释放sysIntr时,OALIntrReleaseSysIntr()函数就会被调用,并将g_oalSysIntr2Irq[]数组和g_oalIrq2SysIntr[]数组中对应的元素重置为UNDEFINED。

2、物理中断产生后是如何得到对应的系统中断号?

当中断发生后,系统会通过OEMInterruptHandler()函数来返回对应的sysIntr,zc702中这个函数位于Oal_intr.c文件中。OEMInterruptHandler()函数会通过寄存器来获取irq的id,然后使用map.c中的OALIntrTranslateIrq(UINT32
irq)函数返回该irq所对应的sysIntr。

3、gpio的引脚中断怎么申请?

在zynq中gpio的irq为52,cpu并没有为每一个gpio引脚分配irq。这就需要我们在bsp代码中手动地给这些引脚分配次级irq。(比如有10个引脚需要次级中断,而1~128 irq是cpu分配的一级中断号,那么我就可以将129~139的irq分配给这10个引脚。)在驱动中可使用与一级中断同样的方式来申请次级中断的sysIntr。当某个引脚中断产生后,OEMInterruptHandler()函数会先获取52的irq号,然后判断出52这个irq有次级中断。OEMInterruptHandler()函数就会继续调用gpio相关的函数来获取具体是哪一个引脚产生了中断,并返回对应引脚的次级中断号。OEMInterruptHandler()函数再调用map.c中的OALIntrTranslateIrq()返回该次级中断号对应的sysIntr。

4、驱动中InterruptDone()如何实现?

在驱动中处理完中断后,需要调用InterruptDone()函数来注销中断,这样才能继续接收下一次中断。该函数会调用map.c中的OEMInterruptDone()函数,OEMInterruptDone()函数又会调用Oal_Intr.c中的OALIntrDoneIrqs()函数,并一直到最底层对中断寄存器操作的函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息