再上一篇:6.6.1 Windows CE 简介
上一篇:6.6.2 基于 Intel Xscale 处理器的 Windows CE 开发环境定制 Windows CE
主页
下一篇:6.6.4 Windows CE 设备驱动开发
再下一篇:附录 A ARM 指令集、ARM 寻址方式和 Thumb 指令集速查表
文章列表

6.6.3 OAL(OEM Adaptation Layer)开发

嵌入式系统(修订本)——Intel XScale 结构与开发 陈章龙 著

如果开发的是硬件平台,而不是外部设备的驱动程序,那么需要开发OAL。OAL 是介 于Windows CE 内核与硬件平台之间的一个软件层,它由硬件平台生产者实现。从与软硬件 的关系来说,OAL 是最基本的驱动程序,它需要驱动CPU、存储器、基本输入输出设备等, 并向Windows CE 内核提供基本的调用。由于嵌入式系统的硬件千差万别,通过OAL 可以 使得Windows CE 内核面对一个相对统一的软件界面。

OAL 层的开发是Windows CE 能否运行的关键部分,它与Windows CE 内核,XScale 处理 器和硬件平台都有关系。OAL 涉及的内容很多,这里只做了梗概介绍,具体的实现需要查 阅相关资料,更要参考示例代码。

一、OAL 开发步骤

OAL 的开发主要分成以下四个步骤:

1. 初始化内核

完成必要的准备工作,描述系统配置。例如:平台的参考设计,Config.bib 文件设计。 这些描述关系到系统的初始化等方面。例如:MMU 初始化必须首先了解物理内存的大小和 具体的布局要求。

2. 创建基本OAL

确保系统在启动时能够进行初始化,启动调试用串行口,初始化通信设置,建立系统节 拍。因此本步骤必须实现基本的系统初始化代码,使之能够支持进一步调试,并保证内核初 始化完成,符合设计要求。

3. 加强OAL 功能

承接上一步骤,实现系统其它功能,例如:实现ISR,管理时钟和计时器,配置调试选
项,启动电源管理,并能向应用程序提供系统信息等,并确保整个操作系统可以启动。

4. 完成OAL

实现其它附加功能。
二、初始化内核
初始化内核主要包括三个部分:设计参考平台;配置 Config.bib 文件;实现 Startup 代 码。 设计参考平台需要确定平台的基本配置,这是操作系统需要满足的最低要求,例如是否具有 输入输出设备,它们是什么类型的。
配置 Config.bib 文件。系统内核通过 Config.bib 了解硬件的配置情况。例如 RAM 的物理地 址空间。Microsoft 提供了 Config.bib 的参考代码,其中的注释可以帮助实现我们自己的代 码。

Startup 代码需要能够初始化参考平台,如初始化CPU,设置ROM,RAMd 等,使之能 够达到一个确定状态,并进而调用系统初始化函数。X86 平台的系统初始函数是 KernelInitialize ,使用其它 CPU 的平台的系统初始函数是 KernelStart 。他们会调用 SystemInitialization ,而 它再调用 OAL 中的 OEMInit , OEMInitDebugSerial , OEMReadDebugByte,OEMWriteDebugByte 等。这些调用会在后面的步骤中实现。

三、创建基本 OAL
基本的OAL 需要实现基本的通信手段和基本的系统节拍。前者使得硬件平台能够向上 输出调试信息;后者需要在OEMInit 中注册处理定时器中断的ISR。

Windows CE 通过串行口将内核调试信息传送到Desktop 主机的调试监视程序。为此, 在OAL 必须实现下列调试串口的功能调用:

·OEMInitDebugSerial
·OEMReadDebugByte
·OEMWriteDebugByte
·OEMWriteDebugString
·OEMClearDebugCommError
内核将使用它们发送调试信息和接收调试命令。

OEMInit 是 OAL 中一个重要的函数调用。内核调用 OEMInit 来初始化硬件环境。在本 阶段,OEMInit 只需要建立一个最小的硬件运行环境即可。主要工作通常是使用 HookInterrupt 系统调用向内核注册处理系统定时器中断的ISR。此外,在OEMInit 中还可以 设置一些全局变量,如fUseIterations,MainMemoryEndAddress,pReadRegistryFromOEM, pWriteRegistryToOEM 等。

