但是WindowsCENET是一个运行时的系统MicrosoftWin32C课件.ppt
1,第十四章 Windows CE.NET系统开发,14.1 Windows CE.NET开发 14.2 BSP开发概述 14.3 驱动程序开发 14.4 BootLoader开发 14.5 OAL开发,2,14.1 Windows CE.NET开发,3,Windows CE.NET开发,根据开发所处的层次以及工具的不同:Windows CE.NET应用开发Windows CE.NET系统开发,OEM 硬件,嵌入式外壳,应用程序,内核,红外,GWES,设备管理,文件管理,TCP/IPIPv6,OALBootloader,驱动,设备驱动,文件驱动,可以定制,基本不可改动,ISV,OEM,4,14.1.1 Windows CE.NET系统开发,Windows CE.NET操作系统定制Windows CE.NET驱动程序开发Windows CE.NET操作系统移植(BSP开发),5,(1)Windows CE.NET操作系统定制,操作系统定制的一般流程:得到并安装BSP(CEC文件)PB自带从OEM硬件厂商获得自主开发定制操作系统生成操作系统镜像:NK.bin文件下载调试仿真CEPC下载到开发板调试,6,(2)Windows CE.NET驱动程序开发,普通操作系统的驱动模型,两种模式:静态链接:驱动代码编译成.LIB文件并与操作系统内核链接,形成一个整体,随操作系统一起启动加载。动态链接:操作系统在启动后对硬件驱动延迟加载,但是依然加载到操作系统的内核空间中。Windows CE.NET驱动模型比较特殊在Windows CE下,所有驱动都以用户态下的DLL文件形式存在。,7,(3)Windows CE.NET操作系统移植,BSP(Board Support Package):是介于主板硬件和操作系统之间的一层软件系统。开发BSP的内容主要包括:BootLoader开发OAL开发,8,2.Windows CE.NET应用开发,Windows CE.NET为应用程序开发人员提供了三种选择,分别是:Win32应用程序编程接口(Win32 API)微软基础类(Microsoft Foundation Class,MFC)和活动模板库(Active Template Library,ATL).NET Framework精简版(.NET Compact Framework,.NET CF),9,Windows CE.NET应用开发的选择,10,三种API的特点比较,11,Device DevelopmentBuilds and Brings Up Device,Debug Device,Build DeviceImage,Component Catalog incl.NET CF,ApplicationDevelopmentBuilds Rich Applications,Smart Device Programmability,Visual Studio.NETVB/C#,eMbedded Visual C+4.0C/C+MFC/ATL,Device UnderDevelopment,Development CycleFrom Platform to Applications,Download Device Specific Windows CE OS and Applications,via KITL,via KITL,Export SDK with Device Specific Win32 APIs or use Standard SDK,Device Emulation,Platform Builder,12,14.1.2 Windows CE.NET开发过程,1.迭代开发过程 基于Windows CE设备的开发过程是由不断修改、增加配置特征、构建、下载、调试等步骤所组成的一个迭代开发过程,13,典型的平台开发周期,在一个典型的平台开发周期当中,为了构建一个基于Windows CE.NET的平台,应该包含以下几个步骤:开发人员必须首先选择一个适合于目标设备的Windows CE 的配置,即平台的定制(Customize Platform)。然后,基于上述配置创建一个操作系统镜像,并且开发一个BootLoader,用于将镜像下载到目标设备(如CEPC,或者一个真正的目标板)。在目标平台上,开发人员可以修改和调试操作系统(Debug Platform),使之更为适合于目标设备。一旦完成操作系统配置,开发者就可以利用P1atform Builder提供的导出SDK工具。,14,2.串行开发和并行开发,一个完整的基于Windows CE的设备开发过程包括硬件开发调试(Port H/W)、Windows CE操作系统定制(Customize OS)和应用程序开发调试(Develop Apps)三个阶段。由于后一阶段的工作必须依赖于前一阶段工作的完成,所以传统的开发设计过程是逐阶段的串行过程,15,并行开发,为了能够缩短基于Windows CE设备的开发周期,充分调动开发人员,必须要能够减小或者消除上述三个阶段的相关性,使各个阶段的工作可以独立进行。,16,并行开发过程,在硬件开发者开发调试定制的设备硬件的同时,操作系统开发者就可以先在模拟器或任意SDB上开始操作系统特征的定制,并按照设备定义为应用程序开发者导出SDK。而应用程序开发者在硬件开发者开发硬件、操作系统开发者定制操作系统的同时,也可以先在模拟器上从事应用程序软件的开发调试,在得到操作系统开发者导出的SDK时,也可以在SDB上进行应用程序的开发调试。在所有三个阶段的工作都分别完成后,定制的操作系统和开发的应用程序最终再移植到定制的设备硬件上进行综合测试和调试。,17,3.工程开发进度图,一个典型的Windows CE工程的开发进度图,图中展示了各个阶段要完成的主要开发任务及其时间线,主要包括四个任务:OS移植Porting、OS定制、应用开发Apps以及测试QA。,18,14.2 BSP开发概述,19,14.2.1 BSP概述,Windows CE.NET的可移植性是通过BSP来实现的。Windows CE采用了分层的设计方法,将系统中与硬件直接相关的一层软件独立出来,称之为板级支持包(Board Support Package,即简称BSP)。BSP位于硬件平台与操作系统之间,属于操作系统的一部分。其主要功能在于配置系统硬件使其工作于正常的状态,完成硬件与软件之间的信息交互,为OS及上层应用程序提供一个与硬件无关的软件平台(包括操作系统的驱动及硬件驱动)。BSP能够支持众多的硬件平台。,20,BSP功能,其具体功能包括:硬件初始化,主要是CPU的初始化,为整个软件系统提供底层硬件支持;为操作系统提供设备驱动程序和系统中断服务程序;定制操作系统的功能,为软件系统提供一个实时多任务的运行环境;初始化操作系统,为操作系统的正常运行做好准备。,21,2.BSP和PC机主板上的BIOS区别,BIOS主要是负责在电脑开启时检测、初始化系统设备(设置栈指针,中断分配,内存初始化.)、装入操作系统并调度操作系统向硬件发出的指令,它的Firmware代码是在芯片生产过程中固化的,一般来说用户是无法修改。在OS正常运行后,BIOS的作用基本上也就完成了。PC机BIOS的作用更像嵌入式系统中的BootLoader(最底层的引导软件,初始化主板的基本设置,为接收外部程序做硬件上的准备)。与BootLoader不同的是,BIOS在装载OS系统的同时,还传递一些参数设置(中断端口定义等),而BootLoader只是简单的装载系统。BSP是和操作系统绑在一起运行在主板上的,尽管BSP的开始部分和BIOS所做的工作类似,可是大部分和BIOS不同,作用也完全不同。此外BSP还包含和系统有关的基本驱动(串口,网口.),此外程序员还可以编程修改BSP,在BSP中任意添加一些和系统无关的驱动或程序,甚至可以把上层开发的统统放到BSP中。而BIOS程序是用户不能更改,编译编程的,只能对参数进行修改设置。更不会包含一些基本的硬件驱动。,22,14.2.2 BSP基本结构,BSP主要由4部分构成:OEM抽象层、引导程序、设备驱动程序和配置文件,23,1.BootLoader,引导程序(BootLoader)是在硬件开发板上执行的一段代码。它的主要功能是初始化硬件,加载操作系统镜像(OS Image)到内存,然后跳转到操作系统代码去执行。,24,2.OAL,OEM抽象层简称OAL(OEM Abstraction Layer)。它是操作系统内核抽象出来的与硬件交互的接口,它的实现代码通常是与硬件高度相关的。OAL层主要负责Windows CE内核与硬件的通信。当引导程序引导操作系统结束后,由OAL层负责硬件平台初始化、中断服务例程ISR、实时时钟RTC、计时器Timer、内核调试、开关中断和内核性能监测等工作。,25,3.Device Driver,设备驱动程序(Device Driver)是BSP的一个重点。对于某个特定的BSP来说,当中应该包含在这块开发板上的所有的设备驱动程序,这样才可以保证Windows CE操作系统能够发挥开发板的最大效能,26,4.Configuration File,配置文件(Configuration File)是一些包含配置信息的文本文件。这些配置信息通常与系统镜像或源代码有关。BSP中的配置文件包括:镜像配置文件BIB、DB、REG、DAT,源代码配置文件Sources和DIRS文件,以及将BSP与Platform Builder集成的CEC文件。,27,14.2.3 BSP开发,BSP开发思想 一般来说,BSP的开发并不是要求开发者从零开始对常用类型的CPU和外围设备,Platform Builder都提供了BootLoader、OAL、Device Driver的源代码,只要使用Platform Builder对已有的BSP进行剪裁和稍做修改,再加上微软提供的内核,就能驱动大多数的硬件设备。而且Platform Builder还提供了丰富的标准应用程序和服务程序,在开发好OEM层之后,再加上这些应用和服务,就能让用户的硬件平台工作起来。,28,BSP开发过程,BSP的开发包括三个方面:BootLoader开发、OAL开发和驱动程序开发。一个BSP可以被定义为一个.cec文件,这个文件定义了可以添加到定制硬件平台的一组默认特征。BSP开发的步骤如下:(1)硬件准备(2)克隆参考BSP(3)开发BootLoader(4)开发OAL(5)开发驱动程序(6)发布BSP,29,14.3 驱动程序开发,30,14.3.1编写Windows CE.NET驱动的要素,要了解驱动程序所针对的硬件阅读硬件规范和白皮书要了解目标操作系统下驱动的工作机制加载和卸载初始化访问外设I/O处理中断处理DMA了解驱动程序模型对于某一类外设,操作系统会提供特定的驱动模型,31,驱动开发工具,Windows CE 的驱动程序可以使用Platform Builder或者Visual Studio来进行开发。平台开发人员通常使用Platform Builder开发设备驱动程序,驱动程序作为BSP(Board SupportPackage)的一部分进行整体编译开发;独立硬件供应商(Independent Hardware Vendor,IHV)使用Platform Builder开发驱动程序,对于部分驱动也会使用Visual Studio开发;应用程序开发人员更多地使用Visual Studio开发驱动,某些情况下会使用PB。,32,14.3.2 Windows CE.NET的驱动模型,驱动程序将操作系统和设备连接起来,使得操作系统能够识别设备并为应用程序提供设备服务。驱动程序模型决定了驱动程序的软件接口,因此,不同的驱动模型只能通过它们支持的软件接口来区别,而不是它们所适用的设备。按加载方式和接口类型分类,基于Windows CE的驱动程序主要分为两类,33,(1)本机驱动程序(Built-In Drivers),本机驱动程序又被称为native device drivers,它是由微软开发并由系统直接支持,适合于集成到CE 平台的设备,典型的包括电源驱动、显示驱动、鼠标键盘驱动、打印机驱动以及LED显示驱动。这些驱动程序通常由GWES(图形窗口及事件子系统)统一管理和加载,成为GWES的一部分,不表现为单个的DLL 使用。,34,(2)流接口驱动程序(Stream Drivers),另外一个名称又称为可安装驱动(Installable Drivers)。它具有较好的可移植性和可扩展性,被设备管理器独立出来管理统筹。流驱动程序是一般类型的设备驱动程序,支持几乎所有可连接在Winows CE平台上的外部设备,所以更常用。,35,流接口驱动程序,流接口驱动程序是以用户模式的DLL文件形式出现,并且通常由设备管理器(Device Manager)动态加载。驱动接口是标准的流式接口,尤其适用于IO操作。它实现了一组流接口函数(CreateFile、ReadFile、WriteFile、IOControl等),这些函数使得应用程序可以通过文件系统访问驱动程序,也就是将设备当作文件来进行操作。典型的流接口驱动程序包括PCMCIA driver(PCMCIA.DLL)、Serial driver(SERIAL.DLL)、ATA/FLASH driver(ATA.DLL)、Ethernet driver(NE2000.DLL,SMSC100FD.DLL)。,36,2.按驱动层次分类,按驱动层次分类,驱动程序可以分为两类,37,(1)层次型驱动程序(Layered Driver),驱动采用分层结构,一般分为两层:上层是模型设备驱动程序MDD(Model Device Driver),与硬件无关,面向上层应用程序,一般由微软建立统一框架;而下层是依赖平台的驱动程序PDD(Platform Dependent Driver),是针对具体硬件平台的操作代码,一般由驱动开发商实现。MDD和PDD之间通过标准的设备驱动服务供应商接口DDSI连接。,38,(2)独立型驱动程序(Monolithic Driver),独立型驱动程序基于单个硬件,直接把硬件设备的功能性通过设备驱动程序接口(DDI)传递给操作系统。独立驱动程序包含了MDD面向上层应用和PDD面向硬件平台两方面的代码,适用于操作不复杂的驱动。这样减少了MDD和PDD传递之间传递信息的开销,实时性更强。,39,3.驱动模型,Windows CE.NET的驱动模型就是基于驱动层次的分类所构建的,大多数 Windows CE 设备驱动程序都由一个平台相关驱动程序(PDD)和一个模型设备驱动程序(MDD)组成。,40,(1)模型设备驱动程序(MDD),微软为链接驱动程序提供了模型设备驱动程序(Model Device Driver,MDD)。对平台和函数来讲模型设备驱动程序是通用的,既是源代码也是库。模型设备驱动程序执行下列任务:链接PDD层并定义它希望调用的函数,通常这些函数叫做设备驱动程序服务器提供接口(DDSI)。把不同的函数集提供给操作系统,通常这些函数叫做设备驱动程序接口(DDI).负责与GWES模块和内核通信,包含一些复杂的操作,例如中断处理等。,41,(2)平台依赖驱动程序(PDD),平台依赖驱动程序(Platform Dependence Driver,PDD)完成真正的硬件访问操作:包含与某款硬件相关的代码对于不同的硬件产品或者标准,有不同的实现只能与某一类MDD协同工作实现MDD所需要的DDSI函数,42,(3)MDD与PDD关系,在编写驱动程序时,通常PB中会自带此类型驱动的MDD代码,所以MDD代码是无需更改,我们只需要修改PDD层的代码。通常,MDD层的代码与PDD层的代码会被编译成独立的静态Lib库,然后进行链接,形成可执行的驱动程序。所以,MDD和PDD的划分只是在源代码逻辑层面,在驱动程序的二进制可执行代码中不会存在MDD和PDD的分层。,43,(4)驱动模型接口,设备驱动程序接口():是在中实现的函数集,模块通过这个接口调用设备驱动程序。设备驱动程序服务器提供接口():是在中实现的函数集并由调用。当操作系统访问硬件时,首先通过使用DDI函数与驱动程序交互,然后在驱动程序内部,MDD再通过DDSI函数与PDD交互,最后由PDD完成真正的硬件访问操作。,44,14.3.3 Windows CE.NET驱动程序的中断机制,与其他计算机结构一样,当设备需要驱动程序的服务时,基于WinCE.NET的平台要使用中断通知操作系统在有些情况下,可以说中断是外部硬件对系统服务的请求,而中断服务程序 I/O地址就是操作系统对硬件服务的响应WinCE.NET把中断处理分为两部分:中断服务例行程序(Interrupt Service Routine,ISR)中断服务线程(Interrupt Service Thread,IST),45,1.ISR,中断服务例程(Interrupt Service Routine,ISR)属于内核模式的服务,其主要功能是响应设备中断请求并确定把哪个中断标识返回给核心中断处理器。一般情况下ISR不会做太多的工作,而是依靠一个特定的中断服务线程(Interrupt Service Thread,IST)完成大量必要的中断处理。当需要更多的处理时,ISR通过返回一个非SYSINTR_NOP的逻辑中断值让内核知道。,46,两种类型的ISR,Windows CE支持两种类型的ISR:静态ISR:只能被静态编译进内核,运行时不能改变。与IST通信是单向的,只能是ISR到IST。静态ISR支持中断嵌套,并使用核心堆栈。可安装ISR:由内核管理程序从DLL中动态加载,双向通信,多个ISR可以和一个中断请求相关联,系统按照加载驱动程序顺序依次调度。,47,2.IST,在Windows CE的中断机制中,由IST具体处理中断的事务性工作。当内核接到ISR传来的中断标识之后,发出一个中断事件,激活一个正等待在该事件的事件队列上的IST,一段时间之后,调度器将调度这个线程工作,处理中断的事务。,48,IST的特点,IST是进行绝大多数中断处理的一个用户模式的线程。IST在大部分时间里是空闲的,当需要它执行一些处理时依靠操作系统去唤醒它,这是通过将一个事件对象与一个中断标识符进行关联来完成的。IST执行的第一个操作是产生一个事件对象并将它与一个逻辑中断关联。当硬件中断发生时,内核触发代表ISR的事件,然后IST使设备完成必要的IO 操作来采集数据或者处理数据。当中断处理完成时,IST应该通知内核再次开启硬件中断。通常IST在正常的优先级之上运行,驱动程序可以通过使用CeSetThreadPriority 函数改变IST的优先级。,49,3.Interrupt Architecture中断机制,OEM Hardware层为硬件和中断控制器的状态;Kernel层是中断服务过程中的内核交互;OAL层描述了主板支持软件包(BSP)的职责;应用层阐述了中断服务所需的应用程序或驱动程序线程交互。,50,中断处理过程,当一个硬件中断发生时,它被发送到内核的异常处理器(Exception Handler),由内核处理这个异常。内核的中断支持处理器(Interrupt Support Handler)调用OAL函数OEMInterupt_Disable与硬件交互。内核调用ISR(中断服务例程)来决定应该怎样处理这个中断。ISR将中断映射并设置相应的核心中断标识。内核触发它的中断支持处理器(Interrupt Support Handler)来触发唤醒IST并完成它的工作。当IST被唤醒后,它做处理中断要做的所有工作。内核在接收到 SYSINTR 值的 InterruptDone 时,调用OEMInterruptDone完成这个中断所有的处理,OAL函数(OAL Routine)通知硬件重新开启这个中断。只有从这时开始,才能接收该设备的其他中断。,51,4.IST中断处理程序的实现,要实现IST必须实现两个过程:首先,IST的中断必须和一个事件相关联;其次,IST必须通过WaitForSingleObject等待中断请求事件。,52,IST具体实现过程如下(在XXX_Init函数中定义),创建一个事件(CreateEvent)创建一个挂起的IST(CreateThread)得到系统的中断号(KernelIoControl)设置IST优先级(CeSetThreadPriority)通知系统注册中断(InterruptInitialize)唤醒IST,IST开始服务(ResumeThread)中断数据被处理完毕后,IST调用(InterruptDone)函数通知内核中断处理结束,内核重新开启和这个线程相关的硬件中断。,53,Interrupt Initialization,/创建事件(Create the Event)gIntEvent=CreateEvent(NULL,/SecurityFALSE,/Manual resetFALSE,/Init as not signaledNULL/No Named Events);/创建挂起的IST(Create a thread that waits for signaling)gThreadInt=CreateThread(NULL,/Security0,/DefaultThreadInt,/Interrupt ThreadNULL,/No ParametersCREATE_SUSPENDED,/Suspended,Kernel,HW,All Higher Enabled,All Except ID,All,OAL,IST,ISR,Set Event,ID,ISR,ISR1,ISRN,IST,54,Interrupt Service Thread,/IST的具体执行 DWORDWINAPIThreadInt(LPVOID lpvParam)/The magic thread waits for the event.while(gRun)/IST等待事件被触发WaitForSingleObject(gIntEvent,INFINITE);/Increment the countergInterruptCount+;/这里可以是IST中断处理具体过程的代码,读者自行添加/中断处理完毕,通知内核重新开启和这个线程相关的硬件中断InterruptDone(gSysIntNum);return 0;,Kernel,HW,All Higher Enabled,All Except ID,All,OAL,IST,ISR,Set Event,ID,ISR,ISR1,ISRN,IST,55,5.Latency,ISR 延迟:定义为从发生中断到 OAL ISR 首次执行之间的时间。导致 ISR延迟的因素包括:中断被关闭的时间;总线指令锁定处理器的时间;内核 ISR 的执行时间加上导向 OAL ISR 的时间。IST 延迟:从中断发生到执行 IST 中的第一行代码之间的时间量。导致 IST 延迟的因素包括:ISR 延迟时间;OAL ISR 执行时间;OS 执行 KCALL(Windows CE 中的内核函数(如计划程序)的时间;调度 IST 的时间。,56,Kernel,Interrupt Architecture,HW,All Higher Enabled,All Except ID,All,OAL,Thread,ISR,Set Event,ID,ISR,ISR1,ISRN,ISR Latency,IST,IST Latency,Ref:http:/,57,14.3.4流接口驱动程序工作原理,Windows CE.NET的驱动程序中,最常见的就是流接口驱动(Stream Interface Driver)。流接口驱动具有较好的可移植性和可扩展性,因而被设备管理器独立出来加以管理。它以DLL动态链接库形式存在的,通过流驱动接口函数和设备管理器进行数据交互,由设备管理器统一加载、管理和卸载。所有的流接口驱动程序都是用同一组接口并调用同一个函数集的,这个函数集称为流接口函数。,58,1.流接口驱动程序的工作结构,流接口驱动程序面向的是各种各样的外设,主要任务是把外设的使用传递给应用程序,这是通过把设备表示为文件系统的一个特殊文件实现的,这一点和UNIX的设备管理很相似。因此,应用程序通过文件系统的API 来调用流接口函数,然后由流接口驱动程序调用本机驱动;或者通过设备管理器与系统内核外围设备通讯交互,最后直接驱动相关硬件执行动作。,59,2.设备管理器,设备管理器可以在设备接口变得可用和不可用时通知用户,而用户或系统本身也可以使设备接口变得可用或不可用。另外,设备管理器通知内核设备接口支持文件操作访问公开流接口的设备。设备管理器也向设备驱动程序发送电源回调通知,并提供电源管理服务。设备管理器虽然不是内核的一部分,但它是与内核、注册表和流接口驱动程序相互影响的单独部分。,60,相关的注册表项,设备管理程序使用存储在HKEY_LOCAL_MACHINEdrivers键中的注册键来管理驱动程序Active 包含由设备管理程序加载的跟踪当前活动的驱动程序BuiltIn 包含由WinCE平台制造商提供的驱动程序,系统启动时加载PCMCIA 包含与PC卡及其流接口驱动程序有关的子键Resource 记录系统中断和I/O使用情况,61,3.设备文件名,在WinCE.NET应用程序通过文件系统里的特殊入口访问外围设备。WinCE.NET操作系统中的文件系统代码包含那些识别特殊文件名并重定向文件I/O操作到适当的流接口驱动程序的代码,62,设备文件名,WinCE.NET的设备文件名前缀:由三个大写的字母组成,WinCE.NET使用这三个字母来识别与特殊流接口驱动程序相对应的特殊设备。文件名前缀存储在称作“Prefix”的注册表键值中索引区分同一驱动程序管理的不同设备缺省:19;可通过“index”的值指明起始索引数,63,设备文件名,在WinCE.NET中,具体的设备名称是由设备文件名前缀和设备文件名索引组成的,索引是紧随文件前缀的那个数字。用来区分由同一个流接口驱动程序管理的所有设备。在驱动程序的注册键里面通过“Index”的值指明起始索引数。如:“COM1:”,”COM2:”,64,4.单访问和多访问,生成一个流接口驱动程序的时候,由于外围设备是以特殊文件形式供应用程序使用的,因此很容易出现多个应用程序同时访问同一个设备的情况。这时要考虑用户驱动程序对它的服务设备是否有多次打开文件处理的功能。在WinCE.NET中一个流接口驱动程序可以通过使用hopenContext参数来实现单访问和多访问。如果是实现单访问,则第一次对XXX_open的调用返回一个合法值,保持该值的合法性,后来的调用都返回空值;若是实现多访问,对于XXX_open的调用每次都返回不同的值。,65,14.3.5流接口驱动程序开发过程,在WinCE 中,设备文件通常是保存在固定的路径Windows 目录下,通过注册表机制来完成特殊的命名惯例。虽然流接口驱动程序具有普遍的特性,但是我们仍旧可以使用不同的方法来实现它们,例如有些内部设备的驱动程序就是使用流接口。尽管流接口程序通常是由设备管理器加载和卸载的,但是有时候应用程序也执行加载和卸载的任务。,66,1.选择代表设备的文件名前缀,首先要选择代表设备的文件名前缀,前缀名以XXX打头,后面跟上入口点名称。例如,假如设备文件名前缀是PWR,那么需要实现的流接口驱动函数就包括PWR_Close,PWR_Init等等。,67,2.实现驱动的各个标准接口函数,每个流接口驱动程序必须实现一组标准的函数,用来完成标准的文件I/O函数和电源管理函数这些函数提供给WinCE.NET操作系统的内核使用,通常叫做流接口驱动程序的DLL接口。,68,流接口驱动程序的入口点函数,函 数 名 称 描 述XXX_Close 驱动程序关闭时候调用XXX_Open 打开一个设备驱动时调用XXX_Deinit 设备管理器或者应用程序卸载驱动时调用XXX_Init 设备管理器初始化设备时调用XXX_IOControl 上层软件进行IO 控制调用XXX_PowerDown 系统挂起前调用XXX_PowerUp 系统重新启动时调用XXX_Read 打开设备时候进行的读操作XXX_Write 打开设备时候进行的写操作XXX_Seek 对设备指针进行操作时调用XXX_Reinit 设备重复打开时调用其中XXX 代表驱动文件名,由驱动类型的3 个大写字母缩写而成,规则由系统约定。,69,3.建立.DEF文件,DEF文件定义了DLL的导出函数列表。如上例,创建*.DEF文件名为PWRBUTTON.DEF。这个文件将被提交给链接器,它包含了入口点函数的名称。,70,4.在注册表中为驱动程序配置表项,最后,开发人员还必须在注册表中为这个驱动程序创建相应的表项,从而使得设备管理器Device.exe能够装载这个驱动。向Windows CE.NET的内核里面添加注册表项的方法有两种:一是直接修改PB下面的reg文件(如StringReg.reg);二是自己写一个注册表文件通过添加组件的方式添加到内核中。,71,14.3.6流接口驱动程序开发实例,我们将通过一个实例来建立一个最简单的流驱动程序。该驱动程序的功能是向缓冲区中读写字符。,72,1、建立模拟器工程,运行Platform Builder,建立一个基于X86 体系的模拟器工程。所创建的驱动程序就可以在仿真器中模拟实现。,73,2、创建驱动程序工程,74,75,选择建立C+Source File,同时添加文件名,存储路径并将文件添加到DLL 工程中。加入“windows.h”,“tchar.h”头文件和动态链接库的入口函数(标准函数)DllEntryPoint(),这样就建立好一个简单的动态链接库的框架,下面将添加相应的处理函数。,76,3、编写驱动程序的代码,编写驱动程序代码。选择一个设备文件名前缀用于表示这个流接口程序的类别。例如:TST分别实现各个入口点函数:(详见创维特wince实践教程P54)(同时参考书上P258类似代码)TST _initTST _DeinitTST _OpenTST _CloseTST _ReadTST _Write,77,4、准备配置文件,需要准备的配置文件包括了:Def 文件、Reg 文件、Cec 文件、Makefile 文件和Sources 文件。这些文件是 DLL 工程编译必须具备的配置文件,它们说明了关于驱动如何链接,编译路径,和系统注册等等重要的工作,在编写新的DLL 时一般都需要进行改动甚至重写。配置文件准备完毕以后,还需要添加驱动程序到定制的内核。添加方法有两种:一是更改BIB文件二是做一个CEC文件添加到PB中。,78,5、编译内核,编译过程和第十三章的编译方法一样特别注意现在是在使用模拟器,所以在编译选项中应该选中“EMULATOR:X86 WIN32”。,79,导入CEC 文件,80,编译内核生成内核镜像文件,编译内核生成内核镜像文件。这一阶段主要是生成一个包含的流接口驱动程序的内核。这里需要一些设置,画面如下:,81,6、加载驱动,在模拟器下面调试驱动程序。首先打开target菜单下的configure remote connection进行相应的设置。然后就可以使用模拟器启动编译的内核了。如左图,82,7.调试驱动程序,调试驱动程序的方法有很多:(1)调试区(2)输出调试信息(3)使用内核调试工具Kernel Debugger(4)硬件辅助调试方法(5)使用Visual Studio调试,83,8.驱动程序的测试、集成和发布,(1)测试开发者可以写一个简单的应用程序来测试驱动程序的正确性,模拟各种可能发生的硬件输入状态来测试驱动程序的正确性,也可以利用Windows CE自带的测试工具CETK来测试驱动程序的性能和完备性。(2)集成驱动测试完毕以后,需要在已有的BSP中集成新的驱动程序。(3)发布最后,对于驱动程序的发布,可以利用CAB Wizard生成.cab驱动包,直接提供驱动程序文件夹以及相关注册表项和修改说明。,84,14.4 BootLoader开发,85,14.4.1 BootLoader 概述,BootLoader 就是在操作系统内核运行之前运行的一段小程序,通常存储在目标设备的Flash或者ROM当中,主要用来管理目标平台的启动过程。通常来讲,BootLoader 是严重依赖于硬件而实现的,每种不同的 CPU 体系结构都有不同的 Boot Loader。所以针对特定的处理器,必须专门来定制BootLoader,以实现不同的功能需求。这也就是BootLoader开发的必要所在。,86,1.BootLoader的工作模式,BootLoader的工作模式分为以下两种:(1)启动加载(Boot loading)模式(2)下载(Downloading)模式,87,2.BootLoader的功能,BootLoaer的具体功能包括:完成基本的硬件初始化;进入supervisor模式,清空指令和数据cache;设置系统时钟,PLL;配置SDRAM控制器;设置中断控制器;重新定位BootLoader代码;打开MMU和Cache;下载/加载Wince内核(串口,Ethernet,USB,CFcard,Hard disk);烧写Flash(NOR,NAND,DOC);参数设置(IP,DHCP,启动参数等);调试功能(内存,寄存器打印)。,88,14.4.2 Eboot,Windows CE 系统和其他RTOS不同,它具有两级BootLoader 来引导内核镜像。Nboot(NandFlash BootLoader)是Windows CE的第一级BootLoader,位于Nand Flash的Block0。主要负责初始化Flash,读取TOC等等工作,最后将Eboot内容拷贝到RAM 中,把CPU执行权交给Eboot接管。Nboot可以使用ADS开发,也可以使用其他工具来开发。,89,1.Eboot概述,Eboot(Ethernet BootLoader)是一种高级BootLoader,可以理解为一个伪的Kernel Image,位于从Nand Flash 的Block2 开始部分空间。它主要负责各个设备的初始化,内存地址映射,文件系统,网络系统驱动和加载内核镜像的相关准备工作,是一种比较复杂的BootLoader。,90,2.Eboot启动流程,在系统初始化开始的时候,Eboot首先判断是否启动Windows CE内核镜像,要么等待用户命令启动,要么开始判断内核镜像是否存在,如果存在,直接启动内核镜像,如果不存在,通过网络从宿主机下载镜像,完成启动。,91,Bin文件格式的内容,92,3.Eboot的代码组成,BootLoader 由两部分组成:OEM 启动代码(OEM startup code)和主代码(maincode),93,14.4.3 BootLoader开发概述,微软为每种类型的CPU都提供了某种标准开发板的BootLoader例程,因此通常的开发方法是:从这些例程中寻找与硬件平台最接近的例程作为标本程序,然后再从自己的硬件平台上入手做相应的改动。目前,在市场上所购买的开发板一般会有第三方的厂商提供BootLoader,我们也可以去寻求这些厂商的帮助,获取BootLoader,从而减少工作量。,94,BootLoader的开发步骤,启动代码的实现 主控代码的实现 镜像下载代码的实现 支持DOC(Disk On Chip)的代码实现 BootLoader的编译、链接和下载,95,14.5 OAL开发,96,14.5.1 OAL概述,