版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、63/63 HYPERLINK WinCE第三方驱动安装之二CAB安装包制作Microsoft Windows CE是紧凑的,高效的操作系统,它被广泛的应用在从手持电脑到专门的工业控制器或消费用电子产品等各种嵌入工业产品中。英创公司ARM9系列工控主板预装了正版Windows CE5.0操作系统,并对板上所有硬件资源提供了完备的驱动支持。随着WinCE操作系统的广泛应用,越来越多的在PC上使用的硬件设备提供了对 WinCE系统的支持,如3G模块,Wi-Fi等。第三方驱动一般以两种形式提供,一是动态链接库(*.dll)加对应的注册表文件(*.reg),另一种是可直接安装的CAB文件(*.cab)
2、。与动态链接库加注册表文件形式的驱动相比,CAB文件安装十分方便,不需要了解繁杂的 WinCE INF文件格式或REG文件格式。本文介绍通过WinCE CAB Manager工具将以动态链接库usbser.dll和注册表文件usbser.reg形式提供的USB转串口驱动程序压缩为可直接在英创主板上安装的 CAB压缩包的方法。1、打开WinCE CAB Manager,选择File-New,运行New Cabinet wizard(CAB新建向导),选择“next”直至完成如图1。 2、在CAB Information上点击右键,选择Properties(属性)选项(如图2),打开CAB包属性设
3、置对话框,如图3。 3、在CAB Properties对话框中(如图3),填写Company Name(公司名称)和Application Name(CAB包名称)。4、切换至CAB Properties-Installation Directory对话框,设置CAB包默认安装路径,此处设置为NandFlashUSBDriverDll目录,如图4。 5、切换至CAB Properties-Cabinet对话框,设置处理器类型,Processor可直接选择为ALL/CEF,如图5。 6、切换至CAB Properties-Operating System对话框,设置操作系统版本,设置为支持CE4
4、.0CE5.0,如图6。设置完成后选择确认完成CAB包属性设置。 7、为CAB包增加DLL文件,如图7,在File标签上点击右键,选择Add添加USB转串口驱动的动态链接库文件usbser.dll。 8、修改usbser.dll的安装路径,在图8中所示USBSER.DLL上点右键,选择Properties,在弹出的 USBSER.DLL Properties对话框中设置usbser.dll的安装路径,如图9,选择%InstallDir%表示使用在第4点中设置的默认安装路径,即将 usbser.dll安装到NandFlashUSBDriverDll目录。 9、选择File-Import-Impo
5、rt form RGE.导入USB转串口驱动程序对应的注册表文件usbser.reg。在导入注册表时需要注意,第三方驱动默认安装目录往往是windows目录,因此需要在注册表文件中将动态链接库安装目录修改为在第4点中指定的目录NandFlashUSBDriverDll 。图10是注册表修改前后的对比。 将上面的工作保存后,一个可在英创主板上安装的CAB包PL2303_Driver.CAB就制作完成了,下面结合英创工控主板EM9161,介绍PL2303_Driver.CAB的安装方法。1、在EM9161的Nandflash目录下新建UsbDriverDll文件夹。2、将制作好的CAB安装包PL2
6、303_Driver.CAB拷贝到EM9161 Nandflash,双击运行,如图11,点击OK完成驱动程序的安装。 对于英创公司其它没有WinCE标准显示界面的嵌入式主板EM9160、EM9260、EM9360可通过WinCE远程桌面实现CAB包安装,安装过程与EM9161一致。 HYPERLINK o posted 2011-07-25 17:06 Maintell 阅读(65) 评论(0) HYPERLINK 编辑 HYPERLINK wince下USB设备驱动程序随着USB设备的不断增加,我们这些开发人员也就多了对USB设备进行驱动程序开发的工作。但是对于很多初学者来说,存在以下三个困
7、难: 一是对WinCE的驱动程序结构了解得太少,没办法得心应手的专注于驱动程序的开发工作; 二是对WinCE自带的USB驱动程序的例子没有弄懂,看到一大堆文件夹结构和源程序思维混乱; 三是几乎没有什么中文的参考资料,不知如何下手。 第三条是很多开发人员都遇到的,我也一样,很多朋友问我有没有什么资料,我也只能说抱歉,因为我也同样有这个问题,一切都靠自己的黑暗中摸索,因此本文不谈第三条。 第一条是可以找到资料的,如Windows CE .NET系统分析与实验教程,因此本文也不打算在此花费大量笔墨。 这样,本文的着重点就在第二条上面了,通过本文,我希望能让更多的朋友理解Windows CE下对USB
8、设备的驱动模型与样例程序中的实现过程,以样例代码为基础理顺USB设备驱动程序的开发思路。同样,本文的读者对象预期是入门者和准备着手 USB驱动开发的人员,驱动开发高手自然就当一笑吧。同时写本文的目的也是履行我半年前答应很多朋友的诺言,并向我的慵懒致歉。 好了,在看样例程序之前,我们还有些东西需要了解,我们就先来看下图: 在此图中,我们可以非常清晰的看到主机和物理外设之间的结构方式,在主机端,通过USBD模块和HCD模块使用默认的PIPE访问一个通用的逻辑设备,实际上就是说USBD和HCD是一组抽象出来的访问所有USB设备的逻辑接口,它们负责管理所有USB设备的连接、加载、移除、数据传输和通用的
9、配置。其中 HCD是主机控制驱动,是为USBD提供底层的功能访问服务,USBD是USB总线驱动,位于HCD的上层,利用HCD的服务提供较高层次抽象的功能。 由于HCD和USBD都是面向的一致的逻辑设备接口,那么对于各种各样的物理设备,就需要有唯一对应的设备驱动程序,这就是上图中最上层的特殊的PIPE所连接的物理设备和USB设备驱动程序。 有了对这个结构的认识,我们可以明确的是我们要写的就是最上端的USB设备驱动程序,在WINCE的样例程序中也称为USB Client Driver,它是工作于USBD之上,所以实际上我们的工作就变成了利用USBD提供的接口针对特定的物理设备来完成USB设备驱动程
10、序,而暂时与其他的部分无关。 好了,先到这,接下来就准备看一些具体的东西吧! 接下来,我们就来分析一下CE中的样例程序,我用的是4.2版本的,所以下面的内容是4.2版本中的程序。这里的程序是通过文件夹的形式组织在一起的,所以我们还是像以前学习CE的时候那样,先来了解与此相关的文件夹结构,如下图。 在USB文件夹下,分成了CLASS,CLIENTS,COMMON,HCD,INC,USBD几个文件夹,其中INC和COMMON里面有一个 lock.c的程序,这个程序很明显是将要被其他USB有关的驱动程序所使用的一个锁,代码很简单,只是一个类似临界区的封装体,可以保护多线程对同一内存区域的读写访问,可
11、以先不去管它。CLIENTS文件夹可能最初微软的开发人员是用来放置设备驱动程序的,但是后来没有放,而发布的时候也没有删除,所以遗留了下来,里面是个空的文件夹,所以没用实际用处。USBD和HCD是前述的底层驱动,里面含有很多子文件夹和程序,由于我们只针对USB设备驱动,因此对这两部分不做分析,不兴趣的朋友可以自己去了解。 重点就在CLASS文件夹了,展开来看,里面又包含了COMMON、HID、PRINTER、STORAGE几个文件夹,同样,COMMON里面存放的源程序是为HID、PRINTER、STORAGE所共有的。HID是USB输入设备如键盘/鼠标的样例驱动程序,PRINTER是USB打印机
12、的样例驱动程序,STORAGE是USB存储设备如U盘的样例程序。 我们此次以USB存储设备为例,所以再来展开STORAGE文件夹,其中的INC文件夹里面是头文件,CLASS是USB存储设备的驱动程序,DISK是磁盘驱动程序。这里为什么有两个驱动程序呢,我来简要解释一下。 驱动程序工作在硬件与操作系统之间,它有两个功能,一个是 将操作系统转发来的操作以符合指定硬件设备的形式控制硬件设备,另一个是向操作系统提供这个访问接口。比如说U盘,一方面驱动程序要把操作系统对U盘的识别、读、写等操作转换成U盘的动作,另一方面又告诉操作系统这是个U盘,可以当成一个文件夹或文件系统来用,能够接受标准的文件操作命令
13、。所以此处存在两个驱动。 另外还有一个文件夹,WINCE420PUBLICCOMMONDDKINC,这里面是与设备驱动有关的头文件,对于USB设备,相关的文件有 USB100.H, USBTYPES.H, USBDI.H,这里面前两个里面关于USB的定义是完全符合USB规范的,不是随便定义出来的,而USBDI.H文件里的内容就是USBD总线驱动程序向USB设备驱动程序提供的接口描述,在开发USB设备驱动时必须要包含此头文件,这样才可以得到USBD接口的原型。 此前,我们共同了解了USB驱动在CE中的位置结构,也了解了样例驱动程序的文件夹结构,接下来,我们就要了解一下USBD为我们提供了哪些接口
14、来实现设备访问以与驱动程序管理的功能。找到USBDI.H,不要告诉我你找不到吧,不管你用什么编辑器,记事本也好,PB也好,VC/EVC或者VS都行,打开它,我们一起来了解一下USBD为我们提供了什么。 我们首先看到的一个大的结构体就是_USB_DRIVER_SETTINGS,注意这个结构体不是USB规范中的USB设备描述,而是为了CE设备管理器加载USB设备驱动程序方便而建立的。该结构体中对供应商描述、设备描述和Interface的描述是用来匹配注册表中对USB设备驱动的注册表键,当设备管理器发现你设备的这些值与注册表中的这些值相符时,就会加载你的驱动。也就是说它是与你的设备唯一对应的东西,是
15、一种标识。该结构体的供应商部分的描述需要根据你的设备的供应商信息来填,设备描述的设备类、子类、协议等可以在USB规范中找到,在USB100.H头文件中也有一部分,在后面的样例程序中也定义了一部分。 在接下来有三个函数是必须由USB设备驱动程序实现的,这也就是我们在MSDN里或其他CE的文档里所看到的,这几个函数就是: USBDeviceAttach:设备加载的时候由系统调用 USBInstallDriver:设备第一次加载的时候由系统调用,用来安装注册表配置以便搜索设备 USBUnInstallDriver:设备移除后清理由上一个函数写入的注册表配置 这样在我们的驱动程序中就一定要按照这三个函
16、数的原型来实现,否则就不能为设备管理器所识别。其实除了这三个,个我觉得第四个也是必须的,这就是一个函数指针所指向的函数: *LPDEVICE_NOTIFY_ROUTINE这个指针所指向的函数是用来接收通知消息的,既然微软说任何USB设备必须实现USB_CLOSE_DEVICE消息的响应,那么这个指针所指向的函数自然也就是必须要实现的了。 继续向下看,是一组函数的原型,这些函数就是USBD向设备驱动程序提供的服务接口,有些函数是可以任意调用的,用来完成版本信息读取、注册表操作和设备驱动程序注册,这些函数有:GetUSBDVersion RegisterClientDriverID UnRegis
17、terClientDriverID RegisterClientSettingsUnRegisterClientSettings OpenClientRegistryKey 还有大量的函数是必须通过指针调用的,通常只允许在驱动程序中调用,为了方例使用,在这里给出一个_USB_FUNCS的结构体,每一个结构体成员对应了一个函数指针,这样在驱动程序中要想使用USBD函数只能通过一个结构体变量来进行了,在这里我们要记住这个结构体的名字,并且微软还对这个结构体变量进行了以下的类型定义:typedef struct _USB_FUNCS USB_FUNCS, * PUSB_FUNCS, * LPUSB_
18、FUNCS;typedef struct _USB_FUNCS const * PCUSB_FUNCS;typedef struct _USB_FUNCS const * LPCUSB_FUNCS; 好了,到此我们发现,大部分的USB工作都已经被USBD完成了,我们为了实现自己的设备驱动,只需要利用这些指针或函数,来实现四个我们自己的函数,然后在其中匹配上我们自己的设备就可以了。是不是忒简单,没错,总不能刚开始就把自己吓得不行,那样后面可就没法做了。在上次了解了所有 USBD接口函数以后,我们已经有了很多基础知识了,回顾USB样例的文件夹结构,我们还能记得USBCLASSCOMMON这个文件夹
19、下是存放所公共部分的源程序,它是微软专门抽象出来的能为大多数USB设备驱动程序服务的一些结构体以与函数的封装,我们这次再来概略的了解一下这里面的源程序。 这里面包含了三个程序,分别是: remlock usbclient utils 下面我们分别来了解一下这三个程序的功能和接口,很显然,USB设备驱动程序肯定是会用到这其中的一部分函数的,因此我们不一定需要读懂这其中的每一行,但至少要对这些函数有个印象,不至于在读驱动程序时不知道函数的来源。 remlock程序是一个移除设备的锁,利用这个结构体 typedef struct _REMOVE_LOCK BOOL Removed; LONG IoC
20、ount; HANDLE RemoveEvent; REMOVE_LOCK, *PREMOVE_LOCK来实现在设备移除时进行的同步控制。其中Removed成员是对设备是否已经移除的标识,IoCount成员是对设备进行访问的数量,这也是驱动程序中常用的行为,就像此前我们看到的那个Lock程序一样,RemoveEvent是一个内核事件,熟悉WIN32编程的应该都很清楚,它是内核通知应用程序的一种方式,也是线程这间并发控制的一种手段,如果不熟悉,还是像我在以前文章中提到的那样,一定要找WINDOWS高级编程之类的书把它学明白,否则就很难控制驱动程序了。 利用它实现的那几个函数就不说了,与临界区的用
21、法是一样的。另外提一句,在此程序中有类似InterlockedIncrement这样的函数,这种函数是WIN32 API函数,专门用来提供多线程对同一变量的同步访问的,可以通过MSDN查到详细用法。 usbclient程序是对USBD进行包装以供USB设备驱动程序使用的函数接口,通过usbclient.h我们可以发现里面是关于数据传输、属性设置、状态描述和复位的一组函数原形的定义,我们再看usbclient.c文件,这些函数大部分都拥有一个LPCUSB_FUNCS类型的参数,回顾上次我们对USBD的了解可知,正是通过这一参数才能访问USBD提供的服务功能,浏览一下函数的实现发现,确实每个函数都
22、是通过这个参数调用了USBD的函数,然后处理调用后的结果,所以这里只是多了一层封装,使得驱动程序的编写更加清晰易于维护。 另外,这里我们要留意一下IssueBulkTransfer()、IssueInterruptTransfer()、 IssueVendorTransfer() 这三个函数,它们实现了通用的Bulk传输、中断传输和自定义的传输方式,在驱动程序中要用得到。 utils程序很简单,是对注册表操作的封装,利用_REG_VALUE_DESCR这个结构体和GetSetKeyValues()函数可以方便的访问注册表,在驱动程序的安装中会用得较多。 又说了这么多东西,虽然没有看多少程序,但
23、我们又离驱动程序近了一层,至少知道了很多函数是要在驱动程序中用到的,如果有兴趣,可以具体阅读每一个函数的实现方法,但我觉得这并不影响对驱动程序的开发。如果是我写驱动,在没有特别的情况下,我会把这些公用的源程序照搬过来,这可是能极大的缩短开发周期的事哦!正如所料,接下来我们就进入到DRIVERSUSBCLASSSTORAGECLASS文件夹下,接触USB设备驱动程序。 我们先来了解两个头文件,分别是STORAGEINCusbmsc.h和STORAGECLASSusbmscp.h,其中前者是USB存储设备公用的头文件,后者是需要按照自己的设备更改的头文件。我们先来看前者。 在usbmsc.h这个头
24、文件中,前边定义了很多常量,包括子类和协议的常量,这是从哪里来的呢?前文我们已经提到过,这些量值是依据USB设备规范得来的,在规范上都作了定义,所以此处的值必须与USB规范中的相一致。再向下的命令块结构体和数据块结构体是用来与USB设备通讯用的,可以通过这两个结构体的实例与USB设备传输数据。 下面的函数原型就不说了,前文提到过,在这里只记得有这几个函数就行了。 再来看usbmscp.h这个头文件,这个头文件是要按照自己的需要和USB设备来进行修改的,比如DRIVER_NAME_SZ是驱动程序的名字,RESET_TIMEOUT 是一个超时的默认值。还有很重要的一个就是USBMSC_DRIVER
25、_SETTINGS的设置,这个设置是与USBDI.H中的 USB_DRIVER_SETTINGS结构体一一对应的,为了符合我自己的设备,通常要把dwVendorId和dwProductId等设置成设备的对应值,比如我的U盘的VendorID是0 x058F,ProductID是0 x9321,那我就会把这两个值对应的写在相应的位置上。同时在系统注册表中也会利用这两个值修改注册表的键以便设备管理器可以顺利的找到我的设备驱动。 下面还有一个_USBMSC_DEVICE结构体,它是用来描述你自己的USB存储设备的,是封装了USBD函数表指针、磁盘设备指针、管道和配置项的最重要的数据结构,在驱动程序实
26、现上此数据结构就是重点的参数,鉴于样例程序对每一个结构体元素都作了明确的注释,此处我就不一一描述了,它就像C+中的类一样,是最后把一些小类组合起来的可以最终使用的结构。 好了,对这两个头文件有所了解以后,我们就进入最关键的部分,源程序。我们接下来来看usbmsc.c这个文件。为什么要先看这个文件而不是同一文件夹下的其他几个文件呢?我来解释一下。在这个文件夹中有一个usbmsc.def的文件,大家都知道它是定义了导出函数的,通常与它同名的程序文件都会含有 DllEntry的入口,既然入口在这,那我们自然就先来看这个文件了。如果用到了其他的文件,再看不迟。 这可是一个有1000多行的源程序,但不要
27、害怕,我们只看最主要的,别的函数的实现你可以自己去研究。首先看到文件的DllEntry入口之前有5个函数原型的定义,从函数名上就可以知道这个函数的功能了,很显然这几个函数是程序实现过程中被调用的,所以目前知道功能就行了,不用了解实现方法。忘了说一句,这个程序中包含了bot.h和cbit.h两个头文件,可见程序中是要用到它们的功能的,不过先不管它,继续往下看。 DllEntry入口函数的下面,就是USBInstallDriver()这个函数了,它的作用是进行与USB设备相关的注册表操作,主要的语句是:bRc = RegisterClientDriverID( wsUsbDeviceID );bR
28、c = RegisterClientSettings( szDriverLibFile, wsUsbDeviceID, NULL, &usbDriverSettings );即先注册设备类别,然后是设备细节。 同样,USBUnInstallDriver()函数是以相反的顺序解除注册信息的。 这几个与注册有关的函数在前面我们提到过,是由USBD接口提供的,这里我们可以看到USBD对设备驱动程序的重要性。 在继续向下看,我们发现了USBDeviceAttach()函数,这可是最重要的地方了,当有USB设备插入插口以后,操作系统是如何识别它的呢,如何将其做为一个文件夹加以访问的呢?我们就来解开这里的
29、谜团。 为了我们方便说明,我将此程序简化如下: 后面的程序将以此行号进行说明。 我们来看程序的第4行,这里有一个判断语句,它是在判断插入的设备是否是USBMSC_INTERFACE_CLASS类型的,这个常量是在usbmsc.h文件中定义的,也就是说如果设备不是USB存储设备,那么就结束这个函数,也就是此驱动只能处理USB存储设备。 当发现设备符合此驱动程序的要求后,就通过函数ParseUsbDescriptors()来解析这个设备,这个函数在下面的程序中将被实现,我们可以看一下该函数的函数体,很显然,它是在为设备进行各种配置,这就不多说它了。 再往下,分配内存,设置标志,从注册表中读取信息。
30、注意,这里读取到的注册表信息是DriversUSBClientDrivers Mass_Storage_Class和bInterfaceSubClass变量组合成的注册表键下的值,具体可参阅源程序,这个注册表键下放置的内容是HKEY_LOCAL_MACHINEDriversUSBClientDriversMass_Storage_Class6DLL=USBDISK6.DLLPrefix=DSKFolder=USB DiskIOCTL=dword:4IClass=A4E7EDDA-E575-4252-9D6B-4195D48BB865由此可以看出,通过此处的注册表读取,驱动程序可以知道这个设备将
31、通过哪种形式以与哪个DLL向操作系统提供接口。同时也为后续的操作进行了准备。 最关键的部分就在接下来的LoadDriver()那句,加载了另一个驱动程序的DLL文件,就是上述注册表中的USBDISK6.DLL文件,计数器增一,取到该文件中UsbDiskAttach函数与UsbDiskDetach函数的地址,注册事件通知处理函数,然后调用了该DLL文件中的 UsbDiskAttach函数。 由此可见,USB设备驱动程序有两层功能,一方面是识别出指定的设备并进行配置,另一方面按照要求调用更高层的驱动程序来向操作系统提供接口。当调用了 USBDISK6.DLL后,操作系统就会按该文件中的程序以一个磁
32、盘的形式或文件夹的形式进行处理,通过文件系统的操作,就可以对其进行读写控制了。我们也可以看一下HID设备的这个函数,它也是通过这种方式让操作系统知道把USB设备识别成鼠标设备的。 前文我们说过还有一个通知消息的回调函数,我们在刚才的程序体中已经发现通过:UsbFuncs-lpRegisterNotificationRoutine( hDevice, UsbDeviceNotify, pUsbDevice );语句已经对这个函数进行了设置。我们再向下来看一下这个函数的函数体。这个函数很简单,只要对USB_CLOSE_DEVICE消息进行处理,既然是要关闭 USB设备,那么调用USBDISK6.D
33、LL中的Detach函数是必须的,让上层的驱动程序进行释放,然后将引用计数减一,如果不再有设备引用此驱动程序,则FreeLibrary(),仅此而已。 其余的函数可以再仔细研究一下,在此就不详细描述了,接下来我们要弄明白的就是到底操作系统是如何通过抽象的DISK读写具体的设备呢? 带着上次留下的疑问,我们继续来学习操作系统如何通过USBDISK读写USB设备的。我们先看USBCLASSSTORAGEDISK SCSI2usbdisk6.def文件。在这个文件中可以看到,该DLL一共导出了14个函数,其中两个是上次内容当中被设备驱动程序调用的 UsbDiskAttach和UsbDiskDetac
34、h,余下的是一组以DSK开头的流驱动接口,易见,USBDISK是以流驱动的形式向操作系统提供服务的。 为了清晰起见,以下大量的程序我们并不学习,而只关心设备读写,因此我们来看DISK.C这个程序文件。找到DSK_Read和DSK_Write两个函数,令我们大失所望,因为这两个函数都是形如UNREFERENCED_PARAMETER(pDevice);UNREFERENCED_PARAMETER(pBuffer);UNREFERENCED_PARAMETER(BufferLength);DEBUGMSG(ZONE_ERR,(TEXT(DSK_Readn);SetLastError(ERROR_I
35、NVALID_FUNCTION);return 0;这样的实现,也就是说用户无法通过常规的Read函数使用这个设备,那怎么办?是否意味着这个DISK无法读写呢?当然不是,我们应该马上想到DSK_IOControl()这个函数,当遇到某些设备无法用常规的文件操作函数操作时,我们有DeviceIoControl()用户函数可以使用,而这个函数就会调用到驱动程序中的DSK_IOControl函数。 在这个函数中,我们找到了对IOCTL_DISK_READ等命令的处理程序,其中最关键的一句就是ScsiRWSG(pDevice, pSgReq, pDevice-Lun, bRead),即调用了一个Scs
36、iRWSG的函数。 在Scsi2.c这个程序中,我们找到了这个函数,其中SG指的是一种读写缓冲区的数据结构,实际上就是带有缓冲区与长度的一个结构体,是CE下磁盘设备通用的读写数据结构,可以在diskio.h中找到它的定义。在这个函数中我们发现它再次调用了ScsiReadWrite()这个函数进行读写操作,找到这个函数,里面有我们最重要的一行调用,即调用了UsbsDataTransfer()函数,还记得这个函数在哪见过吗?没错,就是在USB设备的驱动程序当中。 通过这一过程我们发现,那些Scsi的函数都只是在准备一些缓冲区、数据结构等,并没有对硬件进行操作,真正要操作硬件设备的还是由驱动程序来完
37、成的,可见,设备驱动程序是有着很强层次结构的,下层是专门针对物理设备的,上层是针对操作系统的抽象设备的,下层是U盘等物理实体,上层是文件夹,二者通过一定的通信或调用机制完成了设备在操作系统下的正常工作。 回到usbmsc.c程序中来,找到UsbsDataTransfer函数,这个函数很简单,根据传输协议调用CBIT_DataTransfer()或BOT_DataTransfer() 即可。 HYPERLINK o hive/2009/03/04/1403463.htmlposted 2011-07-25 17:05 Maintell 阅读(55) 评论(0) HYPERLINK 编辑 HYPE
38、RLINK 利用EVC快速开发WINCE5.0的流驱动(转载)WinCE5.0提供了一个标准的流驱动格式,大大方便了设备驱动程序的开发工作。但是传统的开发方式往往效率很低。方法如下: 1.在Platform Builder下建立一个流驱动的dll工程。 2.为流驱动增加注册表项。如: HKEY_LOCAL_MACHINEDriversBuiltinIRControl Prefix=IRC Dll=irc.dll Order=dword:66 Index=dword:1 3.修改platform.bib文件,将流驱动的dll文件打包到NK.bin. 4.MakeImg,生成包含流驱动的NK.BI
39、N. 整个过程烦琐,而且只要稍加修改,就要重先makeImg,大概要浪费3-5分钟.这种开发效率是很低的. 下面2种介绍在EVC下快速开发WINCE流驱动的方法,是我自己亲身经验,拿出来与大家分享,也希望和各高手相互学习和探讨. WINCE 的驱动,不象桌面windows驱动开发那样烦琐,windows驱动开发分好几种,如wdm啦,VXD啦,等等,开发这些驱动需要专门的开发环境和工 具,给开发者带来比较高的技术门槛.所幸的是,WinCE的驱动开发,没有这么多的限制和门槛.而且应用程序可以直接和底层硬件打交道的(注:尽管这样,笔者还是不建议大家直接用应用程序访问底层硬件,这种做法是不安全的),甚
40、至中断初始化,中断线程都可以在用户级的应用程序完成.所以给驱动开发带来了不少的便利. 依我自己的经验来看,具体有以下2种方法. 1.利用EVC生成驱动的DLL. 1).新建一个evc的dll工程,将流驱动代码移植到evc代码中。 2).编写导出文件*.def,将流驱动的10个标准函数导出.并在ProjectSettingLinkProject options里面标注,如:/def:IR.DEF .(这一步如果不做,生成的驱动将不可用) 3).编译代码,这个时候一般会出现一些错误,如找不到头文件或库文件等错误,请在wince的安装目录下找到相应的头文件和库文件,在 ToolsoptionsDir
41、ectories中指明头文件和库文件的路径。在 ProjectSettinglink中指定相应的*.obj文件(具体文件视源代码调用了哪些驱动和库,到wince的目 录下找到这些obj文件链接进来即可) 4).编写一个应用程序来调试驱动.利用RegisterDevice/DeRegisterDevice动态加载/卸载流驱动,模拟WinCE设备管理程序的功能. 以上这种方法,完全脱离了Platform Builder的开发环境,使驱动的开发和调试工作象开发应用程序一样轻松和快捷.可以在驱动程序中利用RETAILMSG函数从UART口输出调试信息. 2.利用EVC将驱动程序写成exe,直接象调试应
42、用程序一样调试驱动. 最后将调试好的源代码移植到驱动程序的dll工程中去.具 体方法和第一种方法类似,不同之处在于,前者是新建一个纯DLL工程(带导出函数),后者是新建一个MFC的exe工程而已.编译的头文件和库文件方法2 者雷同.这种方法的好处是可以直接编译成evc的debug工程,可以在源代码中进行单步跟踪调试和设置断点,大大的提高了驱动程序的调试效率. HYPERLINK o posted 2011-07-25 17:04 Maintell 阅读(19) 评论(0) HYPERLINK 编辑 HYPERLINK WinCE流驱动加载的控制 (转载)前段时间整理了 HYPERLINK Wi
43、nCE下调试串口的动态复用,基本实现了调试串口与普通功能串口之间的动态切换。其中实现的方法有点欠缺,在重新烧录或者升级系统后,导致系统无法正常启动。这算是个BUG。该功能加上才几天,就陆续有好几个同事碰到。本来想着使用方便的,没想到反而增添了一些麻烦。 这个问题在实现时曾考虑到,发布版本的日志里也加了说明,如果启用了调试串口,那么在烧录或者升级系统前,须禁用调试串口。说实在的,确实有点麻烦,不小心就忘了做这个工作。而问题的根源是实现机制不太合理。调试串口的配置被分散在两处,一处是存储在NAND Flash的特定区域,另一处是注册表中。系统启动时,OAL根据Flash中保存的状态,确定是否启用调
44、试串口,而驱动加载时又根据注册表的状态,确定是否加载调试串口的驱动。两处保存的状态不同步时,问题就出现了。问题分析清楚了,解决方法自然就有了,保证两处的状态一致即可。 调试串口的配置由存储在NAND Flash中的参数决定,系统启动时根据该值,动态修改调试串口对应的注册表配置,确保在启用调试串口时,不再加载它所对应的驱动,也就不会产生冲突,导致系统无法正常启动了。 在驱动注册表中,Flags是用于控制流驱动的加载行为的。其中DEVFLAGS_NOLOAD即表示不要加载该驱动。所以,在合适的地方添加如下代码,即可控制调试串口驱动的加载。 HYPERLINK l viewSource o view
45、 source view source HYPERLINK l printSource o print print HYPERLINK l about o ? ?void DisableDebugSerial(BOOL bDisable) HKEY Key; DWORD Status; DWORD Disposition; DWORD Value; DWORD Flags; Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, LDriversBuiltInSerial3, 0, NULL, 0, 0, NULL, &Key, &Disposition); i
46、f (Status = ERROR_SUCCESS) Value = bDisable ? DEVFLAGS_NONE : DEVFLAGS_NOLOAD; RegSetValueEx(Key, DEVLOAD_FLAGS_VALNAME, 0, DEVLOAD_FLAGS_VALTYPE, (PBYTE)&Value, sizeof(Value); RegCloseKey(Key); 如果禁用了调试串口,则将Flag是设置为DEVFLAGS_NONE,设备管理器将正常加载驱动。如果没有禁用调试串口,则将Flags设置为DEVFLAGS_NOLOAD,设备管理器就不会加载该驱动。 通过以上方法
47、的改进,调试串口的动态复用就更方便了。 HYPERLINK o posted 2011-07-25 16:35 Maintell 阅读(18) 评论(0) HYPERLINK 编辑 HYPERLINK WinCE6添加对MFC的支持 转载WinCE6默认情况下不支持MFC,在PB里面也没有与其有关的组件可以添加。要想让WinCE6支持MFC,就要手动拷贝一些DLL,然后修改bib文件,把这些需要的DLL打包进NK。 需要的DLL在Program FilesMicrosoft Visual Studio 8VCceDllarmv4i下可以找到。下面是我打包进NK的DLL。 在bib文件中添加:
48、MFC80ENU.DLL $(_FLATRELEASEDIR)MFC80ENU.DLL NK SH atl80.dll $(_FLATRELEASEDIR)atl80.dll NK SH MFC80CHS.DLL $(_FLATRELEASEDIR)MFC80CHS.DLL NK SH msvcr80d.dll $(_FLATRELEASEDIR)msvcr80d.dll NK SH msvcr80.dll $(_FLATRELEASEDIR)msvcr80.dll NK SH MFC80UD.DLL $(_FLATRELEASEDIR)MFC80UD.DLL NK SH MFC80U.DLL
49、 $(_FLATRELEASEDIR)MFC80U.DLL NK SH 转自: HYPERLINK o posted 2011-07-25 16:30 Maintell 阅读(10) 评论(0) HYPERLINK 编辑 HYPERLINK o Day Archive 2011年7月24日 HYPERLINK Wince初级篇(转载)一、初级问答1、wince驱动它以什么形式存在呢?dll2、怎么把它加到wince内核中呢?platform.bib3、如何在开机时自动加载内核里面的驱动呢?platform.reg4、XIP是什么?Execute in place (XIP),即本地执行。本地执
50、行区域中,程序可以在ROM中执行,而不用复制到RAM中,节省了系统资源。5、访问寄存器1、#define rRTCCON (*(volatile unsigned char *)0 x57000043) /RTC control这有点类似absacc.h中XBYTE的定义2、define XBYTE (unsigned char volatile xdata *) 0) 其中volatile英文愿意为易变的,此处为易变量,是可能指由外部因素改变的变量,如外部设备的寄存器(volatile unsigned char *)0 x57000043这个表达式是强制转换0 x57000043为易变的无
51、符号指针类型,将其作为地址来使用。相当于volatile unsigned char *p;p = 0 x57000043;然后对p进行引用*(volatile unsigned char *)0 x57000043也就是指向了寄存器绝对地址为0 x57000043,然后按照定义宏的习惯,将之用括号小心的包起来。然后就可以对寄存器进行读写啦。二、中级问答1、如何快速编译Wince系统呢?命令行编译:build -c 命令buildrel 命令makeimg 命令 or 点击build按钮2、驱动相关CEC特性目录集合文件定义定义要将哪些特性集成到开发环境中,并加入到操作系统镜像中CEC文件简单
52、的说,就是把自己编写的应用程序、驱动程序、第三方驱动加载到W特性目录中,使建立平台时可以像添加自带特性一样添加自己的特性。而不是每建一个平台都要在Project.bib,Project.reg,Project.dat中重复写很多东西。 BIB文件 二进制镜像编译文件加入定义哪些模块与文件,如何包含在操作系统的镜像中。 REG文件 注册文件系统冷启动时建立注册键与变量(注册表)流接口驱动程序流接口函数使得应用程序可以通过文件系统访问这些驱动程序。流接口驱动程序几乎支持任何类型的可以连接到基于WINCE的平台的外部设备。我理解为通过该驱动使得应用程序访问到任何ARM外的设备,比如一个IO,让灯亮。
53、驱动分为:本机驱动:WINCE专用驱动(如电源和LED),由GWES管理流接口驱动:一般的设备驱动程序,以DLL的形式出现单片驱动分层驱动:上层是MDD,模块设备驱动程序model device driver下层是PDD,平台设备驱动程序Platform Dependent Driver 中断处理函数armint.c中断使能cfw.c 包含硬件访问地址的注册表项platform.regposted 2011-07-24 16:32 Maintell 阅读(41) 评论(0) HYPERLINK 编辑 HYPERLINK Windows CE的嵌入式系统的结构要进行嵌入式系统的应用开发,必须先建
54、立一个开发平台。一个基于Windows CE 的平台由Windows CE 操作系统核组件、OEM 适配层(OEM Adaptation Layer ,OAL) 和设备驱动程序以与组成系统的硬件设备组成,图1为基于Windows CE平台的层次结构。 从图1中可以看出,一个基于Windows CE 的嵌入式系统可分为四个层次,从底层到上层分别是硬件层、OEM层、操作系统层和应用程序层。硬件层是系统的硬件,包括微处理器和各种周边设备。OEM层是一个硬件抽象层,它提供了硬件和操作系统之间的接口,操作系统要访问具体的硬件就可以通过OEM层提供的API 进行访问,而不必直接与硬件打交道。操作系统层中有
55、Windows CE 的组件,用户可以根据自己的系统的需要进行定制,选择需要的组件,去掉不必要的组件,这样可以减小内存需求,使系统性能达到最佳。应用程序层是用户为特定的嵌入式系统开发的应用程序。 在操作系统层中,设备管理器提供对可安装设备的支持,允许在系统中安装诸如PC 卡存储器和调制解调器之类的设备已扩充功能,内核提供最基本的操作系统功能,例如进程调度、内存管理、进程通信等。图形、窗口事件处理模块将用户的击键、鼠标移动和控件选择转换为消息,传送给应用程序和操作系统来处理用户的输入。对象存储、文件系统、数据库和注理用户的输入。对象存储、文件系统、数据库和注册表提供存储数据的能力。附加技术模块指
56、由CE操作系统提供的一些可选择的专用功能模块,如Java语言支持模块、手写体输入识别模块等。用户界面模块为系统提供一个与PC 电脑上的视窗操作系统类似的图形化操作界面。对系统设计者而言,需要自行开发的是应用程序和直接与硬件有关的部分,包括硬件系统本身、OAL 、设备驱动程序。其中,OAL 是指建立在硬件设备与系统内核之间的一层代码,主要任务是为内核管理具体的硬件设备时钟、中断和实施电源管理提供支持。设备驱动程序负责支持操作系统对目标硬件的访问。OAL 和驱动程序都要针对具体的硬件设备编写。 一般硬件设备制造商会为设备提供驱动软件支持,如果有专门为CE 系统编写的驱动程序,只需将其加入到操作系统
57、的相应模块中就可用了。如果没有,则应根据厂商提供的驱动程序开发包编写。通常这些开发包总已经包含了完成各种硬件操作的标准代码,开发者的工作只是将其与相应的CE 系统API函数对应起来。在CE 系统中,所有涉与硬件的操作都通过调用相应的API 接口函数来完成,而OAL 和驱动程序就是要为这些API 函数提供支持,将其翻译为直接对目标硬件进行底层操作。通过这种方式,CE 系统将应用程序与具体的硬件设备进行了隔离,应用程序只需调用API 函数就可以实现对硬件的访问。这样,程序员在开发应用程序时就没有必要编写任何直接针对硬件的代码,因此不必考虑具体的硬件特性,而应用程序也具有了不依赖于具体硬件设备的独立
58、性。 posted 2011-07-24 16:30 Maintell 阅读(12) 评论(0) HYPERLINK 编辑 HYPERLINK Windows CE驱动分类Windows CE提供了许多用于开发设备驱动的模型,这些驱动程序模型使得Windows CE 能适应大部分的内部和外围设备。因此,在深入探讨Windows CE矩阵键盘驱动程序之前,先了解在WinCE平台上使用的两种设备:内建设备和可安装设备。因此,从驱动加载方式来看WinCE可分为本机设备驱动(Built-In Driver)、可加载驱动(Loadable Driver)。 本机设备驱动即Native Device Dr
59、ivers,WinCE设计成可直接使用内建设备,这些设备由本机驱动过程控制。本机驱动程序是与WinCE的核心组件紧密相连,这些驱动对应的设备通常在系统启动时,在GWES的进程空间内被加载,因此它们不是以独立的DLL形式存在。可加载设备是指可与平台连接和分离的第三方接口设备,可由用户随时安装和卸载这些驱动,可以在系统启动时或者和启动后的任何时候由设备管理器动态加载。通常这类驱动是以DLL动态链接库的形式存在,系统加载后这些驱动程序是以用户态的角色运行,这种外围设备的驱动也被称为流驱动。 两者的差别在于它们提供的编程接口不同:本地设备驱动可以根据具体设备的需求提供本机的相应接口;而流接口驱动则是提
60、供一组通用接口即流接口函数,应用程序可以通过流接口提供的接口函数来访问外围设备。posted 2011-07-24 16:22 Maintell 阅读(39) 评论(0) HYPERLINK 编辑 HYPERLINK WinCE USB驱动开发的简介与内容随着USB2.0设备的不断增加,USB设备驱动开发在嵌入式开发中变的越来越重要。Windows CE支持USB 2.0更是对这一波新技术浪潮产生巨大的推动。本文的作者分析了自己进行USE驱动开发的经历,希望可以让读者少走一些弯路。 随着USB2.0设备的不断增加,USB设备驱动开发在嵌入式开发中变的越来越重要。Windows CE支持USB
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 采购物流奖罚制度
- 采购部门上墙制度
- 采购需求内部审查制度
- 采购预算审批制度
- 金属软管采购管理制度
- 铁塔采购制度
- 2025年前台岗位知识试卷
- 《错误》名师教案2
- 《毫米、分米、千米的认识》教材分析
- 生产部门年终的工作总结(集锦15篇)
- 【部编版】三年级语文下册全册导学案
- (完整版)xx中学“双积双评”积分入团实施方案
- 阳明计米器mc-262说明书
- 西藏色拉寺导游词
- 2023国网蒙东电力有限公司招聘管理类《管理科学与工程》考试题库(含答案)
- 2023年重庆大学机械学院复试题重大机械复试真题
- CBCC中国建筑色卡色
- (完整版)简单儿童对比涂色画画-可打印(干货)
- GB/T 26480-2011阀门的检验和试验
- GB/T 21076-2017证券及相关金融工具国际证券识别编码体系
- 腹腔镜辅助下阴式子宫切除的课件
评论
0/150
提交评论