四、加强 OAL 功能
加强 OAL 包括:实现其它 ISR;管理时钟和定时器;配置调试选项;实现电源管理系 统;向应用程序提供系统信息;实现事件跟踪。我们主要了解ISR 和与ARM 处理器有关的 内容。
上一个阶段注册了系统定时器中断的 ISR,现在需要添加其它中断的 ISR。在注册 ISR 时需要中断标识号,这样中断发生时异常处理能够根据中断源调用相应的ISR。Windows CE 预定义了一些自用的中断标识号,如 SYSINTR_TIMING 和 SYSINTR_MAXUMUM,它们 定义在 Nkintr.h 中。自定义的中断标识号可以定义在 OALintr.h 文件中,自定义的中断标识 号必须小于SYSINTR_MAXUMUM 或 SYSINTR_FIRMWARE+23。接下来就要编写ISR 代 码,这部分代码必须响应硬件的中断请求,辨认中断源,并返回中断标识号。有些时候需要 在ISR 和IST 之间传递数据,这可以通过先在Config.bib 中保留物理内存,然后ISR 写入数 据,最后有 IST 使用 MMMapIoSpace 调用将共享的物理内存映射到虚地址空间再读取的方 式解决。为了实现ISR 管理,硬件平台生产者还需要实现:
·OEMInterruptEnable
·OEMInterruptDisable
·OEMInterruptDone
在ARM 平台上使用Windows CE 有一些需要注意的地方。
·ARM 的I/O 寄存器与内存统一编址,使用C 语言也能访问它们,所以可以使用C 来实现

ISR。

·硬件资源可以以1MB 为单位映射到Windows CE 的虚地址空间。为此在OAL 中需要定义 一张映射表——OEMAddressTable,由它将 4G 的物理地址空间映射到 Windows CE 内核的

512M 的静态映射空间。下面是OEMAddressTable 定义的一个例子:

EXPORT OEMAddressTable[DATA] OEMAddressTable

;;;-------------------------------------------------------------

;;; Virtual(cached) Phys Addr MB

;;;-------------------------------------------------------------

DCD PCMCIA_S1_CMN_C_VIRTUAL, PCMCIA_S1_CMN_PHYSICAL, 64

; SA11X0 PCMCIA Slot 1 Common memory space

;- defined in SA11X0.inc

DCD PCMCIA_S1_ATTR_C_VIRTUAL, PCMCIA_S1_ATTR_PHYSICAL, 32

; SA11X0 PCMCIA Slot 1 Attribute memory space

;- defined in SA11X0.inc

DCD PCMCIA_S1_IO_C_VIRTUAL, PCMCIA_S1_IO_PHYSICAL, 32

; SA11X0 PCMCIA Slot 1 I/O memory space

;- defined in SA11X0.inc

DCD PCMCIA_S0_CMN_C_VIRTUAL, PCMCIA_S0_CMN_PHYSICAL, 64

; SA11X0 PCMCIA Slot 0 Common memory space

;- defined in SA11X0.inc

DCD PCMCIA_S0_ATTR_C_VIRTUAL, PCMCIA_S0_ATTR_PHYSICAL, 32

; SA11X0 PCMCIA Slot 0 Attribute memory space

;- defined in SA11X0.inc

DCD PCMCIA_S0_IO_C_VIRTUAL, PCMCIA_S0_IO_PHYSICAL, 32

; SA11X0 PCMCIA Slot 0 I/O memory space

; - defined in SA11X0.inc

DCD DRAM_BANK1A_C_VIRTUAL, DRAM_BANK1A_PHYSICAL, DRAM_MAPPED

; DRAM on Platform

DCD DRAM_BANK1B_C_VIRTUAL, DRAM_BANK1B_PHYSICAL, FLASHRAM_MAPPED

; Flash/ROM or DRAM used to simulate FLASH/ROM

