winCE的体系结构和功能

来源:互联网 发布:淘宝代发货平台哪个好 编辑:程序博客网 时间:2024/04/28 07:07

wince的层次体系结构

应用程序层

操作系统层

OEM层

硬件层

应用层:

包括Internet客户端服务,第三方应用程序,winCE应用程序,用户界面

操作系统层:

包括应用和服务、CoreDLL、对象存储、对媒体技术、GWES、设备管理器、网络、内核

OEM层:

包括OEM抽象层、驱动程序、BootLoader、配置文件。

具体如下图:


下面详细介绍更个层:

1)硬件层:

嵌入式硬件通常具有如下特点:

1、处理器体系结构不统一

处理器从8到128位不等,处理能力也从几KHZ到几MHZ甚至几GHZ各异,更重要的时指令集以及结构不一样。我们的手机大多是ARM体系结构的,网络设备上用的比较多的时Power PC;MIPS和SH等多种不同的CPU也在嵌入式领域占有一席之地。

2、硬件资源通常受限

在嵌入式系统中,不仅cpu计算能力有限,内存RAM也非常小,很多没有输出设备,或者是简单的LED,还有一些使用干电池。值得一说的是,因为嵌入式硬件是以“够用”为前提的,所以不是所有的嵌入式设备资源稀缺。有些娱乐设备(索尼公司PS3)为了增强图形处理能力,使用了128位CPU,一些航天设备也远远超过了PC机。

3、外部设备种类繁多

除了鼠标键盘打印机外,无法满足嵌入式的要求,有些车载嵌入式系统,要传感器来获得参数。

4、实时性和可靠性的要求

在有些嵌入式系统中实时性和可靠性要求很高,否则会造成重大的灾难性损失。

2)OEM层:

OEM层是逻辑上位于硬件和操作系统之间的一层硬件相关代码。他的主要作用是对具体的硬件进行抽象,抽象出统一的接口,然后winCE内核可以使用这些接口与硬件进行通信。OEM层包括OEM抽象层、引导程序、配置文件和驱动程序4各模块。
OEM抽象层(OEM Abstraction Layer,OAL)是整个OEM层的主体。它包含了高度硬件相关的代码。OAL主要负责winCE内核与硬件通信。当引导程序引导操作系统结束后,由OAL初始化硬件平台,包括中断服务例程、实时时钟、计时器、内和调试等。OAL的代码在物理上是内核的一部分,最终经过编译连接会成为内核的一部分。

引导程序:

BootLoader是在硬件开发板上执行的一段代码,主要功能是初始化硬件,加载操作系统映像到内存,然后跳转到操作系统代码去执行。BootLoader可以通过串口、USB、以太网获得操作系统映像。如常见的以太网(eboot)。

配置文件:

这些配置文件一般是与操作系统映像和源代码有关。如如何编译,如何配置最终的操作系统映像等。

设备驱动程序:

设备驱动的种类很多,如电池、显卡、声卡和USB等驱动。

BSP:

和OEM层相对应的一个概念就是bsp。bsp是介于主板硬件和操作系统之间的一层,也可以说是操作系统的一部分。实际上只有讨论体系结构时候我们才说OEM层,OEM和bsp是对等的。不同的操作系统对bsp有不同的定义。在pc机上几乎没有谈到bsp,因为pc机都是采用统一的x86体系架构,这样一定操作系统的bsp就是单一确定的,所以就没什么意义了。有人将bsp和pc机主板上的BIOS相提并论,其实差别很大。BIOS主要是负责在电脑开启时自检、出事画系统设备及装载操作系统代码等,它是固化的,没法改变的。bsp是和操作系统绑定在一起的,开始部分BIOS工作类似,但是大部分不同。bsp可以添加和系统无关的驱动,甚至可以吧上层开发统统放进去,而BIOS不行。

3)操作系统层

操作系统层实现了winCE作为一个操作系统的主要功能。wince的进程管理、线程管理、调度、物理内存、虚拟内存、文件系统以及设备管理等功能的实现在这一层。操作系统的基本功能放在几个独立的进程(exe)里面实现,大致有如下几个:
1、内核NK.exe
2、图形系统GWES.exe
3、对象存储FILESYS.exe
4、设备管理系统DEICE.exe
5、服务SERVICE.exe
其中1和3是必不可少的。

