WinCE中断结构分析
2013-12-30 11:07
260 查看
以前写的原创博文,这里放一份
前一段时间研究了一下WinCE下的中断结构,整理了一下,希望与大家讨论。
最下面有PDF版本下载,便于保存
Windows Embedded CE
中断结构分析
关键字:WinCE,中断,体系,结构
摘要:本文主要以WinCE .NET 5.0为操作系统平台,ARM为硬件平台,分析了WinCE下
中断的结构与实现方式
前言
在嵌入式系统当中,对于中断的处理是非常重要的一部分内容。许多外围设备都需要通
过中断来实现自己的功能或者与系统内核交互,系统时钟本身也是由时钟中断产生的。所以
本文旨在分析WinCE下的中断的结构,以及常用的几种实现方式,来帮助读者了解WinCE
中断体系及实现自己的中断处理结构。
下面的介绍如非特殊说明,均以 ARM架构为硬件基础,操作系统代码使用 Windows
embedded CE 5.0。
一 WinCE中断体系结构
先看图 1:
图 1 WinCE中断体系结构
这张是经典的说明中断体系的图,我们可以通过分析这张图来了解WinCE的中断体系。
从结构上看,WinCE中断涉及4层,即:硬件层、内核层、OAL层、IST处理层。了
解这 4层之间的交互传递将对我们了解WinCE中断处理很有帮助。
1 硬件层:
硬件层就是实际触发中断的硬件,这里主要有两方面作用,一个是触发中断,第二个是
enable/disable硬件中断。
2 内核层:
这一层由内核来处理,包括中断异常产生后跳转到相应的ISR,以及根据SYSINTR来
触发相应的Event。关于SYSINTR 和 IRQ 的概念后面会说明。
3 OAL层
这一层主要就是我们需要实现的代码了,来识别硬件IRQ,对应到SYSINTR。
4 IST处理层
一般使用 IST来做实际的中断处理,这样不会占用很多的锁定系统时间来处理中断,
但是对中断的实时性大打折扣
二 IRQ,ISR,IST和 SYSINTR
说到这里先解释下IRQ,ISR,IST及 SYSINTR 的概念、意义及相互关系。
IRQ:
IRQ (Interrupt request),中断请求。
这里就是外设或其它请求服务的设备发出来的中断。属于硬件中断,可能是一个电平触发的
GPIO 中断,也可能是内部DMA的一个中断。
ISR:
ISR (Interrupt serviceroutine), 中断处理程序。
WinCE实际上使用 ISR来处理中断,即默认的中断入口函数,在 ARM体系中,系统默认的
ISR就是 OEMInterruptHandler
IST:
IST (Interrupt servicethread), 中断服务线程。
在 ARM 的结构中,ISR 一般不会用来进行任何实际的操作,而只是返回一个 SYSINTR,
实际的操作全部在IST中完成,IST一般是在Device Manager 的一个线程中运行的一段
高优先级的应用程序代码,用来服务实际的中断请求。
SYSINTR:
在 WinCE中,SYSINTR 就是 system interrupt,就是一个操作系统的逻辑中断。
一般对于中断的处理方式都是将一个IRQ映射为一个或者多个(中断共享)SYSINTR,而后,
在实际的ISR中根据IRQ返回一个对应的SYSINTR用来告诉操作系统需要服务的逻辑对
象。
使用逻辑中断的好处当然就是可以实现虚拟的中断(一个 SYSINTR 就被 OS 认为是一个独
立中断)和中断共享(单 IRQ对应多 SYSINTR)。
逻辑中断是WinCE需要处理的实际对象,至于这个对象是一个共享的IRQ,还是一个虚拟
的中断,还是独立的物理中断,系统并不过问,从而隔离了硬件与逻辑,我们的 ISR 需要
做的也正是这种物理中断到逻辑中断的映射。
三 WinCE中断处理原理
下面基于 ARM 体系,来介绍 WinCE中断处理的流程与原理。
对于一个硬件IRQ中断,系统内核在捕获之后,会交给OEMInterruptHandler 处理,
这个函数就是我们实现中断处理的中心函数,首先我们从CPU 的寄存器里获得中断的信息,
这些信息告诉我们到底是哪个 IRQ 源触发了中断。
一般实现中断服务的方式有以下几种:
1. 简单中断处理——ISR模型
最简单的中断处理办法就是在ISR中直接处理,这里就是指在OEMInterruptHandler
中直接对中断源进行判断,然后调用服务程序。
这种方式的优点和缺点一样明显。
优点:快速的响应了中断处理,使系统的实时性能增加不少
缺点:由于进入OEMInterruptHandler的时候关闭了系统中断(当然你可以在ISR中
自己打开中断,不过处理起来较麻烦),所以如果处理时间过长,其他中断很可能被忽略,
造成中断丢失。并且系统被锁定,使得系统任务的响应变慢。
2. 中断处理的一般流程——IST模型
前面看到了 ISR模型的优缺点。作为WinCE,主要定位还是民用的消费类电子产品,
所以,对于中断响应的实时性不是特别高,所以系统的运行响应速度就显得更加重要。而且
目前的嵌入式设备的处理速度越来越高,已经几乎达到了当时奔 3 的水平。所以 ISR 的模
型并不适用于WinCE。
如果把中断服务程序当作一个系统进程或者线程来处理,这样就不会造成系统被锁定,
中断被屏蔽等问题,使得中断服务程序和其它进程、线程一样被系统管理调度。于是就有了
IST的概念
IST 模型的想法是,在 ISR 中判断到具体的中断源 IRQ,就返回一个标志,用来标记
需要哪个程序来服务中断,然后重新打开中断,恢复系统调度,系统根据这个标志来激活相
应的程序来服务中断。
这个就是最常用的中断处理模型。使得中断被关闭,系统被锁定的时间最短。
在 WinCE中,经常使用的就是建立中断服务线程(IST),然后以IRQ 来申请一个系统
逻辑中断号(SYSINTR),创建一个事件(Event),将 Event 与 SYSINTR 绑定,随后 IST
阻塞在等待Event上面。
ISR 中只给系统返回一个 SYSINTR,系统根据绑定关系激活相应的Event,使得随后
的 IST得以运行。
这就是 IST的一般服务流程
IST模型的缺点就是中断服务的延迟较大,从 ISR 返回,到 IST开始运行,中间需要
花费一定的时间,相比 ISR 模型的中断实时性较差,但是这种代价对于我们的应用是值得
的。
四 IST模型的实现
下面我们来看IST模型具体在我们的驱动中是如何实现的。
上面已经介绍了 IST模型的一般服务流程,下面我们针对驱动程序实例,来分析具体
的实现步骤。
1 驱动程序中 IST的构建与中断初始化
上面介绍的 IST流程中,很多步骤都是WinCE的内置支持,也就是说你只要调用相应
的 API就可以实现功能了,不需要自己编写太多的代码。只需要实现一些流程代码。
首先是驱动程序端的中断初始化。假设现在有一个驱动程序,需要服务中断源,IRQ
为 0x12。
a) 以 IRQ 为参数,申请SYSINTR,方法为调用
KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&(dwIrq),
sizeof(UINT32),&dwSysIntr,
sizeof(UINT32), NULL)
其中 dwIrq为IRQ号,即0x12
dwSysIntr 为系统中断号,也就是调用返回的结果存放的位置
b) 创建与 SYSINTR 绑定的Event
由于我们的IST是需要Event激活的,所以这里申请一个 Event。
申请 Event的步骤比较简单和标准
hISTEvent = CreateEvent(0,FALSE,FALSE,NULL);
c) 将SYSINTR 与Event绑定
调用 InterruptInitialize(dwSysIntr,hISTEvent,0,0)将 SYSINTR 与 Event绑
定,用来在OEMInterruptHandler 中返回SYSINTR 时激活相对应的 Event
d) 创建一个 IST,并且等待hISTEvent
到了这一步,中断关于系统方面的初始化基本结束,剩下的就是创建一个 IST,然
后等待 Event来运行中断服务代码,例如:
while(TRUE) {
WaitForSingleObject(hISTEvent,INFINITE) ==
WAIT_OBJECT_0)
…
}
这里需要注意的是IST什么时候创建都可以,但是在InterruptInitialize之前不要
运行 IST 以等待这个 Event,也就是说在 InterruptInitialize 之前不要使用这个
Event,否则会导致InterruptInitialize失败。
还有就是不要使用WaitForMultipleObjects来等待Event。
在中断处理完成之后需要调用 InterruptDone,参数为该中断的SYSINTR。来通
知系统,中断处理完成,系统重新使能该中断
到了这里,驱动的中断初始化工作就全部完成了。
2 OEM层需要做的工作
OEM 层 主 要 是 控 制 IRQ 的enable (BSPIntrEnableIrq) 与disable
(BSPIntrDisableIrq), 当然要初始化 IRQ 的配置,使其在正确的触发状态,比如上升延
触发
至此一个中断处理的IST模型就实现了,系统在IRQ触发时调用映射函数,获得相应
IRQ 的 SYSINTR,然后返回合法的SYSINTR给系统,系统查表激活相应的Event,对应
的 IST进行中断服务,然后再次等待 Event。
3 中断资源的释放
当不需要当前中断继续服务的时候可以通过调用KernelIoControl 来释放申请到的
SYSINTR,具体格式为:
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, dwSysIntr, sizeof(DWORD),
NULL, 0, NULL);
其中 dwSysIntr 就是需要释放的 SYSINTR号码。
五 可安装的 ISR
1 为什么要使用可安装 ISR(以下简称 IISR)
需要 IISR 的目的有两种:
I. 动态的安装中断程序
在系统运行的过程中注册中断,这种中断一般是不可预知设备的中断,常用在总线设备
中,比如PCI设备
II. 中断共享
当多个中断源使用同一个中断号(IRQ)时,就需要使用 IISR 来实现了
当然如果是需要动态安装的共享中断就最适合了。
因为我们的 IST模型中,中断服务程序就是驱动中的IST,IRQ与 IST是一对一的关
系。所以在需要动态添加一个中断服务程序的时候就没有办法处理了。
同样由于 IRQ 与 IST 的一一对应关系对于一个 IRQ 对应多个需要服务的 IST 就同样
没有办法处理。
基于上面的情况才会有IISR 的出现,IISR 从本质上是在ISR 中提供了一个接口,当
ISR 调用 NKCallIntChain时,以此IRQ为参数,在链表中依次查找是哪一个服务程序来
服务这次 IRQ,然后返回相应的 SYSINTR,此后的动作与 IST 模型就基本一样,通过
SYSINTR 来激活Event,从而启动相应的 IST。
所以 IISR 的实现就是动态的向某一个IRQ服务程序链表添加结点的过程。
2 IISR的实现
下面我们来看看IISR 的具体实现步骤:
首先我们需要了解IISR服务中断的实现原理,如上面描述的,根据IRQ,来顺序调用
链表中的中断处理程序。所以我们可以有两个选择,一个就是类似 ISR 模型,直接在链表
中的中断处理程序中判断是不是自己的中断,并且做处理。还有一种方式就是类似 IST 模
型,如果判断是自己的中断,则返回一个SYSINTR,以此SYSINTR 来激活IST。
无论哪种方法,关于注册中断和查询中断的方式是一样的,下面我们来看下如何将中断
程序添加到链表,又如何在中断来的时候去搜索链表。
Microsoft提供了一个通用的IISR的处理模型,叫做GIISR,这是一个以 IST模型处
理 IISR 的模块,源程序可以在WINCE500\PUBLIC\COMMON\OAK\DRIVERS\GIISR
找到。熟悉了 GIISR,想实现自己的 IISR 处理程序或者基于 ISR 模型的处理,都比较简
单了。
下面我们就分析这种比较通用的处理 IISR的模型。
a) 首先我们需要以 IRQ 来申请 SYSINTR,并且将SYSINTR 与 Event 绑定,这些
步骤与IST模型中介绍的一样,这里就不重复叙述了,IISR 在这里与 IST模型并
没有任何的不同。其与 IST 模型的唯一不同点就是如何根据 IRQ 来判断相应的
SYSINTR。
在 IST 模型中是 OEM写死的一个判断程序,而 IISR 可以动态来注册一个判断程
序给系统调用,这是唯一的实现区别。
b) 下面我们需要注册可安装中断程序的 dll,和dll中的中断处理函数,并且将他们与
某一个特定的IRQ相关联
这个过程是通过调用LoadIntChainHandler函数来实现的。
这里我们的中断服务dll叫做”giisr.dll”,处理函数名叫做”ISRHandler”,对应IRQ
为0x20,则函数调用形式如下:
HANDLE hIsrHandler = LoadIntChainHandler(TEXT(“giisr.dll”),
TEXT(“ISRHandler”), 0x20);
c) 上一步在GIISR中通过CreateInstance把这个新的中断处理程序加入GIISR自
己的管理。GIISR 的主要作用就是判断当中断来的时候,是不是其内部数组中的某
个成员需要服务中断。所以需要更多的信息用来判断中断是否匹配当前的中断服务
程序,所以我们需要把信息传递进去,这里就是调用KernelLibIoControl。
具体的方法为:
KernelLibIoControl(hIsrHandler,IOCTL_GIISR_INFO,&giisr_info,
sizeof(GIISR_INFO), NULL, 0, NULL);
这里就是把 giisr_info 的内容传递给刚才注册的中断,giisr_info 是一个
GIISR_INFO的结构体,其内容如下:
typedef struct _GIISR_INFO {
DWORD SysIntr; // SYSINTRfor ISR handler to return
(if associated device is asserting IRQ)
BOOL CheckPort; // If true,check port to see if device is
asserting IRQ
BOOL PortIsIO; // Port isIO port (possibly true only for
x86)
BOOL UseMaskReg; // If true, read fromMaskAddr to
obtain mask
DWORD PortAddr;
前一段时间研究了一下WinCE下的中断结构,整理了一下,希望与大家讨论。
最下面有PDF版本下载,便于保存
Windows Embedded CE
中断结构分析
关键字:WinCE,中断,体系,结构
摘要:本文主要以WinCE .NET 5.0为操作系统平台,ARM为硬件平台,分析了WinCE下
中断的结构与实现方式
前言
在嵌入式系统当中,对于中断的处理是非常重要的一部分内容。许多外围设备都需要通
过中断来实现自己的功能或者与系统内核交互,系统时钟本身也是由时钟中断产生的。所以
本文旨在分析WinCE下的中断的结构,以及常用的几种实现方式,来帮助读者了解WinCE
中断体系及实现自己的中断处理结构。
下面的介绍如非特殊说明,均以 ARM架构为硬件基础,操作系统代码使用 Windows
embedded CE 5.0。
一 WinCE中断体系结构
先看图 1:
图 1 WinCE中断体系结构
这张是经典的说明中断体系的图,我们可以通过分析这张图来了解WinCE的中断体系。
从结构上看,WinCE中断涉及4层,即:硬件层、内核层、OAL层、IST处理层。了
解这 4层之间的交互传递将对我们了解WinCE中断处理很有帮助。
1 硬件层:
硬件层就是实际触发中断的硬件,这里主要有两方面作用,一个是触发中断,第二个是
enable/disable硬件中断。
2 内核层:
这一层由内核来处理,包括中断异常产生后跳转到相应的ISR,以及根据SYSINTR来
触发相应的Event。关于SYSINTR 和 IRQ 的概念后面会说明。
3 OAL层
这一层主要就是我们需要实现的代码了,来识别硬件IRQ,对应到SYSINTR。
4 IST处理层
一般使用 IST来做实际的中断处理,这样不会占用很多的锁定系统时间来处理中断,
但是对中断的实时性大打折扣
二 IRQ,ISR,IST和 SYSINTR
说到这里先解释下IRQ,ISR,IST及 SYSINTR 的概念、意义及相互关系。
IRQ:
IRQ (Interrupt request),中断请求。
这里就是外设或其它请求服务的设备发出来的中断。属于硬件中断,可能是一个电平触发的
GPIO 中断,也可能是内部DMA的一个中断。
ISR:
ISR (Interrupt serviceroutine), 中断处理程序。
WinCE实际上使用 ISR来处理中断,即默认的中断入口函数,在 ARM体系中,系统默认的
ISR就是 OEMInterruptHandler
IST:
IST (Interrupt servicethread), 中断服务线程。
在 ARM 的结构中,ISR 一般不会用来进行任何实际的操作,而只是返回一个 SYSINTR,
实际的操作全部在IST中完成,IST一般是在Device Manager 的一个线程中运行的一段
高优先级的应用程序代码,用来服务实际的中断请求。
SYSINTR:
在 WinCE中,SYSINTR 就是 system interrupt,就是一个操作系统的逻辑中断。
一般对于中断的处理方式都是将一个IRQ映射为一个或者多个(中断共享)SYSINTR,而后,
在实际的ISR中根据IRQ返回一个对应的SYSINTR用来告诉操作系统需要服务的逻辑对
象。
使用逻辑中断的好处当然就是可以实现虚拟的中断(一个 SYSINTR 就被 OS 认为是一个独
立中断)和中断共享(单 IRQ对应多 SYSINTR)。
逻辑中断是WinCE需要处理的实际对象,至于这个对象是一个共享的IRQ,还是一个虚拟
的中断,还是独立的物理中断,系统并不过问,从而隔离了硬件与逻辑,我们的 ISR 需要
做的也正是这种物理中断到逻辑中断的映射。
三 WinCE中断处理原理
下面基于 ARM 体系,来介绍 WinCE中断处理的流程与原理。
对于一个硬件IRQ中断,系统内核在捕获之后,会交给OEMInterruptHandler 处理,
这个函数就是我们实现中断处理的中心函数,首先我们从CPU 的寄存器里获得中断的信息,
这些信息告诉我们到底是哪个 IRQ 源触发了中断。
一般实现中断服务的方式有以下几种:
1. 简单中断处理——ISR模型
最简单的中断处理办法就是在ISR中直接处理,这里就是指在OEMInterruptHandler
中直接对中断源进行判断,然后调用服务程序。
这种方式的优点和缺点一样明显。
优点:快速的响应了中断处理,使系统的实时性能增加不少
缺点:由于进入OEMInterruptHandler的时候关闭了系统中断(当然你可以在ISR中
自己打开中断,不过处理起来较麻烦),所以如果处理时间过长,其他中断很可能被忽略,
造成中断丢失。并且系统被锁定,使得系统任务的响应变慢。
2. 中断处理的一般流程——IST模型
前面看到了 ISR模型的优缺点。作为WinCE,主要定位还是民用的消费类电子产品,
所以,对于中断响应的实时性不是特别高,所以系统的运行响应速度就显得更加重要。而且
目前的嵌入式设备的处理速度越来越高,已经几乎达到了当时奔 3 的水平。所以 ISR 的模
型并不适用于WinCE。
如果把中断服务程序当作一个系统进程或者线程来处理,这样就不会造成系统被锁定,
中断被屏蔽等问题,使得中断服务程序和其它进程、线程一样被系统管理调度。于是就有了
IST的概念
IST 模型的想法是,在 ISR 中判断到具体的中断源 IRQ,就返回一个标志,用来标记
需要哪个程序来服务中断,然后重新打开中断,恢复系统调度,系统根据这个标志来激活相
应的程序来服务中断。
这个就是最常用的中断处理模型。使得中断被关闭,系统被锁定的时间最短。
在 WinCE中,经常使用的就是建立中断服务线程(IST),然后以IRQ 来申请一个系统
逻辑中断号(SYSINTR),创建一个事件(Event),将 Event 与 SYSINTR 绑定,随后 IST
阻塞在等待Event上面。
ISR 中只给系统返回一个 SYSINTR,系统根据绑定关系激活相应的Event,使得随后
的 IST得以运行。
这就是 IST的一般服务流程
IST模型的缺点就是中断服务的延迟较大,从 ISR 返回,到 IST开始运行,中间需要
花费一定的时间,相比 ISR 模型的中断实时性较差,但是这种代价对于我们的应用是值得
的。
四 IST模型的实现
下面我们来看IST模型具体在我们的驱动中是如何实现的。
上面已经介绍了 IST模型的一般服务流程,下面我们针对驱动程序实例,来分析具体
的实现步骤。
1 驱动程序中 IST的构建与中断初始化
上面介绍的 IST流程中,很多步骤都是WinCE的内置支持,也就是说你只要调用相应
的 API就可以实现功能了,不需要自己编写太多的代码。只需要实现一些流程代码。
首先是驱动程序端的中断初始化。假设现在有一个驱动程序,需要服务中断源,IRQ
为 0x12。
a) 以 IRQ 为参数,申请SYSINTR,方法为调用
KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&(dwIrq),
sizeof(UINT32),&dwSysIntr,
sizeof(UINT32), NULL)
其中 dwIrq为IRQ号,即0x12
dwSysIntr 为系统中断号,也就是调用返回的结果存放的位置
b) 创建与 SYSINTR 绑定的Event
由于我们的IST是需要Event激活的,所以这里申请一个 Event。
申请 Event的步骤比较简单和标准
hISTEvent = CreateEvent(0,FALSE,FALSE,NULL);
c) 将SYSINTR 与Event绑定
调用 InterruptInitialize(dwSysIntr,hISTEvent,0,0)将 SYSINTR 与 Event绑
定,用来在OEMInterruptHandler 中返回SYSINTR 时激活相对应的 Event
d) 创建一个 IST,并且等待hISTEvent
到了这一步,中断关于系统方面的初始化基本结束,剩下的就是创建一个 IST,然
后等待 Event来运行中断服务代码,例如:
while(TRUE) {
WaitForSingleObject(hISTEvent,INFINITE) ==
WAIT_OBJECT_0)
…
}
这里需要注意的是IST什么时候创建都可以,但是在InterruptInitialize之前不要
运行 IST 以等待这个 Event,也就是说在 InterruptInitialize 之前不要使用这个
Event,否则会导致InterruptInitialize失败。
还有就是不要使用WaitForMultipleObjects来等待Event。
在中断处理完成之后需要调用 InterruptDone,参数为该中断的SYSINTR。来通
知系统,中断处理完成,系统重新使能该中断
到了这里,驱动的中断初始化工作就全部完成了。
2 OEM层需要做的工作
OEM 层 主 要 是 控 制 IRQ 的enable (BSPIntrEnableIrq) 与disable
(BSPIntrDisableIrq), 当然要初始化 IRQ 的配置,使其在正确的触发状态,比如上升延
触发
至此一个中断处理的IST模型就实现了,系统在IRQ触发时调用映射函数,获得相应
IRQ 的 SYSINTR,然后返回合法的SYSINTR给系统,系统查表激活相应的Event,对应
的 IST进行中断服务,然后再次等待 Event。
3 中断资源的释放
当不需要当前中断继续服务的时候可以通过调用KernelIoControl 来释放申请到的
SYSINTR,具体格式为:
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, dwSysIntr, sizeof(DWORD),
NULL, 0, NULL);
其中 dwSysIntr 就是需要释放的 SYSINTR号码。
五 可安装的 ISR
1 为什么要使用可安装 ISR(以下简称 IISR)
需要 IISR 的目的有两种:
I. 动态的安装中断程序
在系统运行的过程中注册中断,这种中断一般是不可预知设备的中断,常用在总线设备
中,比如PCI设备
II. 中断共享
当多个中断源使用同一个中断号(IRQ)时,就需要使用 IISR 来实现了
当然如果是需要动态安装的共享中断就最适合了。
因为我们的 IST模型中,中断服务程序就是驱动中的IST,IRQ与 IST是一对一的关
系。所以在需要动态添加一个中断服务程序的时候就没有办法处理了。
同样由于 IRQ 与 IST 的一一对应关系对于一个 IRQ 对应多个需要服务的 IST 就同样
没有办法处理。
基于上面的情况才会有IISR 的出现,IISR 从本质上是在ISR 中提供了一个接口,当
ISR 调用 NKCallIntChain时,以此IRQ为参数,在链表中依次查找是哪一个服务程序来
服务这次 IRQ,然后返回相应的 SYSINTR,此后的动作与 IST 模型就基本一样,通过
SYSINTR 来激活Event,从而启动相应的 IST。
所以 IISR 的实现就是动态的向某一个IRQ服务程序链表添加结点的过程。
2 IISR的实现
下面我们来看看IISR 的具体实现步骤:
首先我们需要了解IISR服务中断的实现原理,如上面描述的,根据IRQ,来顺序调用
链表中的中断处理程序。所以我们可以有两个选择,一个就是类似 ISR 模型,直接在链表
中的中断处理程序中判断是不是自己的中断,并且做处理。还有一种方式就是类似 IST 模
型,如果判断是自己的中断,则返回一个SYSINTR,以此SYSINTR 来激活IST。
无论哪种方法,关于注册中断和查询中断的方式是一样的,下面我们来看下如何将中断
程序添加到链表,又如何在中断来的时候去搜索链表。
Microsoft提供了一个通用的IISR的处理模型,叫做GIISR,这是一个以 IST模型处
理 IISR 的模块,源程序可以在WINCE500\PUBLIC\COMMON\OAK\DRIVERS\GIISR
找到。熟悉了 GIISR,想实现自己的 IISR 处理程序或者基于 ISR 模型的处理,都比较简
单了。
下面我们就分析这种比较通用的处理 IISR的模型。
a) 首先我们需要以 IRQ 来申请 SYSINTR,并且将SYSINTR 与 Event 绑定,这些
步骤与IST模型中介绍的一样,这里就不重复叙述了,IISR 在这里与 IST模型并
没有任何的不同。其与 IST 模型的唯一不同点就是如何根据 IRQ 来判断相应的
SYSINTR。
在 IST 模型中是 OEM写死的一个判断程序,而 IISR 可以动态来注册一个判断程
序给系统调用,这是唯一的实现区别。
b) 下面我们需要注册可安装中断程序的 dll,和dll中的中断处理函数,并且将他们与
某一个特定的IRQ相关联
这个过程是通过调用LoadIntChainHandler函数来实现的。
这里我们的中断服务dll叫做”giisr.dll”,处理函数名叫做”ISRHandler”,对应IRQ
为0x20,则函数调用形式如下:
HANDLE hIsrHandler = LoadIntChainHandler(TEXT(“giisr.dll”),
TEXT(“ISRHandler”), 0x20);
c) 上一步在GIISR中通过CreateInstance把这个新的中断处理程序加入GIISR自
己的管理。GIISR 的主要作用就是判断当中断来的时候,是不是其内部数组中的某
个成员需要服务中断。所以需要更多的信息用来判断中断是否匹配当前的中断服务
程序,所以我们需要把信息传递进去,这里就是调用KernelLibIoControl。
具体的方法为:
KernelLibIoControl(hIsrHandler,IOCTL_GIISR_INFO,&giisr_info,
sizeof(GIISR_INFO), NULL, 0, NULL);
这里就是把 giisr_info 的内容传递给刚才注册的中断,giisr_info 是一个
GIISR_INFO的结构体,其内容如下:
typedef struct _GIISR_INFO {
DWORD SysIntr; // SYSINTRfor ISR handler to return
(if associated device is asserting IRQ)
BOOL CheckPort; // If true,check port to see if device is
asserting IRQ
BOOL PortIsIO; // Port isIO port (possibly true only for
x86)
BOOL UseMaskReg; // If true, read fromMaskAddr to
obtain mask
DWORD PortAddr;
相关文章推荐
- WinCE中断结构分析
- WinCE中断结构分析
- WinCE中断结构分析
- WinCE中断结构分析
- Linux中断处理体系结构分析(三)
- WinCE 6.0中断驱动程序分析
- S3C2410 && WinCE6.0的中断处理分析
- ARM中断分析之四:WinCE的OAL层的中断分析
- Linux中断处理体系结构分析
- WinCE中断体系结构
- S3C2410 && WinCE6.0的中断处理分析
- WinCE 6.0中断驱动程序分析
- Linux中断处理体系结构分析(一)
- 转载——wince源码分析中断之map.c
- Windows Embedded CE 中断结构分析
- Linux中断处理体系结构分析
- ARM中断分析之三:WinCE驱动的中断分析
- arm-Linux中断处理体系结构与处理流程分析
- Linux中断处理体系结构分析(1)
- wince源码分析中断之map.c