Chinaunix首页 | 论坛 | 博客
  • 博客访问: 407240
  • 博文数量: 128
  • 博客积分: 2247
  • 博客等级: 大尉
  • 技术积分: 767
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-17 09:30
文章分类

全部博文(128)

文章存档

2011年(4)

2010年(124)

我的朋友

分类: 嵌入式

2010-07-27 08:51:57

发布日期 : 7/23/2004 | 更新日期 : 7/23/2004

Nat Frampton(Windows Embedded MVP
Real Time Development Corp. 总裁)

适用于:
Microsoft Windows CE .NET with Microsoft Platform Builder 4.0

本页内容
概述
中断体系结构
OAL ISR 处理
可安装的 ISR
IST 中断处理
导致延迟的因素
小结

概述

通 过 Microsoft Windows CE .NET,Microsoft 已经升级了 Windows CE 的中断体系结构。该操作系统 (OS) 所具有的处理共享中断的能力极大地扩展了 Windows CE .NET 支持许多中断体系结构的能力。本文从原始设备制造商 (OEM) 和应用程序开发人员的角度探讨了处理中断的方案。本文还探讨了 OEM 适配层 (OAL) 中断服务例程 (ISR) 处理;提供了可安装 ISR,包括一个简单的入门级外壳程序;介绍了中断服务线程 (IST) 中断处理,并提供了一个初始化和执行模板。最后,本文分析了 ISR 和 IST 的延迟根源。

中断体系结构

探讨 Microsoft Windows CE .NET 中断体系结构的第一步是定义中断过程中硬件、内核、OAL 和线程交互的总体模型。下图大概说明了这些不同级别的职责以及导致状态变化的转换。

winceinterruptarch_fig1

1.

该 图阐述了中断过程中的主要转换,时间按从左到右的顺序递增。该图的最低层为硬件和中断控制器的状态。次低层是中断服务过程中的内核交互。OAL 描述了主板支持软件包 (BSP) 的职责。最顶层阐述了中断服务所需的应用程序或驱动程序线程交互。该图阐述了单个中断过程中的交互;它表示了 Windows CE .NET 拥有共享中断的新能力。

活动从该图最左侧部分以直线表示的中断开始。生成了一个异常,导致内核 ISR 向量被加载到处理器中。内核 ISR 与硬件交互,禁用所有处理器上的所有具有相同和较低优先级的中断(ARM 和 Strong ARM 体系结构除外)。然后,内核推进到已为该特定中断注册的 OAL ISR。此后,OAL ISR 既可以直接处理中断,也可以使用 NKCallIntChain 遍历已安装的 ISR 列表。主 ISR 或任何已安装的 ISR 随后执行任意工作,并且为该设备返回名为 SYSINTR 的映射中断。如果该 ISR 确定其相关设备没有导致该中断,该 ISR 将返回 SYSINTR_CHAIN,这会使 NKCallIntChain( ) 遍历 ISR 列表以到达链中的下一个中断。ISR 按照它们的安装顺序调用(它们在安装时会在调用列表上创建一个优先级)。

在调用了单个 ISR 或其相关 ISR 链之后,返回值可能为下列值之一:

返回值

操作

SYSINTR_NOP

中断不与设备的任何已注册 ISR 关联。内核启用所有其他中断。

SYSINTR

中断与已知的已注册 ISR 和设备关联。

SYSINTR_RESCHED

中断是由请求 OS 重新调度的计时器到期引起的。

SYSINTR 返回值是我们讨论的重点。一旦 ISR 完成,内核将重新启用处理器上除已识别的中断之外的所有中断。然后,内核将通知与 SYSINTR 值关联的事件。

然后,驱动程序或应用程序的 IST 将能够运行(假设它是准备好运行的最高优先级线程)。IST 将与相关设备通讯,并从完成它的中断交互的设备中读取所有必要的数据。然后,IST 用关联的 SYSINTR 值来调用 InterruptDone( ),以通知它已完成。

内核在接收到 SYSINTR 值的 InterruptDone 时,将重新启用指定的中断。只有从这时开始,才能接收该设备的其他中断。

这只是对 Windows CE .NET 内部活动的中断序列的一个粗略介绍。现在,我们将详细研究上述每个组件及其职责。

OAL ISR 处理