系统调用与CoreDII.dll:

CoreDLL.DLL不是一个单独的进程,它是一个会被所有用户进程都加载的动态链接库。所有的应用程序不能直接与操作系统或硬件打交道,如果应用程序希望访问winCE提供的服务,那么只能通过CoreDLL.DLL进行。下面说一下系统调用的详细过程。
a.当进行系统调用时,它直接调用的时CoreDLL.DLL中的一个包装函数,此包装函数为真正系统调用准备所需要的参数。CoreDLL.DLL会被winCE的所有进程加载,因此这一步其实只是进程内部的函数调用。
b.CoreDLL.DLL会发起一个异常,也叫软件中断。总之,异常把执行权重重新有应用程序还给操作系统。
c.操作系统内核捕捉所有异常,当操作系统获得此异常时,也就重新获得CPU。在WINCE上,NK.exe会处理这个软件中断,这样系统调用的应用程序进程就挂起来了,执行转入了NK.exe。
d.接下来NK.exe根据系统调用的不同,找到具体实现该系统调用的进程,此进程可能是NK.exe也可能不是,如果不是在跳转。
e.实现系统调用的进程会得到执行的机会,然后返回。
f.当系统调用的进程执行结束返回的时候,整个系统调用也就结束了,应用程序可以从对CoreDLL.DLL的调用返回,然后继续执行。
值得一提的时CoreDLL.DLL有些函数不是系统调用的包装函数,如字符串处理,如果不是,就不用发生自陷和进程执行跳转。

如:charlowerbuff()函数就是在CoreDLL.DLL中实现,不用中断;createProcess()调用CoreDLL.DLL,然后自陷进入NK.exe,而NK.exe中可以实现createProcess(),所以无需切换到其他进程;CreateWindow(),调用CoreDLL.DLL,然后自陷进入NK.exe,而NK.exe中没有相关函数,所以要切换到GWES.exe图形界面线程中进行执行,执行后返回。
图:

1、NK.exe
实现了进程创建加载、线程调度、中断处理和内存管理等核心功能。
2、GWES.exe
负责图形界面的相关部分,用户的输入(键盘、鼠标、触摸屏)和现实都是由它来管理的。
3、FILESYS.exe
负责对象存储进程,包括文件系统、数据库系统、系统注册表三部分。
4、DEVICE.exe
负责加载卸载和管理所有不被GWES.exe管理的驱动程序。同时也向系统提供所有有关驱动的API的实现。
5、SERVICE.exe
系统服务进程。如FTP、HTTP等

4)应用程序层

目前一个比较普遍的误解就是应用含金量低,底层比较有技术含量,其实衡量一个系统的价值,很重要的标准就是看运行在其上的应用程序如何。没有应用程序的支持,功能在强大、设计在精良的操作系统也只能是玩具而已。

A.进程

进程是程序的一次动态执行实例。进程和程序有很多区别:
1、进程是动态的概念,而程序是静态的概念
2、进程有创建、执行以及结束完整的生命周期,而程序只是一个文件
3、一个程序可以对应多个进程,而一个进程只能对应一个程序。如:打开多个IE浏览器网页,内存中会有多个浏览器的进程,但是每个进程对应的只有iexplore.exe
在WINCE中,进程本身不参加系统调度,也没有优先级和上下文,真正参加系统调度的时线程,进程只是线程的容器,每个进程都会有一个主线程。

由于winCE只支持32个进程同时运行,每个进程有32MB的虚拟地址空间,也被称为一个slot。在系统启动时,filesys.exe gwex.exe device.exe 已经占据了多个slot,用户可以用的只有不到30个。所以能多线程就不要多进程。

此外,wince不支持环境变量和当前目录。如下面的代码是不正确的。
_wfopen(L"%windows\\myfie.txt",L"w");
_wfopen(L"myfie.txt",L"w");

一种解决办法就是使用GetModule()函数得到当前执行文件所在的目录,然后再吧要打开的文件拼接到路径中得到完整的路径,参考代码如下:


