wince

您所在的位置:网站首页 timerisr wince

wince

#wince| 来源: 网络整理| 查看: 265

最近要搞一个项目,本人有参与而且任务繁重。 呵呵, 顺便学习一下。

//192.168.3.59/internet-srv/wince/wince

1. 安装 dotNetFramework 1.1 , 因为安装wince v5.0时需要 , 最好直接安装Visual Studio 2003

2. 安装wince v5.0

3. 打上历史各项补丁 (http://www.microsoft.com/downloads 找)

4. 安装 eVc 4.0, 这个是为了做wince上的应用的工具

5. 为evc 4.0 安装补丁

wince v5.0 安装的同时也安装了platform builder 5.0, PB是用于定制基于Windows CE OS为内核的嵌入式操作系统的集成开发环境。PB提供了所有基于Windows CE内核的design, create, build, test and debug的工具。比如CETK,甚至一部分Windows CE的内核代码。总体来讲,PB是个开发平台的工具。

WINCE500的目录组织

目录

 说明

CRC

 存放了一个PB5.0安装时用到的校验文件crc.ini

PBWORKSPACES

 用来存放PB的工程

OTHERS

 存放了一些运行库、用于编译操作系统的二进制文件、注册表文件、批处理文件

PLATFORM

 存放了和硬件平台相关的BSP及MCU相关的代码和其他一些文件

PRIVATE

 存放了WinCE5.0开放的源代码

PUBLIC

 存放了WinCE5.0的相关组件,这里应该是纯软件的代码和库

SDK

 存放了用于编译WinCE5.0的相关工具和DLL文件

一般来说,在移植BSP的过程中,我们只会修改PLATFORM下的相关目录和文件,而其他的除PBWORKSPACES之外的目录,最好都不要修改,以免出错。PLATFORM目录下除了COMMON目录外,其他都是特定硬件平台的BSP,而COMMON目录中则包涵了不同体系结构的相关代码(ARM、X86、MIPS、SHX)、与平台无关的代码(COMMON)和SOC的相关代码(SOC),这些代码都不能直接修改,如果需要修改,应该先CLONE出来,再做修改。

Windows CE OAL层的结构与开发

引 言

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所示。

2 最小化的OAL

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

首先来看一下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。

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

Naked_Startup()

{_asm

{

cli

jmp KernelInitialize

}

}

S t a r t u P执行完毕后,跳转至K e r n e 1 S t a r t/Kemellnitialize(x86下)。

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的中断服务例程:

void OEMInit(void)

{...

HookInterrupt(5,TIMERISR);//注册定时器中断

}

⑾ 清除中断掩码,防止初始化内核时有中断申请。

(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(),完成串口初始化,为串口调试工作作好准备。

(3)OEMGetExtensionDRAM()

在最简最小化OAL层函数中,OEMGetExtensionDRAM()并不是一个必需的函数。OEMGetExtensionDRAM()的主要功能是查询是否存在另外一片DRAM.如果目标板上只有一片DRAM,则该函数返回FALSE。但在KernelStart通常都包含此函数。

至此,最小的OAL层已经完毕,kernel的最基本的功能可以正常使用。骨架搭起,第一阶段的任务告一段落,但是很多非常重要的功能还不完整,还不能做到物尽其用。于是需要进一步加强OAL层的功能。这种做法也是OAL层开发通常使用的方法。先完成基本功能,在基本功能确保正确无误后,逐渐加入其它功能。循序渐进,即使出错也很容易找到出错的地方,便于排查。

3 加强OAL

第二阶段主要目的是充分利用板上硬件资源和加强调试手段。主要包括中断、KITL、以太网口调试函数和OEMIOControl四方面内容。我们把包含这四方面内容的OAL层称为加强OAL。

3.1 中 断

外设硬件与CPU的数据交换基本上是异步进行的、最常用的中断形式。CE的中断处理顺序如图3所示。由图3可知,CE的中断实际上是由两部分ISR和IST 组成的。其中IST包含在驱动程序中,而ISR包含在OAL层中。所以,要想支持一个硬件,首先必须从0AL层为其作好准备。这个准备用两步完成。

①创建中断标识符。下面代码节选自SAMSUNG2410的oalintr.h。中断映射表通常位于/Platform//INC。

#define SYSINTR USB (SYSlNTR FIRMWARE+11)

#define SYSINTR USBD (SYSlNTR_FIRMWARE+12)

② 创建并注册ISR。ISR的主要任务是返回中断标识符。ISR代码通常位于/Platform//KERNEL/HAL下。

下面代码节选自SAMSUNG2410的armint.c。

if(IntPendVal==INTSRC_ADC){

s2410INT.>rlNTSUBMSKl=BIT_SUB_TC;

s2410INT_>rINTMSK |=BIT_ADC;

s2410INT_>rSRCPND |=BIT_ADC;

s2410INT_>rINTPND =BIT_ADC;

return(SYSINTR_TOUCH);

}

在中断处理中,还有三个函数也起着至关重要的作用。它是OEMInterruptEnable()、OEMInterruptDisable()和OEMInterruptDone()。

◇OEMInterruptEnable()用于执行允许设备产生中断的硬件操作;

◇OEMInterruptDisable()禁止设备发出中断申请;

◇OEMInterruptDone()中断处理结束。

3.2 以太网口调试函数

以太网口调试函数与串口调试函数相比,具有更快的速度。

◇OEMEthInit 初始化以太网调试口;

◇OEMEthEnableInts开以太网适配器中断;

◇OEMEthDisableInts关以太网适配器中断;

◇OEMEthISR 以太网适配器中断服务例程;

◇OEMEthGetFrame从以太网调试口收数据;

◇OEMEthSendFrame从以太网调试口发数据;

◇OEMEthQueryClientlnfo获取平台相关信息;

◇OEMEthGetSecs 返回从某一特定时间开始的计时值。本函数用于处理超时。

3.3 KITL

KITL 全称为Kernel Independent TransportLayer。它的主要用途是提供更方便的调试手段,如图4所示。KITL出现在Windows CE.net之后,把软件传输协议与硬件传输层隔离开。KITL使得开发者不必了解硬件传输层如何与软件协议层接口。

以下是应该在OEMInit函数中加入的KITL初始化代码。

①初始化所有PCI桥和设备,枚举它们并且给它们分配资源,然后使能,使他们能正常工作。注:此条适于有KITL网络接口卡(NIC)和NIC桥的情况。

② 对相关总线进行初始化,使得CPU能够正确识别NIC。

③通过调用KitlInit函数来初始化KITL。这部分代码可参照其它平台,代码文件为Halkitl.c。

④执行0EMKitlInit函数,进行相关的硬件初始化工作。搜索是否存在KITL 网口、串口或并口连接。

⑤执行完OEMKitlInit后,把Kitl.1ib和Kitleth.1ib包含入平台资源文件//Kernel/Buildexe/Kernkitl,以便把KITL打包进内核。有关KITL的其它函数请参考微软MSDN。

3.4 OEMIOControl

OEMIOContr01在OAL层是一个非常重要的函数,应用程序是通过调用KernelIoContrOI来调用OEMl0Control的。内核对许多硬件平台信息的获得都要通过对它的调用来实现。此外, 0EMl0Contr0I还是用户模式应用代码到内核模式OAL代码之间的转换入口。这就是说,用在用户模式下通过调用0EMl0Control可以获得内核模式的权力。0EMIOControl函数原型如下:

BOOL OEMIoControl(......)

{switch(dwloControlCode)

{caseIOCTL_HAL_SET_DEVICE_INFO:

case10CTL_HAL_REBOOT:

……

default:

return FALSE;

}

return TRUE:

}

硬件资源利用和调试手段的加强大大丰富了OAL的功能,但是嵌入式系统通常会面临的功耗问题和由于网络功能的日益普及而带来的安全性问题并没有涉及到。

4 完整OAL

完整OAL是指在加强OAL的基础上扩充了功耗和安全性验证的OAL。所以这一阶段的主要工作集中在电源管理与模块认证两部分。

4.1 电源管理

OAL 层的电源管理与驱动程序的电源管理颇为不同。一种设备驱动程序仅负责某种特定的设备,如果可能,则把这种设备置为省电模式,当形势需要时再把设备置为满载荷模式。OAL层的电源管理则是负责整个系统功耗管理。例如,调度器在下一个25ms没有线程要运行时,系统将被置为省电模式。

电源管理函数响应关闭系统和使系统空闲的系统调用。这些系统调用可能是软触发也可能是硬触发。以下两个函数是须在OAL层中实现的电源管理函数:

◇0EMIdle一一把设备置为空闲状态,此时系统处于低功耗状态;

◇0EMPoweroff一一把设备置为断电状态;

◇OEMPowerOff和OEMIdle的程序代码可在如下目录中参照例程%_WINCER00T%/Platform//Kerlael/Hal。

4.2 模块认证

自从Windows CE 3.0以来,在RAM中加载和运行模块前,内核可以对其进行授权核查。对于在ROM中运行的模块则不需要此过程。模块认证实际上是在被加载的模块后添加一数字签名,只有当系统用公开密钥验证数字签名通过后,该模块才可以被加载到RAM中运行。这样系统可以阻止或限制一些模块的运行,达到系统安全的目的。

要达到以上目的须完成以下两个函数:

◇OEMCertifyModuleInit,用于初始化验证过程,每验 证一个模块调用一次;

◇OEMCertifyM0dule,用于验证数字签名。

为了支持这两个函数,在OEMInit函数中须分配两个全局变量pOEMLoadInit和p0EMLoadModule,用来存放这两个函数的地址。

结语

Windows CE的OAL层是一个复杂的函数集。它的复杂性不但体现在包含函数数目繁多,而且体现在很多函数的硬件相关性非常大。本文并没有详细讲解每个OAL层函数,而是就一些通常会遇到的OAL层函数进行层层划分;在说明OAL层的功能和结构的同时,提出开发OAL的一种方法和思路。

PQOAL

这个概念全称为Production Quality OAL,产品级的OAL。它的基本原则如下:

不同芯片或片上系统的代码必须分离开来;

BSP中的代码应该是组件化的并且有逻辑的组织在一起;

芯片级代码、片上系统的代码和板级支持包(BSP)中的代码都应该是高质量的,以便于代码重用。

从PQOAL的角度分析PLATFORM的目录组织

PLATFORM/COMMON:这里存放了所有可重用的代码。这一部分代码将在BSP之前编译。

PLATFORM/COMMON/SRC/COMMON:这里存放了被BSP中重用的通用代码,这一部分代码是跟硬件平台无关的。譬如一般的IOCTL处理函数、与内核交互的公共的中断程序等等,另外还包括一下库文件,如OAL_IOCTL.lib、oal_intr.lib、oal_log.lib、kitl_log.lib等等。这一部分代码由微软提供,一般不能修改。

PLATFROM/COMMON/SRC/:CPU表示MCU的不同体系结构,如ARM、MIPS、SH和X86。这些目录分别存放了各体系结构的MCU的相关代码,如CACHE相关代码、物理地址和虚拟地址转换的代码等等。这部分代码只针对MCU的内核,不涉及具体的芯片。这一部分代码也由微软提供,不建议修改。

PLATFORM/COMMON/SRC/SOC:该目录下存放了不同的MCU对应的代码,跟BSP对应,这里可看做是CSP(CHIPSET SUPPORT PACKAGE)。这一部分的代码一般来说不能直接修改,如果需要移植类似平台的BSP,应该复制一个,重命名后再做修改。这里的目录和其中链接后的库文件的命名也遵循一定的规则(芯片名称_厂商名称_版本号)。这里需要注意的是SOC目录下dirs文件需要包括体系结构的说明,如PLATFORM/COMMON/SRC/SOC/PXA27X_MS_V1中的dirs文件以DIRS_ARM= /打头。这与BSP中的一般的DIRS文件不同。我在移植BSP的时候,并没有在这里做任何修改,只是将其中相关的文件拷贝到我自己的BSP目录下,这样方便BSP的发布

PLATFORM/BSPName:这里存放了跟开发板对应的相关代码。在编译WinCE操作系统时,它在/PLATFORM/COMMON的目录之后编译。我们在针对一款新的硬件平台移植WinCE5.0时就是在这里做相应的添加和修改。

BSP的目录组织如下:

目录

 说明

CATALOG

 存放BSP的CATALOG file

CESYSGEN

 编译的过程中,bib和reg文件将被拷贝到这

FILES

 存放BSP的bib、reg、dat等配置文件和无须编译的二进制文件

SRC

 存放BSP的所有源代码

SRC/BOOTLOADER

 存放BOOTLOADER的源代码

SRC/COMMON

 存放共享代码,链接后的库可被BOOTLOADER、OAL和驱动使用

SRC/DRIVERS

 存放设备驱动的代码

SRC/INC

 存放相关头文件

SRC/KITL

 存放KITL的相关代码

SRC/OAL/OALEXE

 链接OAL.lib和其他一些库,生成OAL.exe

SRC/OAL/OALLIB

 存放OAL的源代码,编译生成OAL.lib

WinCE文件系统概要

文件系统是一个实现了数据的存储、组织、处理和获取等操作的抽象数据类型。一般分为磁盘文件系统,网络文件系统和特定功能的文件系统。

      磁盘文件系统主要包括FAT(FAT12、FAT16、FAT32),NTFS、HFS、ext2、ext3,现在ext4也出来了。

      FLASH文件系统是针对FLASH存储器设计的文件系统。随着移动设备的不断普及,和FLASH存储空间的不断增长,FLASH文件系统也流行起来。在嵌入式系统中,绝大多数都使用FLASH文件系统。

      数据库文件系统是基于数据库的文件系统。与分层结构的管理不同,在数据库文件系统中,文件由描述符来标识,如文件的类型、主题、作者或其他一些元数据。

      网络文件系统是用来访问服务器中文件的文件系统,常见的协议有NFS、AFS和SMB。

      现代操作系统都集成了文件系统,WinCE也不例外。与桌面Windows的文件系统不同,WinCE的文件系统中没有分区的概念。所有的文件系统,都被Mount到根目录“/”下面。编程时需要注意,WinCE中也没有当前目录的概念,所有的目录都以根目录为参考。

      WinCE中支持的文件系统有如下几种:

文件系统

 概要

FAT或FATFS

 标准的FAT文件系统。单个文件不能超过4G,分区大小也有限制。

exFAT

 FAT的升级版,取消了文件和分区大小的限制。

TFAT

 基于exFAT的文件系统,支持交互操作,需要驱动的支持。

BinFS

 支持将bin文件Mount成一个文件系统,WinCE中的Multi-BIN需要用到该文件系统。

CDFS/UDFS

 用来支持CD和DVD的文件系统。

RAM(对象存储)

 RAM文件系统由FSD Manager管理。

RELFSD

 在开发的过程中,将开发主机的release目录mount到设备上。

WinCE文件系统的配置,由注册表实现,一般在[HKLM/System/StorageManager]中。

    在定制WinCE操作系统时,我们可以选择ROM-only 的文件系统或RAM and ROM的文件系统。当选择RAM and ROM的文件系统时,根目录文件系统在内存当中,掉电即丢失。为了实现根文件系统和注册表的保存,即在冷启动时不丢失,我们需要选择ROM-only的文件系统和HIVE BASED注册表,以将存储空间Mount成根目录,并配置注册表使其支持HIVE BASED注册表。

      Linux的文件系统有ext、XFS、JFS和ReiserFS。嵌入式Linux的文件系统主要有rootfs、RAMDisk、Cramfs、JFFS2(基于日志的FLASH FS)、YAFFS2(Yet Another FLASH FS)等。

WinCE驱动程序的分类

主要介绍WinCE下驱动程序的分类。

       驱动程序是介于操作系统和设备之间的一个代码层,它的主要作用是为操作系统提供一个接口,以操作不同的硬件,包括物理的和虚拟的设备。虽然驱动程序有很多种,但从编程的角度来看,无非是往一个固定的框架中添加相应的代码。这里的框架指的是一个接口,面向操作系统。代码实现的宗旨是,在正确的时间往正确的寄存器中写正确的值。

       驱动程序的分类,从不同的角度有不同的分法。拿串口驱动来说,你可以说它是一个分层驱动,你也可以说它是一个流驱动,你还可以说它是开机时自动加载的驱动……这似乎有点乱。如果你也这么认为,那建议往下看。如果这些你都了如指掌,那就不浪费时间了,当然,您愿意找茬,我会很感谢!

       先说本地驱动(Native Drivers)和流驱动(Stream Drivers)。WinCE下的驱动都可以归类到这两个里面,二者必居其一。这是从驱动程序提供给操作系统的接口来区分的。流驱动为操作系统提供了流接口函数,如XXX_Init()、XXX_Open()、XXX_Read()、XXX_Write()、XXX_Close()等等。这一类的驱动由Device Manager来管理,它调用ActivateDeviceEx()函数来加载流驱动。ActivateDeviceEx()的参数是注册表中相应的键,用来设定加载流驱动的属性,如Index、Order、Prefix等等。流驱动的注册表配置信息一般存放在[HKEY_LOCAL_MACHINE/Drivers/BuiltIn]下。流驱动加载成功后,应用程序通过调用CreateFile()、ReadFile()、WirteFile()等来访问流驱动的设备。流驱动可以动态管理,驱动调试助手就是用来帮助调试这一类驱动的。

与流驱动相反,本地驱动提供给操作系统的不是标准的流接口,而是事先约定好的特定接口。不同的设备,接口也不一样。WinCE中,常见的本地驱动有LCD显示驱动、触摸屏驱动、鼠标和键盘驱动及打印机驱动等。可以看到,本地驱动主要是人机界面相关的驱动。它们由GWES管理,在系统启动时加载。他们在注册表中也有各自相应的配置信息。如键鼠的注册表配置如下:

[HKEY_LOCAL_MACHINE"System"CurrentControlSet"Control"Layouts"00000409]

"Layout File"="kbdmouse.dll"

"Layout Text"="US"

"PS2_AT"="kbdmouse.dll"

"Matrix"="kbdmouse.dll"

本地驱动由操作系统调用,应用程序不能访问。对于这类驱动,驱动调试助手是无能为力的,只能老老实实的编译、下载、验证。

WinCE驱动中经常会听到MDD(Model Device Driver)和PDD(Platform Dependent Driver)的概念,这是从驱动代码实现的结构来区分的。WinCE的驱动可以是单层的,也可以是PDD+MDD。这没有硬性规定,一个驱动程序可以采用分层结构,也可以采用单层结构。一般来说,单层结构的驱动执行效率更高,而分层结构的驱动方便代码维护和移植。拿串口驱动来说,完全可以采用单层结构。而把它分为PDD和MDD,作为一般的开发者,我们只需实现PDD层就可以了,MDD层由微软实现。这样,驱动开发的工作量少很多,而代码的可靠性则有了更好的保证。至于采用哪一种结构的驱动,主要看你的需求。

WinCE 6.0引入了内核态驱动和用户态驱动的概念。在WinCE5.0及先前的版本中,驱动工作在用户态。从代码方面看,内核态驱动和用户态驱动没太大差别。如果驱动中没有采用什么特别的技术,内核态驱动和用户态驱动甚至是二进制兼容的。我曾经试过将一个DLL分别加载到内核态和用户态,都工作得很好。内核态驱动被加载到内核空间,用户态驱动被加载到特定的用户进程空间中。从执行效率来看,内核态的驱动效率比用户态的驱动高。从稳定性方面考虑,用户态的驱动不会对系统产生致命影响,而内核态的驱动相对危险。同样,采用哪一种类型的驱动,也是看你的需求。

从驱动加载的时间来看,可分为两种:系统启动时加载和需要时加载。一般来说本地驱动都是在启动时加载的,所以这里说的主要是流驱动。如果想要驱动在系统启动时加载,只需将它的注册表配置信息放到[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/]下,如[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Battery],系统启动时,Device Manager会自动加载它。需要时加载,顾名思义,就是想加载就加载,想卸载就卸载,很灵活。这里很有必要说一下USB设备的驱动加载,如USB摄像头驱动,它也属于需要时加载的驱动。从驱动的接口来看,它属于流驱动,但相对普通的流驱动,它增加了几个函数:USBDeviceAttach()、USBInstallDriver()、USBUnInstallDriver()等。USB摄像头驱动的加载在USBDeviceAttach()中完成。所以,它无须,也不能,用驱动调试助手加载。需要时加载的驱动还有一个作用,在无法修改系统的情况下,应用程序中动态加载该驱动,以完成对硬件的操作。

综上所述,WinCE驱动的分类,主要有以下几种分法:

按驱动接口分,可分为本地驱动和流驱动;

按驱动结构分,可分为单层驱动和分层驱动;

按驱动加载的空间分,可分为内核态驱动和用户态驱动;

按驱动加载的时间分,可分为启动时加载和需要时加载两种。

驱动调试助手,是用来动态管理流驱动。本地驱动和USB驱动不再它的控制范围之内,各位在使用时注意这一点。

WinCE中串口通讯的调试方法

      串口是嵌入式系统中应用很广的一种通讯接口。在WinCE中,通常会有一个串口供调试使用,另外的串口可与外围设备连接,如GSM和GPS等模块,以获取相应的信息并进行处理。

      在WinCE中,为了使用串口,必须有相应的串口驱动程序,一般在BSP中都有实现。串口驱动是典型的流驱动。应用程序中可通过CreateFile()、ReadFile()和WriteFile()等文件系统的操作函数来访问串口,从而实现串口数据的收发。

     虽然串口操作相对简单,但在实际调试时依然会碰到很多问题,譬如如何监视串口收发的数据。在调试GSM模块时,如果WinCE不能正确控制模块,我们就需要确认是发送还是接收的问题,是模块还是开发板的问题。在调试GPS模块时,经常需要监视GPS数据又不能影响固有GPS软件的运行。这些都要求我们能内建虚拟串口,以将物理串口收到的数据分发到不同的虚拟串口上,相反,发送则是由不同的虚拟串口往物理串口转发的过程。

    Serial Splitter Mobile就是这样一款专业软件,它能满足上述要求。以前曾用它调试过一个串口设备。当时用的是一个试用版,单次连接只能收发1M Bytes,超过1M就不工作了。开始没在意,以为是串口驱动和自己软件的问题,后来发现是Serial Splitter试用版的限制。调试手段引入的错误,是最让人郁闷的。为了方便使用,今天到其官网下载了最新的版本,并破解之,去除了收发数据的限制和应用程序中的注册信息。

    破解前的截图如下:

破解后的截图如下:

    使用截图:

    该软件使用很方便,简单测试了一下,效果还是可以的,有需要的请到这里下载:

   http://files.cnblogs.com/we-hjb/WINCE_SERIAL.rar,其中包括WinCE6.0下的Splitter Mobile破解版、WinCE串口调试助手和使用参考视频

测试:

直接通过网络下载.nb0格式的WINCE镜像文件到0x30200000,再通过运行go 0x30201000(过滤掉暂时无用的头),即可运行wince

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/huangfeng152/archive/2009/10/26/4729874.aspx



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3