您的位置:首页 > 其它

WINCE4.2到5.0(2)中断服务差异

2012-09-07 00:35 393 查看
WINCE4.2到5.0(2)中断服务差异

共同的内核函数:

OEMInterruptHandler():中断服务例程ISR

OEMInterruptEnable():

OEMInterruptDisable():

OEMInterruptDone():顾名思意,应用层在调用InterruptEnable、InterruptDisable、InterruptDone函数时会调用这几个内核函数
4.2下的OEMInterruptHandler()函数会跟据转进来的硬件IRQ中断号返回对应的SYSINTR逻辑中断号,也就是说如果需要修改两个中断号对应关系,可以直接在这个函数中修改,这里的这种对应、映射关系称之为静态映射。OEMInterruptEnable()...三个函数传进来的参数是SYSINTR逻辑中断号,可以根据OEMInterruptHandler()函数中的映射关系,对硬件中断IRQ来进行相应的操作。这几个函数分别位于platform\bsp\kernel\hal\cfw.c与bsp\kernel\hal\arm\armint.c文件中。换句话说4.2下的中断可以称之为静态映射,也就是不能在运行时的应用/驱动层将硬件与逻辑IRQ进行映射。
5.0下的OEMIntrruptHandler()函数位于:platform\common\src\arm\samsung\s3c2410x\intr\intr.c中。注意,他不像4.2中的该函直接将参数传递进来的硬件IRQ送出对应的逻辑SYSIRQ,而是调用OALIntrTranslateIrq()函数进行映射。OALIntrTranslateIrq()函数位于platform\common\src\common\intr\base\map.c文件中。这个函数只是简单的将以Irq参数为下标的数组中找出SYSIRQ,然后返回:

UINT32 OALIntrTranslateIrq(UINT32 irq)

{

UINT32 sysIntr = SYSINTR_UNDEFINED;

if (irq>=OAL_INTR_IRQ_MAXIMUM) goto cleanUp;

sysIntr = g_oalIrq2SysIntr[irq];

return sysintr;

...

}

看这里的g_oalIrq2SysIntr数组,还有一个与之对应的g_oalSysIntr2Irq数组,从名字上可以看出功能。这两个数组也定义在map.c文件中,是通过OALIntrMapInit()函数进行初始化的。这里也可以进行静态映射,使用OALIntrStaticTranslate这个函数,它的实现过程就是填充数组:

OALIntrStaticTranslate(UINT32 sysIntr, UINT32 irq)

{

...

g_oalSysIntr2Irq[sysIntr] = irq;

g_oalIrq2SysIntr[irq] = sysIntr;

...

}

看一下流程:OEMInit()=>OALIntrInit()=>OALIntrMapInit()这个就是对两个数组进行初始化=>BSPIntrInit()可以在这个函数里用OALIntrStaticTranslate()函数进行静态映射。
5.0下的OEMInterruptEnable()...这三个函数位于platform\common\src\common\INTR\common\oem.c文件小,大致流程是这样的:

OEMInterruptEnable()=>OALIntrTranslateSysIntr()这个函数是在将逻辑中断号转换成硬件的系统中断号,与OALIntrTranslateIrq()函数功相反,位于同一个文件中。=>OALIntrEnableIrq()这个函数先调用BSPIntrEnableIrq()使得BSP有机会先做处理,这个函数与OEMIntrruptHandler()位于同一个文件中,在platform\common\src\arm\samsung\s3c241x\intr\intr.c文件中。

OEMInterruptEnable()=>OALIntrTranslateSysIntr()=>OALIntrEnableIrqs()=>BSPIntrEnableIrq()

OEMInterruptDisable()=>OALIntrTranslateSysIntr()=>OALIntrDisableIrqs()=>BSPIntrDisableIrq()

OEMInterruptDone()=>OALIntrTranslateSysIntr()=>OALIntrDoneIrqs()=>BSPIntrDoneIrq()
总结:

跟4.2的区别,实际上主要是5.0可以/是在应用/驱动层使用OALIntrRequestSysIntr()动态请求/映射,而4.2好像不可以,至少我没找到。4.2的方法更简单明了,5.0的好处更明显,更改驱动等代码时无须动内核函数。

上面5.0使用到的几个函数分别位于下面的文件中:

platform\common\src\arm\samsung\s3c241x\intr\intr.c

OALIntrDisableIrqs()

OALIntrDoneIrqs()

OALIntrEnableIrqs()

OALIntrInit()

OALIntrRequestIrqs()

OEMInterruptHandler()
platform\smdk410\src\kernel\oal\init.c

OEMInit()
platform\smdk2410\src\kernel\oal\intr.c

BSPIntrActiveIrq()

BSPIntrDisableIrq()

BSPIntrDoneIrq()

BSPIntrEnableIrq()

BSPIntrInit()

BSPIntrRequestIrqs()
platform\common\src\common\intr\base\map.c

OALIntrMapInit()

OALIntrReleaseSysIntr()

OALIntrRequestSysIntr()

OALIntrStaticTranslate()

OALIntrTranslateIrq()

