新闻中心

EEPW首页>嵌入式系统>设计应用> WinCE平台USB摄像头驱动开发流程

WinCE平台USB摄像头驱动开发流程

作者: 时间:2016-10-08 来源:网络 收藏

由于良好的性能、低廉的价格和灵活方便的特性,USB 摄像头正被广泛的集成到嵌入式系统中。例如,通过USB 摄像头WinCE系统可以很方便地得到实时图像,这对某些要求实时图象监控的嵌入式系统是一个很不错的选择。但是由于嵌入式硬件平台的多样性,以及WinCE对USB设备驱动开发只提供了底层支持,再加上许多摄像头厂商尚未提供WinCE下的USB摄像头驱动,这对初级开发人员在开发WinCE USB摄像头程序时是一个难点。

本文引用地址://m.amcfsurvey.com/article/201610/305937.htm

前段时间,公司委派我负责一个嵌入式项目,项目要求是在WinCE平台上集成USB摄像头驱动和视频采集程序。这个项目的关键是要集成USB摄像头驱动,并高效的把摄像头设备进行初始化以取得一幅完整的图像。幸好我以前开发过WinCE USB的主从设备的驱动程序。但虽然如此,我还是花了一些时间来调整系统的稳定性和可靠性。在这里我分享在这次项目实践中得到的经验和教训,希望大家能少走弯路。

一. 什么是USB设备驱动程序开发?

随着USB设备的普及,USB设备驱动开发在嵌入式系统变得越来越重要了。为了支持不同类型的硬件可以连接到WinCE平台上,微软提供了具有定制接口的流接口驱动程序模型。WinCE的USB外围设备一般是使用流接口驱动程序。流接口驱动程序是指通过系统提供的文件系统API与应用程序交互;WinCE内核系统会通过设备管理器来完成对流接口驱动程序的加载、卸载等管理工作;而流接口驱动程序则会通过调用USBD模块提供的接口函数实现与底层USB设备通信。因此,在进行USB设备驱动程序开发之前,我们必须先了解USB设备驱动的结构和分类。

(1)主机与USB摄像头的通讯结构

USB摄像头驱动程序主要是利用系统提供的底层接口配置设备和摄像头设备进行通讯。因此,WinCE的USB摄像头驱动分为两层:USB Client设备驱动程序和底层的WinCE函数实现层。而底层的函数层本身又由两部分组成,即通用串行总线驱动程序(USBD)模块和较低层的主控制器驱动程序(HCD)模块。HCD负责最底层的处理,USBD模块实现较高的USBD函数接口。因此,USB摄像头驱动主要是利用USBD接口函数和外围USB摄像头打交道。

一般来说,主机和USB外设之间的通讯是由在主机端通过USBD模块和HCD模块使用的PIPE访问一个通用的逻辑设备来完成。也就是说,USBD和HCD是一组抽象出来用于访问USB设备的逻辑接口,它们主要是负责管理USB外设的连接、加载、移除、数据传输和通用的配置。其中HCD是由主机控制和驱动的,是为USBD提供底层的功能访问服务。而USBD则是由USB总线驱动的,位于HCD的上层,是利用HCD的服务提供较高层次抽象的功能。

由于HCD和USBD都是面向一致的逻辑设备接口,因此如果嵌入式系统中拥有多种USB物理外设的话,那么就需要有唯一对应的外设驱动程序,也就是要有最上层的PIPE所连接的物理设备和USB设备驱动程序。有了对这个结构的认识,那么我们在进行USB设备驱动程序开发时首先要写的就是最上端的USB摄像头客户端驱动程序,在WinCE的样例程序中它也被称为USB Client Driver。它是工作于USBD之上,所以实际上我们的工作就变成了利用USBD提供的接口针对特定的物理设备来完成USB设备驱动程序。(见图)

(2)流驱动程序的分类和函数结构

WinCE驱动程序是介于内核系统和物理设备之间的一个代码层,它的主要作用是为内核系统提供一个接口用来操作不同的外围设备,包括物理设备和虚拟设备。驱动程序提供给内核系统的接口一般可以分为:本地驱动(Native Drivers)和流驱动(Stream Drivers)。我从这次项目实践中得到的经验是,WinCE下的所有驱动都可以归类到这两个里面,二者必居其一。

流驱动是指通过为内核系统提供流接口函数来实现驱动外围设备,如XXX_Init()、XXX_Open()、XXX_Read()、XXX_Write()、XXX_Close()等。这一类的驱动由Device Manager来管理,它是通过调用ActivateDeviceEx()函数来实现加载流驱动的。ActivateDeviceEx()的参数是注册表中相应的键,用来设定加载流驱动的属性,如Index、Order、Prefix等等。流驱动加载成功后,应用程序就可以通过调用CreateFile()、ReadFile()、WirteFile()等函数来访问流驱动设备了。而与流驱动相反,本地驱动提供给内核系统的不是标准的流接口,而是事先约定好的特定接口。因此不同的本地驱动设备,接口也是不一样的。在WinCE中,常见的本地驱动有LCD显示驱动、触摸屏驱动、鼠标和键盘驱动及打印机驱动等。从这里可以看出,本地驱动主要是涉及与人机界面相关的驱动。它们是由GWES来管理的,由于他们在注册表中有各自相应的配置信息,因此它们会在系统启动时自动加载。简单的说,就是本地驱动是由内核系统操作和调用的,一般的应用程序是不能访问和调用的。

在上一段描述中我们提到自动加载的概念,这是从驱动加载时间来区分的。主要分为两种:一是系统启动时自动加载;二是需要时才加载。一般来说,本地驱动都是在启动时自动加载的。而需要时才加载的方式,顾名思义就是想加载时才加载、想卸载时就可卸载。USB设备的驱动加载都是属于需要时才加载的驱动,例如USB摄像头的驱动程序。而从驱动的接口来看,USB摄像头驱动又属于流驱动接口。但相对于普通的流驱动接口,它增加了几个特有的接口函数:如USBDeviceAttach()、USBInstallDriver()、USBUnInstallDriver()等。在这次项目的调试中,我们发现需要时才加载的驱动程序有一个非常实用的好处,就是能在不修改嵌入式内核系统的情况下,应用程序可以动态加载该驱动以完成对硬件的操作,而操作完成后又可卸载其驱动程序以节省有限的内存。

(3)USB设备驱动程序入口点函数分析

大部分USB外围设备由于功能性的原因会更适合使用流接口驱动结构,所以一般都会采用加载式流接口驱动程序模型来开发USB设备驱动程序。流驱动是指通过流接口函数来实现驱动外围设备的。因此,编写流驱动程序实际上就是对各种流函数进行调用。

又由于USB摄像头驱动程序主要是和USBD打交道,所以我们必须详细的了解USBD提供的函数。让人感到幸运的是在WinCE下微软已经提供了通用串行总线驱动程序(USBD)模块、USBD接口函数全集、样本主机控制器驱动程序(HCD)模块。所以,我们只需要根据USB摄像头的硬件特性,利用USBD提供的不同函数就能实现流接口函数与外围摄像头设备的交互。就能大大的节省开发时间,从而能更快速地进行嵌入式开发。


上一页 1 2 下一页

关键词:

评论


相关推荐

技术专区

关闭