DWORDdwLen;


    TCHARszPath[MAX_PATH];

 

    dwLen= GetModuleFileName(NULL, szPath, MAX_PATH);//获取当前模块目录

    if (!dwLen)

    {

       return 0;

    }

 

    while (szPath[--dwLen] != _T('\\'))

    {

       szPath[dwLen] = _T('\0');

    }       

    wcscat(szPath, _T("myfie.txt"));//

线程


一个进程拥有的线程理论上是没有限制的,只与当前可用的内存有关,也就是说只要内存够用,就可以创建线程。进程中的线程共享进程所占有的资源,包括地址空间和代开的文件等内核对象。线程出了占有内存外,还占有其他资源,如处理器的寄存器和栈,每个线程都有自己独立的栈,这些资源构成了线程的上下文。

在核心态,线程可以访问操作系统所有的资源。一般来说,操作系统线程和中断服务例程运行在核心态,应用程序和设备驱动程序的中断服务例程运行在用户态。wince运行所有的进程运行在核心态,虽然不稳定,但是可以提高效率。
创建一个线程:
HANDLE CreateThread(  LPSECURITY_ATTRIBUTES lpThreadAttributes, // 不支持,NULL  DWORD dwStackSize, // 通常默认值  LPTHREAD_START_ROUTINE lpStartAddress, // 线程函数地址(很重要,基本上也就是线程要做的事情,可以是下面的ThreadProc,做的事情就在那个线程函数中实现了)  LPVOID lpParameter, //线程参数(线程要做事情,总得给它传点东西,否则不知道如何干)  DWORD dwCreationFlags, // 线程创建属性  LPDWORD lpThreadId // 线程ID(线程的名字了)  );
线程函数定义:
DWORD WINAPI ThreadProc(
LPVOID lpParamerter//参数指针
);


调度

wince是一个抢占式多任务操作系统。调度程序使用基于优先级的时间片算法对线程进行调度。线程优先级多达256个,0最高,255最低。通常应用程序只须使用248-255的优先级,比较高的优先级供驱动程序和内核使用。

wince的优先级映射

优先级组件优先级组件0-19高于驱动程序的实时145ps2键盘20图形垂直回描148ircomm99电源管理唤醒线程150tapi100-108
usb 串口 ohci uhci

248电源管理109-129红外 ndis 触摸屏249鼠标 pnp power wavedev130内核无关传输层250wavapi131VMini251正常132cxport252-255应用程序

同步(看些例子很容易懂)

1、Mutex
2、Semaphore
3、Event
4、Critical Section
5、互锁函数

进程间通信

wince提供了很多进程间通信的方式,在这里主要说一下文件映射和点对点消息队列。
1、剪贴板:可使用剪切板函数在不同的进程间复制数据。但是一般只适合图形界面的程序,而且通常剪贴板都是由用户操作完成的。
2、com/dcom 通过com组件的代理或存根方式进行进程间数据的交换,但是只能在调用接口函数时传送数据;通过dcom可以在不同主机间传送数据。
3、网络套接字:通过计算机网络,可在相同主机或不同主机间交换数据。
4、WM_COPYDATA消息:通过向进程发这个消息,将数据放在参数中给其他进程传递数据。只适合窗口消息队列的进程。

文件映射:

文件映射又叫内存映射文件。通过内存映射文件可在进程的共享虚拟地址空间内保留一个地址空间的区域,同时将文件所在的物理内存映射到次区域。这样只需要对虚拟内存做读写操作,剩下的就有操作系统做了。wince中内存映射文件会被映射到4gb的虚拟地址空间0x42000000-0x7fffffff的进程区域中,因此实现了多个进程之间的通信。

点对点消息队列:

是常用的系统模块之间进行通信的方式。它很好地附和了操作系统原理中生产者-消费者的模型。消息队列通常是一个先进先出的队列结构,当一个进程吧消息写入队列,需要此消息的其他进程,就可从队列中取得消息,从而达到进程间通信的目的。
wince下的消息队列实现中,有以下特色:
1、消息可以为任何类型,事实上消息只是一个任意大小的内存缓冲区。这非常有利于在不同进程之间进行数据交换。
2、消息队列还可以用来进行同步。
3、消息是没有优先级的,对于同一个队列,所有的消息都严格按照先进先出的方式进出
4、wince中的消息队列是基于点对点操作,它不能用来进行广播

内存管理

wince采用层次化的结构内存管理。从下到上依次分别是物理内存、虚拟内存、逻辑内存和c或c++语言运行库。内存管理的每一层都会向外提供一些编程接口函数,这些编程接口可被上一层使用,也可直接被应用程序使用。

物理内存:

wince中RAM、ROM和Flash Memory都被看做物理内存,而不仅仅是传统意义上的,只有RAM被认为是物理内存。
RAM 关机后,可以用电池保存上次的一些状态,如果开机,可以恢复上次的页面。
ROM可以断电永久存储,和硬盘一样。
ROM的替代品flash memory(闪存)。比ROM最大的优点就是可擦写。flashmemroy可以分为and、nand、nor、dinor等。其中nand和nor是目前主流类型。nor的缺点是容量小。nand优点是容量大,但是速度慢。

虚拟内存:

wince是32位的操作系统,也有4GB的虚拟寻址能力,但是与winXP的每个进程独享4GB虚拟地址空间不同,wince是共享4GB的空间。
wince系统支持两种页的大小:1KB和4KB。wince中虚拟内存的申请分为保留和提交两个过程。虚拟地址空间的保留是以64KB为边界的。也就是说,任何一次虚拟内存申请都会返回一个64KB整数倍的地址。但是把虚拟内存提交到物理内存是以页为粒度的。
管理虚拟内存的硬件是内存管理单元MMU。MMU负责把虚拟地址映射到物理地址,并提供一定的保护。
wince将4GB的虚拟地址空间分为若干个slot,每个32MB,slot编号从0-63.slot0是用于映射当前处理器上执行的进程;slot1有XIP(本地执行)的dll代码使用。slot2-32是wince每个进程的32MB的虚拟地址空间,其中slot2被filesys.exe占有。也就是理论上wince可以有30几个进程,但是用户可以用的只有不到30个。
slot33-63对应的虚拟地址空间0x42000000-0x7fffffff。这块是有所有进程共享的。slot63是用来保存dll资源的。
从0x80000000开始时wince内核的虚拟地址空间。虚拟地址0x80000000-0x9fffffff一段用来静态映射所有物理地址。wince会把物理内存1:1地映射到这段虚拟地址上。这段地址一共512MB,这也是wince支持的物理地址的最大值是512MB的原因。

逻辑内存:

逻辑内存分为堆和栈两种。对是进程中一块连续的虚拟地址空间,应用程序可以在堆上动态地进行内存申请和释放。申请堆是以字节为单位,与页的大小无关,所以每次可以申请4字节或者8字节。
wince为每个进程分配了60kb的栈,并把栈顶2KB用来判断是否栈满,因此每个线程用户可用58KB。


c或c++语言运行库:

malloc/free new/delete
localAlloc()等

存储管理和文件系统

对象存储:

是一个被filesys.exe控制的内存堆,包括:
RAM文件系统
注册表
ce数据库

文件系统:

RAM文件系统:直接挂在根目录下
ROM文件系统:\windows目录下。windows目录中的内容一般就是romimage.exe最终生成的windowsCE运行时镜像的内容,这也就意味着windows目录里面的文件通常都是只读的,用户不能修改和删除。
可安装文件系统:

注册表:

用来保存应用程序、驱动程序和用户设定的一些配置信息。

存储管理器:

主要功能是管理所有的外存设备。从逻辑上讲,它包含设备驱动管理器、分区管理器、和文件系统驱动管理器。
下面以读取磁盘上的一个文件为例,看看wince的存储管理器是如何对存储设备进行管理的。
1、应用程序readfile请求操作系统读操作。coredll中断并被nk截获,然后到filesys执行。
2、filesys会通过对象存储来解析路径,查找此文件的位置,然后发现文件在外存上。
3、filesys通过文件系统驱动程序在外存上查找此文件,如果这个文件系统包含多个分区,还要调用分区驱动程序在分区上查找文件,如果找到,则进行读写。
4、真正的读写是在块设备驱动程序进行的。


用户界面与图形系统

gwes的3个关键的模块:图形、窗口、事件

原创粉丝点击