OAL ISR 是属于平台的基本中断处理程序。下面是 X86 平台的实际 ISR。配置分析和 ILTiming 支持已被删除。X86 ISR 是所有基于 Windows CE 的平台的代表。它演示了能够处理系统中所有中断的单个 ISR。

该 ISR 的目标是向内核交还引起中断的相关设备的 SYSINTR 号。ISR 执行以下活动序列。

  • PICGetCurrentInterrupt (PIC) 中获取当前硬件中断

  • 如果该中断是 INTR_TIMER0(系统计时器)

    • 更新OS 的 CurMSec 保持时间

    • 检查并确认是否已经注册了重新启动地址 (RebootHandler)

  • 如果中断是 INTR_RTC

    • ISR 检查并确认闹钟是否已到期 (SYSINTR_RTC_ALARM)

  • 如果中断小于 INTR_MAXIMUM

    • 调用中断链 (NKCallIntrChain)

    • NKCallIntrChain 的返回值设置为该返回值

    • 如果中断链未包含中断:(SYSINTR_CHAIN)

      映射当前硬件中断 (OEMTranslateIRQ)

      如果该中断被注册到 OEMInit 中的 HookInterrupt

      OEMTranslateIRQ 返回 SYINTR

      如果该中断未注册,则返回 SYSINTR_NOP

    • 启用除当前中断以外的所有中断。(PICEnableInterrupt}

    • 完成恰当的中断结束工作以通知 PIC 中断已完成 (EOI)

  • ISR 返回下列值之一:

    • SYSINTR_NOP — 没有任何 ISR 包含该中断

    • SYSINTR_RESCHED — 重新调度计时器已到期

    • SYSINTR — ISR 已经包含该中断

    • SYSINTR_RTC_ALARM — 闹钟已到期

ULONG PeRPISR(void)
{
ULONG ulRet = SYSINTR_NOP;
UCHAR ucCurrentInterrupt;

ucCurrentInterrupt = PICGetCurrentInterrupt();

if (ucCurrentInterrupt == INTR_TIMER0) {

CurMSec += SYSTEM_TICK_MS;
CurTicks.QuadPart += TIMER_COUNT;

if ((int) (CurMSec - dwReschedTime) >= 0)
ulRet = SYSINTR_RESCHED;
}

//
// Check if a reboot was requested.
//
if (dwRebootAddress) {
RebootHandler();
}

} else if (ucCurrentInterrupt == INTR_RTC) {
UCHAR cStatusC;
// Check to see if this was an alarm interrupt
cStatusC = CMOS_Read( RTC_STATUS_C);
if((cStatusC & (RTC_SRC_IRQ)) == (RTC_SRC_IRQ))
ulRet = SYSINTR_RTC_ALARM;
} else if (ucCurrentInterrupt <= INTR_MAXIMUM) {
// We have a physical interrupt ID, return a SYSINTR_ID

// Call interrupt chain to see if any installed ISRs handle this
// interrupt
ulRet = NKCallIntChain(ucCurrentInterrupt);

if (ulRet == SYSINTR_CHAIN) {
ulRet = OEMTranslateIrq(ucCurrentInterrupt);
if (ulRet != -1)
PICEnableInterrupt(ucCurrentInterrupt, FALSE);
else
ulRet = SYSINTR_NOP;
} else {
PICEnableInterrupt(ucCurrentInterrupt, FALSE);
}
}

if (ucCurrentInterrupt > 7 || ucCurrentInterrupt == -2) {
__asm {
mov al, 020h ; Nonspecific EOI
out 0A0h, al
}
}
__asm {
mov al, 020h ; Nonspecific EOI
out 020h, al
}

return ulRet;
}

如果 ISR 没有为已经用 OAL 的 OEMInit 中的 HookInterrupt 初始化的中断安装,则该 ISR 将返回适当的 SYSINTR 值。

如果只能通过 IST 交互为设备提供服务,则不需要为中断安装可安装的 ISR。通过对 OALOEMInit 中的 HookInterrupt 进行调用以启用中断就足够了。

ISR 代码是一段非常小且快速的代码。它的执行时间将直接影响整个系统中的中断的延迟。Windows CE 3.0 中引入的中断体系结构更改是能够嵌套中断。在进入 OAL ISR 的那一刻,所有具有较高优先级的中断都已被启用。ISR 可能被占先。如果该 ISR 内部的计时

阅读(1039) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~