正如CE的帮助文档所言创建OAL是一个非常复杂的任务而通常的办法是复制原有的相同平台的OAL代码然后修改来适应平台的特殊要求也就是说对于没有特殊要求的平台复制原有相同平台的OAL代码就足够了由于OAL的复杂性在这篇文章中我只讲解常用的部分 一实现ISR ISR的概念 ISR(interrupt service routine)是处理IRQs(interrupt request line)的程序Windows CE用一个ISR来处理所有的IRQ请求当一个中断发生时内核的异常处理程序先调用内核ISR内核ISR禁用所有具有相同优先级和较低优先级的中断然后调用已经注册的OAL ISR程序一般ISR有下列特征 ) 执行最小的中断处理最小的中断处理指能够检验答复产生中断的硬件而把更多的处理工作留给IST(interrupt service thread) ) 当ISR完成时返回中断ID(中断ID大部分是预定义的) X平台的ISR结构 X平台的ISR保存在%_WINCEROOT%\PUBLIC\COMMON\OAK\CSP\I\OAL\fwpcc中函数名为PeRPISR下面分析一下此函数的主要代码 ULONG PeRPISR(void) { ULONG ulRet = SYSINTR_NOP; ///返回值既中断ID(以SYSINTR_为前缀) UCHAR ucCurrentInterrupt; ///当前中断号 if (fIntrTime) ////// fIntrTime 用于测试SR和IST的延时时间测试工具为ILTimingexe
ucCurrentInterrupt = PICGetCurrentInterrupt(); ////返回当前中断IRQ if (ucCurrentInterrupt == INTR_TIMER) ///IRQIRQ为系统时钟(system tick)中断具体见二实现系统时钟
if (dwRebootAddress) ////是否需要重启动 RebootHandler();
if(ucCurrentInterrupt == INTR_RTC) ////IRQrealtime clock的中断
else if (ucCurrentInterrupt <= INTR_MAXIMUM) ///如果中断小于 INTR_MAXIMUM { ulRet = NKCallIntChain(ucCurrentInterrupt); ////调用中断链 if (ulRet == SYSINTR_CHAIN) ///如果中断链未包含中断 ulRet = OEMTranslateIrq(ucCurrentInterrupt); ////在IRQ 和SYSINTR之间转换此函数返回IRQ对应的SYSINTR
PICEnableInterrupt(ucCurrentInterrupt FALSE); ///启用除当前中断以外的所有中断 } ///else if OEMIndicateIntSource(ulRet); ///通知内核已经发生SYSINTR中断 } [] [] [] |