DCD SA11X0DB_REG_BASE_C_VIRTUAL, SA11X0DB_REG_BASE_PHYSICAL, 1

; SA-1110 Dev board CPLD register space

DCD SA11X1DB_REG_BASE_C_VIRTUAL, SA11X1DB_REG_BASE_PHYSICAL, 1

; SA-1111 Debug board CPLD register space

DCD SA11X1_BASE_C_VIRTUAL, SA11X1_BASE_PHYSICAL, 4

; SA11X1 Control Registers - defined in SA1101.inc

DCD DMA_BASE_C_VIRTUAL, DMA_BASE_PHYSICAL, 4

; SA11X0 DMA Controller and LCD Controller

;Registers - defined in SA11X0.inc

DCD MEMC_BASE_C_VIRTUAL, MEMC_BASE_PHYSICAL, 4

; SA11X0 Memory control registers

;- defined in SA11X0.inc

DCD SC_BASE_C_VIRTUAL, SC_BASE_PHYSICAL, 4

; SA11X0 System control registers

;- defined in SA11X0.inc

DCD ZBANK_BASE_C_VIRTUAL, ZBANK_BASE_PHYSICAL, 4

;ZeroBank-mappedtoSA-1100cachecleaning

; regions - defined in SA1100.inc

DCD SER_BASE_C_VIRTUAL, SER_BASE_PHYSICAL, 4

; SA11X0 Serial (UART/MCP/SSP/HSSP)

; port control registers

DCD APP_FLASH_C_VIRTUAL, APP_FLASH_PHYSICAL,FLASHROM_MAPPED

; Application FLASH

DCD DRAM_BANK2_C_VIRTUAL, DRAM_BANK2_PHYSICAL, FLASHROM_MAPPED

; DRAM on SA1111DB

DCD BOOT_FLASH_C_VIRTUAL, BOOT_FLASH_PHYSICAL, FLASHROM_MAPPED

; FLASH/ROM

DCD 0x00000000, 0x00000000, 0

; End of Table (MB MUST BE ZERO!)

每一行的第一项是虚地址;第二项是资源的物理地址;第三项是需要映射的块的大小,
以1MB 为单位。
定义OEMAddressTable 表时需要特别考虑RAM 访问是的效率问题。
·ARM 处理器除了 IRQ 外,还有特别的 FIQ ,所以必须要在 OAL 中实现

OEMInterruptHandlerFIQ 调用,即便它什么也不做,只是一个空函数而已。

·硬件设备生产者必须在 OEMInterruptHandler 中采用适当的策略来屏蔽中断,以实现中断
嵌套。
·在 OEMInit 中对 CEProcessorType 赋值,只有这样才能在调用 GetSystemInfo 时得到正确 的处理器类型。如:

CEProcessorType=PROCESSOR_STRONGARM;

加强OAL 功能的内容很多,详细的资料参见Platform Builder 3.0 的文档。
五、完成 OAL
这是开发OAL 的最后一个步骤,完善OAL 的所有功能。通常包括:
·实现OAL 中的进程日志函数。进程日志函数可以帮助你监视系统中各个进程线程的运行 情况,查找系统瓶颈。
·创建 CEDDK。通过实现 Ddk_bus.c,Ddk_io.c,Ddk_map.c 创建 Ceddk.dll。Ceddk.dll 是 一个设备驱动的库,提供硬件总线,I/O 和读写的软件接口。
·定义扩展内存。除了系统固有的内存,还可以动态通过CF 卡等方式扩展内存,这不会影 响系统的运行,但是去除扩展内存会引起系统冷启动。
·清楚对象存储。系统热启动不会清除内存中的数据,这些数据称为对象存储。有些时候你 需要彻底重新启动系统(而不想拔电源),包括清空内存中的数据,需要一种手段保证从启 动是一次冷启动。这种功能由清除对象存储实现。
·支持高精度定时器。GetTickCount 只能提供毫秒级的定时器,需要更高精度的定时器需要 实现OEMQueryPerformanceCounter 和OEMQueryPerformanceFrequency。
·配置注册表。这部分与硬件平台的关系已经不大了。