OALIntrTranslateSysIntr()
贴两个网上找到的资料,都是5.0的:
WinCE有两种私有的中断表,一种是物理中断——中断请求(IRQs),另一种是逻辑中断——SYSINTR值。WinCE必须将一个物理中断和一个逻辑中断关联起来。
物理中断号定义在platform\c8090\pubic\csp\arm\intel\pxa27x\inc\Bulverde_intr.h。
逻辑中断号定义在platform\c8090\platform\mainstoneii\src/inc\Bsp_cfg.h。
两个中断表定义在platform\c8090\platform\src\common\intr\base\map.c
static UINT32 g_oalSysIntr2Irq[SYSINTR_MAXIMUM];
static UINT32 g_oalIrq2SysIntr[OAL_INTR_IRQ_MAXIMUM];
OAL_INTR_IRQ_MAXIMUM定义在platform\c8090\common\src\inc\oal_intr.h,
#define OAL_INTR_IRQ_MAXIMUM 64
该值表示物理中断——IRQs的最大值,现在最大只支持到64。
SYSINTR_MAXIMUM定义在wm522\public\common\oak\inc\nkintr.h
#define SYSINTR_DEVICES 8
#define SYSINTR_MAX_DEVICES 64
#define SYSINTR_MAXIMUM (SYSINTR_DEVICES+SYSINTR_MAX_DEVICES)
OEM Adaptation Layer——OAL初始化函数是OEMInit(),它是WinCE的OAL层初始化函数,在基本初始化完成之后,由内核调用,定义在:
platform\c8090\platform\mainstoneii\src\kernel\oal\init.c。
在这里调用中断初始化函数:OALIntrInit(),该函数定义在:
platform\c8090\platform\common\src\arm\intel\pxa27x\intr\intr.c中,该函数首先调用函数OALIntrMapInit(),初始化前面提到的两个数组表g_oalSysIntr2Irq和goalIrq2SysIntr。该函数定义在platform\c8090\platform\common\src\common\intr\base\map.c,源码如下:
for (i = 0; i < SYSINTR_MAXIMUM; i++) {
g_oalSysIntr2Irq[i] = OAL_INTR_IRQ_UNDEFINED;
}
for (i = 0; i < OAL_INTR_IRQ_MAXIMUM; i++) {
g_oalIrq2SysIntr[i] = SYSINTR_UNDEFINED;
}
然后调用函数BSPIntrInit()将物理中断和逻辑中断关联起来,该函数定义在:
platform\c8090\platform\mainstoneii\src\kernel\oal\intr.c中。
关联代码例子如下:
OALIntrStaticTranslate(SYSINTR_PMIC, IRQ_GPIO0);
OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBOHCI);
OALIntrStaticTranslate(SYSINTR_TOUCH, IRQ_GPIOXX_WM9712);
OALIntrStaticTranslate(SYSINTR_TOUCH_CHANGED, IRQ_OSMR1);
OALIntrStaticTranslate(SYSINTR_KEYPAD, IRQ_KEYPAD);
前面都是逻辑中断,后面是物理中断。OALIntrStaticTranslate函数定义在:
platform\c8090\platform\common\src\common\intr\base\map.c,源码如下:
if (irq < OAL_INTR_IRQ_MAXIMUM && sysIntr < SYSINTR_MAXIMUM) {
g_oalSysIntr2Irq[sysIntr] = irq;
g_oalIrq2SysIntr[irq] = sysIntr;
}
OAL是位于WindowsCE内核与目标设备硬件之间的一个代码层,用于实现windowCE与目标设备硬件之间的通信。为了实现内核与硬件之间最基本的通信功能,OEM必须实现一些必要的功能,同时为了适合不同的硬件配置与操作系统功能,OEM有必要的选择实现一些其他的功能。

在OAL开发过程中,OEM需要实现下列主要功能或函数:

.Startup函数;

.调试串口;

.OEMInit函数;

.系统计时器;

.中断处理;

.内核的输入/输出(ioctl);

.KITL。

下面给出微软公司提供的各个功能的函数。

/***************************中断处理****************************/

./platform/Common/src/common/intr/base/map.c

The file implement simple table/array based mapping between IRQ and SYSINTR

which is suitable for most OAL implementations.

这个文件主要是用来定义IRQ和SYSIRQ的映射关系。

主要函数如下:

OALIntrMapInit();//此函数由OALInterruptInit调用来初始化IRQ和SYSIRQ的映射,只是简单的映射数组的初始化;初始化为未定义类型。

VOID OALIntrStaticTranslate(UINT32 sysIntr, UINT32 irq); //此函数建立IRQ和SYSINTR的静态映射,大多数情况下都不可能用到,只有在SYSINTR_RTC_ALARM和过时的设备驱动的时候会用到。

BOOL OALIntrTranslateSysIntr(UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs);//此函数将SYSINTR映射为它相应的IRQ,主要用在OEMInterruptXXX中对于给定SYSINTR得到其IRQs。

UINT32 OALIntrTranslateIrq(UINT32 irq);//此函数将IRQ映射为相应的SYSINTR。

UINT32 OALIntrRequestSysIntr(UINT32 count, const UINT32 *pIrqs, UINT32 flags);//此函数为给定的IRQ分配一个新的SYSINTR,如果此IRQ没有静态映射,就创建一个。

BOOL OALIntrReleaseSysIntr(UINT32 sysIntr);//此函数释放一个SYSINTR,并且消除存在的静态映射。

问题:

SYSINTR于IRQ的映射关系是不是一对一?BOOL OALIntrTranslateSysIntr(UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs)使用的是地址来进行映射,而UINT32 OALIntrTranslateIrq(UINT32 irq)使用值来进行映射,目前我认为应该是一对一的关系来映射的。

感想:

微软的程序写的很缜密,设计的很合理,能让我学到不少编程的方法。映射关系的编程可以参考微软的中断映射表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: