您当前的位置:五五电子网电子知识单片机-工控设备嵌入式系统-技术Windows CE OAL层的结构与开发 正文
Windows CE OAL层的结构与开发

Windows CE OAL层的结构与开发

点击数:7390 次   录入时间:03-04 11:40:08   整理:http://www.55dianzi.com   嵌入式系统-技术

       引 言    

       Windows CE 是微软针对嵌入式领域推出的一款全新的 操作系统 。之所以说它是一款全新的操作系统,是因为尽管Windows CE的UI非常接近其它的桌面版Windows操作系统,但是它的内核完全是重新写的,并不是任何一款桌面版Windows的精简版本。 Windows CE是一种支持多种CPU架构的操作系统,这其中包括ARM、x86、MIPS和SHx,极大地减轻了0EM开发过程中移植操作系统的工作量。   

       操作系统移植包含两个层面上的工作:一个层面是CPU级的,另一个层面是板级的。CPU级的移植通常由微软或芯片制造商来完成;板级移植则是由OEM来完成的。0AL正是0EM完成这一系统移植的工作核心!       

1 OAL    

       OAL的全称是OEM Adaption Layer,即原始设备制造商适配层。从逻辑结构上看,它位于操作系统的内核与硬件之间,是连接系统与硬件的枢纽;从功能上看,OAL颇似桌面机上的BIOS,具有初始化设备、引导操作系统以及抽象硬件功能等作用。与B10S不同的是,0AL隶属于操作系统,是操作系统的一部分。从存在方式上,讲OAL是一组函数的集合体,这些函数体现出0AL的功能,如图1所示。

<a target=Windows CE 系统结构" hspace="0" src="/55dz_dzwz/UploadPic/2015-11/2015112712156567.jpg" width="393" border="0" onload="return imgzoom(this,600);" onclick="javascript:window.open(this.src);" style="cursor:pointer;"/>


       2 最小化的OAL
 

       OAL层的首要任务是加载内核。OAL层中为内核的启动作种种铺垫的函数的集合构成最小OAL层。我们可以由此深入0AL层,如图2所示。 

OS启动顺序

首先来看一下OS的启动顺序。    

       ①CPU执行引导向量,跳转到硬件初始化代码,即Startup函数;    

       ②在start up函数完成最小硬件环境初始化后跳转到KernelStart函数(当CPU为x86架构时为Kernel Initial-ize函数),来对内核进行初始化;    

       ③Kernelstart函数调用OEMInitDebugSerial完成对调试串口的初始化,调用0EMInit函数来完成硬件初始化工作以及设置时钟、中断,调用OEMGetExtensionDRAM函数来判断是否还有另外一块DRAM。    

       至此,内核加载完毕。由此可见,OS启动的重中之重是Startup函数的正确加载。   

       2.1 Startup 

       Startup阶段的特点是Kernel还没有加载起来,调试工作比较困难。StartuP函数的两大核心任务分别是把CPU初始化到一已知状态和调用内核初始化函数来初始化内核。以下是Startup函数中通常包含的内容:①把处理器置为监控模式;②禁止CPU的IRQ和FIQ输入:③禁止内存管理单元MMU和指令、数据Cache; ④刷新指令和数据Cache、TLB、清空写buffr; ⑤确定启动的原因一hard reset,wake from sleep, GPIO reset,Watchdog reset,eboot handoff; ⑥根据目标板需要配置GPIO,比如连接LED的GPIO; ⑦配置内存管理器,设置刷新频率,使能时钟; ⑧配置中断控制器;⑨初始化实时时钟(RTC)为0,使能实时时钟:⑩设置电源管理寄存器;⑾打开所有板级时钟和片内外部时钟;⑿取得OEMAddressTable的物理基地址并把它存在r0中;⒀跳转到KernelStart。    

www.55dianzi.com
       Bootloader和 OAL 中均包含Startup函数。它的功能大致相同,都是要初始化最小硬件环境。Bootloader是在为自己的执行准备硬件环境,OAL则是为kernel的执行准备硬件环境。由于这两种硬件环境要求基本相同,所以它们的代码也有很大部分可以相互借鉴。但应该明白,Bootloader与OAL在物理上是独立的,它们并不是同一段代码。而且,如果可以确定这一硬件部分Bootloader已经初始化过,则在OAL中不必重复。当然,前提是每次加载都要经过Bootloader这一环节。最典型的例子就是x86 OAL中的Startup,见例程:
x86 OAL中的Startup

       2.2 Kernel Start

      
Kernel Start主要完成内核的最小初始化并且通过调用OEMInit函数来完成板级硬件初 始化。以下是ARM内核初始化过程:① 初始化一级页表;②使能MMU和cache;③为每种工作模式使能栈(stack);     ④重新定位内核;⑤执行串口调试函数;⑥调用OEMInit;⑦初始化内存;⑧执行其它初始化。    

       KernelStart中用到的三个函数OEMInit ()、OEMInitDebugSerial()和OEMGetExtensionDRAM()中,OEMInit()硬件相关性较大,也最重要。(1)OEMlnit() 0EMInit的最小任务是初始化其它硬件和注册系统时钟。通常OEMInit应该完成以下工作。①通过设置以下值来设置中断映射表一SYSINTR→IRQ和IRQ→SYSINTR。②在中断映射表中设置静态中断映射。③设置KITL,但在最小化的OAL层中通常不包括KITL。④用Init CLOCk配置系统定时器、实时时钟、时钟。⑤确定系统时钟的中断源。⑥初始化内核时间粒度为1ms。⑦配置中断控制器或可编程中断控制器(PICS)。⑧提供调试用LED指示灯。⑨置pWriteDedugLED=OEMWriteDedugLED。⑩调用HookInterrupt函数来注册中断服务例程ISRs,以下示例说明如何处理TIMERISR硬件中断5的中断服务例程:
处理TIMERISR硬件中断5的中断服务例程

       (2)串口调试函数

      
有限的调试手段是0S移植人员经常遇到的难题。串口调试函数虽然不像以太网口调试函数那样功能强大,但仍然要比LED指示灯或数码管要直观得多,是调试OAL层代码不可或缺的一组工具。这个函数组由四个函数组成,分别是0 E M I n i t D e b u g S e r i a l()、OEMReadDebugByte()、OEMWriteDebugByte()和OEMWriteDebugString()。   

       ◇OEMInitDebugSerial()用于配置串口;   

       ◇OEMReadDebugByte0和OEMWriteDebugByte()用于向串口读写一个字节;   

       ◇OEMWriteDebugString()用于向串口写一个调试用字符串。    

       KernelStart中调用的是OEMInitDebugSerial(),完成串口初始化,为串口调试工作作好准备。   



www.55dianzi.com        (3)OEMGetExtensionDRAM()

      
在最简最小化 OAL 层函数中,OEMGetExtensionDRAM()并不是一个必需的函数。OEMGetExtensionDRAM()的主要功能是查询是否存在另外一片DRAM.如果目标板上只有一片DRAM,则该函数返回FALSE。但在KernelStart通常都包含此函数。至此,最小的OAL层已经完毕,kernel的最基本的功能可以正常使用。骨架搭起,第一阶段的任务告一段落,但是很多非常重要的功能还不完整,还不能做到物尽其用。于是需要进一步加强OAL层的功能。这种做法也是OAL层开发通常使用的方法。先完成基本功能,在基本功能确保正确无误后,逐渐加入其它功能。循序渐进,即使出错也很容易找到出错的地方,便于排查。   

[1] [2] [3]  下一页


本文关键字:开发  Windows  嵌入式系统-技术单片机-工控设备 - 嵌入式系统-技术