USB驱动程序
USB驱动程序(精选10篇)
USB驱动程序 第1篇
随着微机技术水平的日益提高,传统的计算机接口已经不能满足当前计算机高速发展的需求,计算机业迫切需要一种新的通用型、高速总线接口,通用外设接口标准USB就应运而生。
USB,全称是Universal Serial Bus(通用串行总线),是一种新型的、基于令牌的、高速的串行总线标准,由Compaq、Microsoft、Intel、IBM等七家公司共同开发的,旨在解决日益增加的PC外设与有限的主板插槽和端口之间的矛盾而制定的一种串行通信标准[3],自1995年在Comdex上亮相以来已广泛地为各PC厂家支持。现在市场上几乎所有的P C机器都配备了U S B接口,USB接口之所以能够得到广泛支持和快速普及,是因为它具备以下优点:
1)终端用户的易用性
●为接缆和连接头提供了单一模型
●电气特性与用户无关
●自检外设,自动的进行设备驱动和设置
●外设可以动态连接,动态重置
2)广泛的适用性
●适应不同设备,传输速率从几kb/s到十几Mb/s
●在同一线上支持同步、异步两种传输模式
●支持对多个设备的同时操作
●可同时操作127个物理设备
●在主机和设备之间可以传输多个数据和信息流
●支持多功能的设备
●利用底层协议,提高了总线利用率
3)同步传输带宽
●确定的带宽和低延迟适合电话系统和音频的应用
●同步工作可以利用整个总线带宽
4)灵活性
●直接发送一系列指定大小的数据包,允许对设备缓冲器大小进行选择
●通过指定数据缓冲区的大小和执行时间,支持各种数据传输率
●通过协议对数据流进行缓冲处理
5)健壮性
●在协议中使用差错处理/差错恢复机制
●完全实时热插拔
●可以对有缺陷的设备进行鉴别
6)与P C产业的一致性
●协议的易实现性和完整性
●与P C机的即插即用体系结构一致
●与现存操作系统有良好衔接的接口
7)性价比
●以低廉的价格提供传输速率为1.5 M b/s的子通道
●将外设和主机硬件进行了最优化的集成
●促进了低价格外设的发展
●廉价的电缆和连接头
●运用商业技术降低成本
8)可升级性
●体系结构的可升级性支持在一个系统中同时存在多个USB主机控制器
正由于上述优点,开发USB接口的设备已成为一种发展趋势。然而随着USB技术的迅猛发展,传统的U S B 1.1接口已经不能适应用户的需求,于是在1 9 9 9年在Intel的开发者论坛大会上又提出了USB2.0技术,使得U S B不仅支持1.5 M b/s的“低速”,传输和12Mb/s的“全速”传输,而且支持480Mb/s的“高速”传输,比USB1.1标准快40倍左右,速度的提高对于用户的最大好处就是意味着用户可以使用到更高效的外部设备,而且具有多种速度的周边设备都可以被连接到USB 2.0的线路上,而且无需担心数据传输时发生瓶颈效应。
2 USB驱动程序设计
一个完整的USB系统包括主机系统和USB设备。所有的传输事务都是由主机发起的。一个主机系统又可以分为以下几个层次结构,如图1所示。
U S B总线接口包括U S B主控制器和根集线器,其中USB主控制器负责处理主机与设备之间电气和协议层的互连,根集线器提供USB设备连接点。USB系统使用USB主控制器来管理主机和USB设备之间的数据传输,另外它也负责管理USB资源,如带宽等。应用软件不能直接访问U S B设备硬件,而通过U S B系统和USB总线接口与USB设备进行交互[1]。
U S B设备包含一些向主机软件提供一系列U S B设备的特征和能力的信息的设备描述符,用来配置设备和定位USB设备驱动程序。这些信息确保了主机以正确的方式访问设备。通常,一个设备有一个或多个配置(C o n f i g u r a t i o n)来控制其行为。配置是接口(I n t e r f a c e)的集合,接口指出软件应该如何访问硬件。接口又是端点(endpoint)的集合,每一个与USB交换数据的硬件就为端点,它是作为通信管道的一个终点。图1显示了一个多层次结构的通信模型,它表明了端点和管道所扮演的角色。
2.1 USB驱动程序结构
1)USB驱动程序体系结构
运行在核心态的USB驱动程序是基于WIN32驱动程序模型WDM(Windows Driver Model)的,它采用分层驱动程序模型,由USB总线驱动程序和USB功能驱动程序两部分组成,总线驱动程序由操作系统提供,用户只需要编写相应的功能驱动程序即可[2]。
2)处理流程
因为I/O管理器把每一个设备对用户程序都抽象成文件,所以用户程序通过调用文件操作API函数就可以实现与驱动程序中某个设备的通信。
用户程序发送的请求由I/O管理器转换为具有不同主功能代码的IRP(I/O请求包)发送给功能驱动程序。功能驱动程序接收该IRP,在回调程序中根据IRP中包含的具体操作代码,构造相应的U S B请求,把它放到一个新的IRP中,并把这个新的IRP传递给USB总线驱动程序。USB总线驱动程序根据IRP中所包含的USB请求块执行相应操作,再将操作结果通过IRP返还给功能驱动程序,功能驱动程序接收此IRP,将操作结果通过IRP返还I/O管理器。最后,I/O管理器将此IR P中的操作结果返回给应用程序。至此,应用程序对USB设备的一次I/O操作完成,其处理流程如图2所示。
3 USB设备驱动程序中关键代码实现
下面是以开发的A R M读写驱动程序为例,介绍U S B驱动程序中几个关键例程的实现。本驱动程序的主要功能是控制USB设备上的ARM并对ARM板进行读写操作。
1)初始化函数Driver Entry()
设备驱动程序与应用程序不同,没有main()或Win Main()函数,而是有一个名为Driver Entry()的入口函数,它通常完成一些初始化工作。当设备驱动程序被加载时,操作系统调用这个入口。
2)创建设备函数Add Device()
大多数的PDO都是在Pn P管理器调用该程序入口点时被创建的。插入新设备后,系统启动时,总线枚举器会搜索总线上的所有设备,自动寻找并安装设备的驱动程序,并由驱动程序中的处理Pn P功能模块自动处理Add Device()。本程序使用Create Device()函数创建设备对象,再使用Register Devicelnterface()函数将设备组成一个特定的设备接口,然后通过Attach Device To Device Stack()函数关联设备栈。
3)ARM的传输处理函数Usb Transmit()
该函数是实现本驱动程序功能的关键,它用来与ARM进行通信。分析发送的请求数据后根据命令的具体含义对ARM进行读写操作。应用层通过调用标准的AR M板函数来发送I/O请求。
4 结束语
随着支持USB的个人电脑的普及,大量支持USB接口外设的不断涌现,以及USB技术的发展和不断完善,因此基于USB驱动程序的开发也将成为这一发展趋势的重中之重。本文介绍了USB的通信模型,分析了基于WDM的USB驱动开发的关键所在,结合ARM驱动程序开发介绍了DDK开发环境的构建,最终结合实际系统完成了基于DDK的USB接口WDM驱动开发和调试。
参考文献
[1]盖素丽,常青.USB接口的驱动程序开发[J].河北省科学院学报,2005,(6):18-19.
[2]王志强,孙书鹰,孙世宇.USB设备驱动程序开发技术研究[J].中文核心期刊《微计算机信息,》2006,22(1):57-58.
关于usb鼠标、键盘驱动浅谈 第2篇
你可能会遇见这样一个不可思议的问题,usb鼠标(键盘)插上亮但就是不可以用,去设备管理器里边发现其前边有个黄色的叹号——找到问题了原来是驱动的问题,于是就联网自动更新驱动发现可以找到但是打开文件失败,对于您对计算机的了解,也许你已经用了好几个测试软件比如驱动人生,驱动精灵,鲁大师等等,都可以检测到该驱动没有装上,但令人不可意思的是就是装不上驱动。在确定鼠标可用的情况下,这个时候您也许就该想这是不是1硬件的问题(主板usb接口)2系统问题。但是真正的做一个正版的系统是很费劲费事的(后期处理特繁琐)。接下来您可以这样做更新主板芯片组驱动,南桥驱动试试等等,如果还是不管用。这时候您可以试试进入u盘系统看看鼠标会不会用,如果会的话 那就是系统的问题。这时候就做只能系统了(几乎可以确定是系统的缺陷性)。
出现这些问题很大程度上是精简版系统的缺陷性,在一点是尽量不要有软件优化系统,很肯能把某些东东优化没了。所以在这里建议大家在选择系统时候做好做原版系统。有自带的系统更好,精简版系统很可能出现一些未知错误。
USB驱动程序 第3篇
关键词嵌入式设备驱动端口
1引言
随着多媒体、网络技术的迅猛发展和后PC机时代的到来,利用嵌入式系统实现远程视频监控、可视电话和视频会议等应用已成为可能。为了实现这些应用,嵌入式Linux系统平台上摄像头驱动的加载是个很重要的环节。Linux环境下设计驱动程序,思想简洁,操作方便,功能也很强大;而USB摄像头性能良好价格低廉应用广泛,易于集成到嵌入式系统中。尽管如此,由于Linux支持函数少,只能依赖Kernel中的函数,有些常用的操作要亲自动手编写,并且调试也不方便,使得在Linux下驱动USB摄像头并不如Windows环境下那般轻松。
由于相关课题采用的是HH S3C2410板,因此,本文简单介绍基于嵌入式Linux2.4的USB摄像头驱动的开发与加载。
2Linux设备驱动的基本概念
设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。作为内核的一部分,设备驱动程序可以实现如下功能:
(1)对设备初始化和释放;
(2)把数据从内核传送到硬件和从硬件读取数据;
(3)读取应用程序传送给设备文件的数据和回送应用程序请求的数据;
(4)检测和处理设备出现的错误。
Linux内核就是通过驱动程序来同外围设备打交道的,因此,系统设计人员必须为每个设备编写驱动程序,否则设备无法在操作系统下正常工作。
3Linux2.4下USB摄像头驱动的实现
3.1USB驱动程序的框架
在Linux下,一个完整的USB驱动程序必须包含:USB Core(usbcore.o),USB主控制器驱动和USB设备驱动三个模块。其层次关系如图1所示。其中USB Core模块封装了支持USB主控制器及USB设备驱动的特定API(Application Program Interface),它通过定义一系列的数据结构、宏和函数(在/usr/include/linux/usb.h里声明)来抽象化硬件并掩蔽硬件的具体细节,使得系统对各种设备的访问都采用统一的形式,做到了硬件无关。同时主控制器驱动和设备驱动均将各自的功能及数据结构注册在usbcore.o中,之间通过URB(USB Request Block)关联起来,从而实现USB设备的信息传递。
由于在Linux系统中已内置了usbcore.o,另外在嵌入式系统中,芯片的厂商一般都会提供主控制器的驱动模块。我们仅需开发USB设备端的驱动模块。
3.2USB摄像头驱动的编写
驱动程序的编写是要构造一系列可供应用程序调动的函数,如:open、release、read、write等。在驱动程序中,首先要根据程序功能的需要,实现file_operations结构中的函数,file_operations的变量会在驱动程序初始化时注册到系统内部,不需要的接口初始化为NULL。当系统对设备操作时,驱动程序注册的file_operations结构中的函数指针会被调用。
Linux Kernel源码目录中driver/usb/usb_skeleton.c提供了一个基础的USB驱动程序,被称为USB骨架。通过他仅需要修改极少的部分,就可以完成一个USB设备的驱动。我们的USB驱动开发也是从他开始的。
Linux USB驱动程序需要做的第一件事情就是在Linux USB子系统里注册,并提供一些相关信息,例如这个驱动程序支持哪种设备,当被支持的设备从系统插入或拔出时,会有哪些动作。所有这些信息都将传送到USB子系统中。以下代码完成USB摄像头的注册和注销功能:
static struct usb_driver spca5xx_driver = {
owner = THIS_MODULE,
name = "spca5xx",
id_table = device_table,
probe = spca5xx_probe,
disconnect = spca5xx_disconnect
};
static int __init usb_spca5xx_init(void)
{
……
proc_spca50x_create();
……
if (usb_register(&spca5xx_driver) < 0)
return -1;
info("spca5xx driver %s registered", version);
return 0;
}
static void __exit usb_spca5xx_exit(void)
{
……
info("driver spca5xx deregistered");
……
proc_spca50x_destroy();
……
}
module_init(usb_spca5xx_init);
module_exit(usb_spca5xx_exit);
在spca5xx_driver结构中,变量name是一个字符串,他对驱动程序进行描述。probe和disconnect是函数指针。
当插入USB 摄像头时,调用spca5xx_probe( )函数:
static void *spca5xx_probe(struct usb_device *dev,unsigned int ifnum,const struct usb_device_id *id)
nlc202309010116
{ ……
memcpy(spca50x->vdev, &spca50x_template, sizeof(spca50x_template));
……
if (video_register_device(spca50x->vdev, VFL_TYPE_GRABBER, video_nr) <
0) {
err("video_register_device failed");
goto error;
}
……
}
其中spca50x_template定义为视频设备文件操作结构:
static struct video_device spca50x_template = {
name:"SPCA5XX USB Camera",
type:VID_TYPE_CAPTURE,
hardware:VID_HARDWARE_SPCA5XX,
open:spca5xx_open,
close:spca5xx_close,
read:spca5xx_read,
mmap:spca5xx_mmap,
ioctl:spca5xx_ioctl
};
spca5xx_probe( )函数主要用来向视频子系统注册摄像头,因为USB摄像头不仅是一种USB设备,也是一种视频设备,所以在其插入主机后,还必须向Linux的视频子系统注册,即发送一个命令给video_register_device。当摄像头从USB总线拔掉,设备指针会调用spca5xx_disconnect( )函数:
static void spca5xx_disconnect(struct usb_device *dev, void *ptr)
{……
usb_driver_release_interface(&spca5xx_driver,&spca50x->dev->actconfig->interface[spca50x->iface]);
spca50x->dev = NULL;
up(&spca50x->lock);
……} ;
spca5xx_disconnect ( )函数用来清除那些被分配了的所有私有数据,关闭URBS ,并且从视频子系统上注销掉自己。
3.3设备驱动程序中的一些具体问题
3.3.1内存操作
在设备驱动程序中用返回物理地址的kmalloc动态开辟内存而不是返回线性地址的malloc,或者用get_free_pages直接申请页。可以用kfree或free_pages释放内存。
内存映射的I/O口,寄存器或是硬件设备的RAM一般占用F0000000以上的地址空间。在驱动程序中不能直接访问,要通过内核函数vremap获得重新映射以后的地址。用vremap映射后的内存,不用时应用unremap释放,否则会浪费页表。
另外,很多硬件需要一块比较大的连续内存用作DMA传送。这块内存需要一直驻留在内存,不能被交换到文件中去。因为kmalloc最多只能开辟128KB-16B的内存,所以需要通过牺牲小部分系统内存的方法来解决。
3.3.2I/O端口
同硬件打交道离不开I/O端口,老的ISA设备经常是占用实际的I/O端口,在Linux下,操作系统没有屏蔽I/O端口,这意味着,任何驱动程序都可对任意的I/O端口操作,这样就很容易引起混乱,因此每个驱动程序应该能避免误用端口。
内核函数中的check_region(int io_port,int off_set)和request_region(int io_port,int off_set,char *devname)可以保证驱动程序做到这一点。
3.3.3中断处理
同处理I/O端口一样,要使用一个中断,必须先向系统登记。
int request_irq(unsigned int irq,void(*handle)(int,void *,struct pt_regs *),unsigned int long flags,const char *device);
其中,irq:是要申请的中断;handle:中断处理函数指针;flags:SA_INTERRUPT请求一个快速中断,0正常中断;device:设备名。
如果登记成功,返回0,这时在/proc/interrupts文件中可以看请求的中断。
3.3.4其他问题
对硬件操作,时序很重要。如果用C语言写一些低级的硬件操作,gcc往往会对程序进行优化,这样时序就错了。如果用汇编写,gcc同样会对汇编代码进行优化,除非用volatile关键字修饰。最保险的办法是禁止优化。这当然只能对一部分自己编写的代码。如果对所有的代码都不优化,会发现驱动程序根本无法装载。这是因为在编译驱动程序时要用到gcc的一些扩展特性,而这些扩展特性必须在加了优化选项之后才能体现出来。
4驱动加载
首次编译设备驱动程序如有报错,可根据内核下的Config.in.rej文件和Makefile.rej文件所保存的内容进行修改。
4.1解决方案
根据内核下的Config.in.rej文件和Makefile.rej文件所保存的内容进行依次修改Config.in和Makefile文件,具体如下:
将Config.in.rej文件中的
“dep_tristate'USB SPCA5XX Sunplus Vimicro Sonix Cameras'CONFIG_USB_SPCA5XX $CONFIG_USB $CONFIG_VIDEO_DEV”
nlc202309010116
加到Config.in文件中;
将Makefile.rej文件中的
“subdir-$(CONFIG_USB_SPCA5XX) += spca5xx
ifeq ($(CONFIG_USB_SPCA5XX),y)
obj-y += spca5xx/spca5xx.o
endif?”
加到Makefile文件中
4.2内核配置
首先,到/HHARM2410-R3/kernel下,打开Makefile文件,把ARCH?:= $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
CROSS_COMPILE =
改为
ARCH:= arm
CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-unknown-linux-
然后,执行make menuconfig,配置内核,只需选择如下两处:
Multimedia device --->
USB support --->
--- USB Multimedia devices
最后,执行make dep make modules,因为不需要内核映像文件所以把make zIamge略去。
4.3编译加载模块
[root@localhost ~]# cd spca5xx[root@localhost spca5xx]# make[root@localhost spca5xx]# depmod ./spca5xx.o[root@localhost spca5xx]# modprobe spca5xx
亦可将spca5xx.o拷贝至/lib/modules/''uname -r''/kernel/drivers/usb下,并在此目录下执行insmod spca5xx)
4.4测试
执行lsmod |grep spca5xx及ls -lh /dev/video0,根据打印查看设备驱动模块是否加载情况,如正常加载,显示如下:
[root@localhost spca5xx]# lsmod |grep spca5xx
spca5xx 606256 0 (unused)
videodev 8288 0 [spca5xx]
usbcore 78784 1 [spca5xx usb-storage hid usb-uhci ehci-hcd]
[root@localhost usb]# ls -lh /dev/video0
crw------- 1 root root 81, 0 2003-01-30 /dev/video0
成功加载摄像头驱动后,可通过spcaview查看摄像头采集的视频图片的效果。
5总结
简单论述了Linux2.4下USB摄像头驱动程序的开发以及编译加载,其中包括开发过程中和加载过程中容易遇到的问题和实际的解决方法。
USB设备驱动程序设计 第4篇
关键词:USB2.0,DriverStudio,设备驱动程序
引言
USB总线是1995年微软、IBM等公司推出的一种新型通信标准总线, 特点是速度快、价格低、独立供电、支持热插拔等, 其版本从早期的1.0、1.1已经发展到目前的2.0版本, 2.0版本的最高数据传输速度达到480Mbit/s, 能满足包括视频在内的多种高速外部设备的数据传输要求, 由于其众多的优点, USB总线越来越多的被应用到计算机与与外外设设的的接接口中, 芯片厂家也提供了多种USB接口芯片供设计者使用, 为了开发出功能强大的USB设备, 设计者往往需要自己开发USB设备驱动程序, 驱动程序开发一直是Windows开发中较难的一个方面, 但是通过使用专门的驱动程序开发包能减小开发的难度, 提高工作效率, 本文使用Compuware Numega公司的Driver Studio3.2开发包, 开发了基于NXP公司USB2.0控制芯片ISP1581的USB设备驱动程序。
USB设备驱动程序的模型
USB设备驱动程序是一种典型的WDM (Windows Driver Model) 驱动程序, 其程序模型如图1所示。用户应用程序工作在Windows操作系统的用户模式层, 它不能直接访问USB设备, 当需要访问时, 通过调用操作系统的API (Application programming interface) 函数生成I/O请求信息包 (IRP) , IRP被传输到工作于内核模式层的设备驱动程序, 并通过驱动程序完成与UBS外设通信。设备驱动程序包括两层:函数驱动程序层和总线驱动程序层, 函数驱动程序一方面通过IRP及API函数与应用程序通信, 另一方面调用相应的总线驱动程序, 总线驱动程序完成和外设硬件通信。USB总线驱动程序已经由操作系统提供, 驱动程序开发的重点是函数驱动程序。
USB设备驱动程序的设计
使用DriverStudio3.2开发USB设备驱动程序
该驱动程序的主要功能包括:从控制端点0读取规定个数的数据、向端点0发出控制命令、从端点2批量读数据、向端点2批量写数据, 驱动程序的开发采用Driver Studio 3.2驱动程序开发包及V C++6.0, 使用开发包中的向导程序DriverWizard就可以方便的生成驱动程序框架、模块及部分程序源代码, 开发者只需要在功能模块中加入自己的实现程序就能完成复杂的USB设备驱动程序设计, 下面介绍使用DriverWizard生成ISP1581驱动程序的过程:
(1) 启动Driver Wizard, 选择DriverWorks Project创造一个名为USBDIO的VC++项目;
(2) 在驱动程序类型中选择WDM Driver, WDM Function Driver, 在硬件设备所支持的总线类型中选择USB (WDM Only) , 在USB Vendor ID (厂商识别码) 中填写0741, 在USB Product ID (产品识别码) 中填写0821;
(3) 增加USB设
备端点, 设置端点2为批量输入/输出传输方式;
(4) 在驱动程序支持的功能项中选择Read、Write、Device Control、Cleanup;
(5) 选择自动产生批量读及批量写程序代码;
(6) 在I/O请求IRP处理方式中选择None, 即IRP不排队;
(7) 在接口的打开方式中选择Symbolic link:Usbdio Device, 即应用程序以符号链接名打开设备;
(8) 定义应用程序调用DeviceIoControl函数对WDM驱动程序通信的控制命令, 结果如图2所示。
(9) 最后选择完成并确认生成新的项目信息, 向导程序就会在usbdio目录中生成一个名为USBDIO的项目文件, 其中包括了ISP1581驱动程序框架、模块及部分源代码。
USB设备驱动程序的编程
在使用DriverWizard生成驱动程序框架、模块及部分程序源代码后, 开发者只需完成图2中三个控制代码所对应的三个功能模块的编程:模块USBDIO_IOCTL_ID_CODE_Handler的功能是从控制端点0读取数据, 模块USBDIO_IOCTL_TEST_COMMAND_Handler的功能是向控制端点0发送一个控制命令, 模块USBDIO_IOCTL_DMA_COMM AND_Handler的功能是向控制端点0发送一个要求USB设备进行DMA传输的控制命令, 下面是第一个模块的编程实例。
对象I包含了应用程序下传的IRP内容, 包括命令或数据等参数, 函数BuildVendorRequest用来分配并初始化一个用于厂商请求的URB (USB Request Block) , 该URB将作为下传IRP的一个参数, 通过函数SubmitUrb发送给总线驱动程序, 以便完成与硬件的通信。
在初始化URB时需要了解USB的传输方式及传输协议, 该功能使用了USB的控制传输方式, 该方式包括三个阶段:设置阶段、数据阶段和状态阶段, 其中数据阶段可选, 开发者主要关注设置阶段中的8个关键字节的定义, 8字节分成了5个字段, 定义了传输请求及相关信息, 这8个字节的格式如图3所示。
BmRequestType:1字节, 用来指定数据流动的方向, 请求的类型, 以及接收者。
bRequest:1字节, 用来指定请求。
wValue:2字节, 主机用来传输信息给设备, 开发者可以根据情况自己定义。
wIndex:2字节, 主机用来传输信息给设备, 开发者可以根据情况自己定义。
wLength:2字节, 包含数据阶段中接下来要传输的数据字节数目。
以上字段的应用已经在程序注释中标出, 在此不再赘述。
USB设备驱动程序的安装及调用
USB设备驱动程序的安装
驱动程序编译完成后会生成一个名为USBDIO.SYS的文件, 即USB设备驱动程序, 另外在使用向导程序WizardDriver生成驱动程序时会产生一个名为USBDIO.INF的驱动程序安装程序, 对此程序只需稍做修改就能正常使用, 具体是将类改为USB, 即Class=USB, 由于本驱动程序使用符号链接名打开设备, 所以删除ClassGUID选项, 注意设备标识符必需为:%Device Desc%=USB D IO_DDI, USBVID_0471&PID_0821, 其中0471是USB控制芯片的厂商识别码, 0821是USB设备标识码。
驱动程序安装过程是:将U S B设备加电, 连入计算机的USB接口, 这时候会看到Windows操作系统提示发现新硬件, 提问是否安装驱动程序, 选择是, 然后选择驱动程序所在文件夹, 选择文件USBDIO.INF即可完成安装。
USB设备驱动程序的调用
为了完成对驱动程序的调用, 笔者使用VC++6.0编写了USB应用程序包, 程序包共由五个功能模块组成, 用户通过调用这些模块即可方便的完成对U S B外设的控制及读写, 这些模块如下。
int CTRLReadData (unsigned char usbSelect, unsigned char*rbuffer, unsigned char numData) , 主要功能是读取ISP1581控制端点0发来的数据, 数据存放在缓冲区rbuffer中。
int CTRLSendTest Command (unsigned char usbSelect, unsigned short int testCommand) , 主要功能是发送测试命令, 变量testCommand定义了测试命令。
int CTRLSendDMACommand (unsigned char usbSelect, unsigned chard ma Di rection, unsigned char ramSelect, unsigned long dmaLength) , 主要功能是发送D M A传输命令, 变量dma D irection定义数据传输方向, ramSelect定义将要操作的USB外设的存储器, dmaLength定义了数据传输总数。
int DMARead (unsigned char usb Select, unsigned char*rbuffer, int len, int waitTime) , 主要功能是计算机批量读取ISP1581中的数据, 而ISP1581以DMA方式从外部R A M读取数据。
int DMAWrite (unsigned char usb Select, unsigned char*rbuffer, int len, int waitTime) , 主要功能是计算机批量写数据到ISP1581, 而ISP1581将以DMA方式写数据到外部RAM。
结语
USB设备驱动程序开发是Windows编程中较难的一个方面, 要求开发者不但要有良好的Windows编程知识, 还要掌握USB控制芯片工作原理、USB传输协议、USB固件等相关知识, 使用DriverStudio3.2进行USB设备驱动程序开发可大大减少工作量和工作难度, 笔者所设计的U S B设备驱动程序, 已经应用到某雷达的自动测试设备中, 驱动程序在计算机应用程序控制下可以顺利的发送各种测试命令, 批量输入或者输出大量数据, 达到设计要求。
参考文献
[1]武安河.WIindows2000/XP WDM设备驱动程序开发[M].北京:电子工业出版社, 2005.
[2]萧世文, 宋延清.USB2.0硬件设计[M].北京:清华大学出版社, 2006.
[3]王跃钢, 韩心中.基于WDM模式的USB设备驱动程序开发[J].微计算机信息, 2008, 22 (8-3) :305-307.
[4]马官营, 杨明, 吴晓琳.Windows2000通用设备驱动程序设计[J].计算机应用, 2003, 23 (6) :179-180.
USB驱动程序 第5篇
摘要:介绍了在Iinux系统下开发符合Video for Linux标准的USB摄像头驱动的方法,并对该标准提出“不间断采集”的改进思路,配合双URB、双帧缓冲等方法,提高采集速度。
关键词:Linux设备驱动 USB摄像头 Video for Linux 不间断采集
USB摄像头以其良好的性能和低廉的价格得到广泛应用。同时因其灵活、方便的特性,易于集成到嵌入式系统中。但是如果使用现有的符合Video for Linux标准的驱动程序配合通用应用程序,难以充分利用USB带宽,帧速不高,不易满足实时监控等要求。本文首先介绍在Linux系统下USB摄像头驱动编制的一般方法,然后说明在此基础上如何提高帧速。
USB驱动程序 第6篇
关键词:WDF,设备驱动程序,USB
0 引言
设备驱动程序是硬件设备连接到计算机系统的软件接口。在Windows系统中,任何设备都必须有相应的驱动程序才能正常工作,驱动程序的优劣直接关系到整个系统的性能和稳定性[1]。从Windows 2000开始,驱动程序以WDM为主,开发难度较大。为此,微软推出了新的驱动程序开发模型WDF(Windows Driver Foundation),在WDM的基础上进行了建模和封装,降低了开发难度,提高了驱动的稳定性和兼容性,是Windows 7的首先驱动模式。
1 WDF简介
WDF驱动程序框架由对象和事件回调例程构成,框架中所有的事物都由对象来表示,而所有的操作都被定义成一个事件(Event)或回调(Callback)。可以说,WDF是真正的基于对象的驱动开发,对每个对象封装了属性、方法和事件[2,3]。WDF还封装了驱动程序中的某些公共的驱动程序功能:如即插即用和电源管理等。如果用WDM编写即插即用和电源管理问题要上千行的代码,而且需要相当编程水平。WDF将即插即用和电源管理封装在对象之内,成为对象的缺省(默认)行为,程序更加健壮。
WDF还改变了操作系统内核与驱动程序之间的关系。不像WDM驱动程序,既要处理硬件,有要处理驱动程序与操作系统内核的交互,WDF将驱动程序与操作系统内核进行了分离,驱动程序与操作系统交互工作交给框架内封装的方法(函数)完成,驱动开发者只需专注处理硬件的行为即可。这不仅大大降低了工作量,还由于双方的分离,WDF驱动程序有很好的兼容性。WDF驱动程序可以同时支持Windows 2000、XP、Vista和最新的Windows 7系统,不用在代码中对系统进行判断,更不用每个系统各写一个驱动版本[2,3]。
WDF中包含了两套子框架:内核模式框架KMDF和用户模式框架UMDF。KMDF用来编写内核驱动,UMDF用来编写用户层驱动,两者由同一套对象模型构建,采用同一个基础承载[3]。本文主要介绍KMDF的设计与实现。
2 USB接口数据传输卡简介
在任意波形发生器项目的研制过程中,考虑到系统的反应速度,信号产生板是基于嵌入式计算机和PCI接口设计的。由于不能与笔记本相连,调试与展示十分不便。为此特别设计制作了一款基于USB接口的数据传输控制卡,通过USB2.0连接计算机,转换成SCSI68形式的自定义接口后与任意信号产生板相连。
USB数据传输卡的主要功能是:完成USB接口,将USB串行数据转换成32bit并行数据,并合成三个必要的控制信号(命令写CWR#、数据写DWR#和数据有效标志FLAG)。该卡由一片Philips的ARM处理器LPC2148FBD64、两片16bit的数据锁存驱动器IDT74162835构成(如图1所示)。LPC2148FBD64内嵌有USB接口内核,接收USB串行数据,并将数据拼接成两个16bit的并行数据,通过P1口产生IDT74162835的控制信号CK和LE,分两次经P0口将16bit的数据送到锁存驱动器中,再在P1口产生控制信号CWR#、DWR#和FLAG,将D[31..0]、CWR#、DWR#和FLAG连接到SCSI68,从而实现了USB-SCSI68串并数据的转换功能[4]。
3 WDF设备驱动程序的实现
编写设备驱动需要解决设备配置、数据操作和设备控制。设备配置就是初始化设备,首先要能识别设备,然后获取设备信息、状态,如对USB数据传输卡设备而言,需要知道他的设备描述、接口数量、端点数量和类型,然后是配置设备(设备、PNP、电源、IO等等),并让总线为设备分配带宽等系统资源。数据操作可以被分为两大类:输入和输出,就是把数据正确地输入或输出。设备控制包括很多操作,如USB数据传输卡设备初始化,管道初始化,接口设置等。
WDF设备驱动程序本质上只是一个入口函数(Driver Entry)和多个回调函数的集合。回调用于响应KMDF接收到的IO请求和其他驱动特定功能函数。驱动可以创建多个IO请求队列,并把接收到的IO请求放入队列。最小的内核驱动只包含入口函数和回调函数,KMDF会处理大部分的Pn P和电源管理,如果使用KMDF的默认处理,驱动完全不需要干预这些IO请求,甚至连向下层驱动栈转发都由KMDF自动完成。设备特定的东西越多,驱动提供的功能就越多,所需要的代码也越多。
WDF驱动程序的标准入口函数是Driver Entry,与上一代驱动模型WDM不同,WDF的Driver Entry只需要编写创建和初始化WDFDRIVER对象,告诉WDF框架处理添加新设备连接的回调函数。其它的工作则由WDF框架完成驱动程序的默认初始化。用户只需在默认初始化的基础上,增加自定义的初始化,如果没有,则WDF的默认初始化即能保证驱动程序的正常稳定运行。
Driver Entry调用成功后,驱动文件被加载到系统内存空间,并开始设备的初始化过程。Usb Data Trans Add是一个Evt DriverDevice Add类型的回调函数,也是在设备初始化过程中,第一个被框架调用的回调函数。在Usb Data Trans Add中完成:
(1)创建框架设备对象WDFDVICE;
(2)创建设备对象的符号链接或设备接口,供用户程序使用;
(3)创建框架队列;
(4)设置各种事件的回调例程,如Pn P例程、电源管理例程等。设置电源策略,一般设备必须支持工作状态D0和关闭状态D3两种电源状态,D1和D2是可选的休眠状态。
第二个被框架调用的函数是Usb Data Prepare Hardware,它是Evt Device Prepare Hardware类回调函数,主要任务就是为设备申请必要的系统资源,为以后的设备操作做好准备。在这个函数里创建了USB设备对象,进行USB接口配置等。
设备配置好以后就可以向USB设备发送控制命令以及进行读、写等操作。发送控制命令是由应用程序通过调用Device IOControl实现。应用程序的请求被保存在请求队列中,并在Evt Io Device Control函数中被处理。在这个函数里构造并发送控制命令,控制命令有规定的格式,称作Setup包,共7个字节,表示了命令属性、命令ID、命令对象等信息,所以需要初始化一个WDF_USB_CONTROL_SETUP_PACKET结构体。要特别注意的是,不要把设备不认识的控制命令发给设备,那样设备返回STALL握手信号,总线可能因此将你的驱动挂起,直到物理设备移除总线。
读、写操作由应用程序通过调用Read File、Write File函数实现,并在Device Io Read、Device Io Write函数中被处理。Device Io Read首先获取应用请求的输出缓冲内存对象,然后构造一个读请求并设置完成函数,最后发送请求,在完成函数里检查读数据是否已经完成,若没有就再次进行读传输。类似的,Device Io Write首先获取应用请求的输入缓冲内存对象,然后构造一个写请求并设置完成函数,最后发送请求,在完成函数里检查写数据是否已经完成,若没有就要再次进行写传输。
4 结语
驱动程序写好后,在编译环境WDK 1.9中编译即可得到SYS文件和INF文件。实验测试表明,我们开发的USB数据传输卡可替代PCI卡工作,在SCSI68端口可以获得大约12MB/S的32bit并行数据。总而言之,WDF驱动程序模型是新一代驱动程序模型,KMDF框架为开发内核模式驱动程序提供了一个面向对象、事件驱动的开发框架,极大地简化了设备驱动程序的开发,提供了比WDM更健壮、更灵活、可扩展、可诊断的驱动程序框架。
参考文献
[1]武安河,邰铭,于洪涛.WDM设备驱动程序开发[M].电子工业出版社,2003.
[2]武安河.Windows设备驱动程序WDF开发[M].电子工业出版社,2009.
[3]Penny Orwick,Guy Smith.Developing Drivers with the Microsoft Win-dows Driver Foundation[M].Microsoft Press,2007.
USB驱动程序 第7篇
由于现在大多数计算机没有并行口而具有多个USB接口, 因此很多并行口设备无法和计算机直接连接使用。利用基于单片机STC11F32XE的USB转ECP模式并行口可以连接其他ECP模式并口设备, 以达到让具有ECP接口的设备可以和没有并口的PC进行数据通信的目的。并口采用的是IEEE 1284-A接口, USB接口驱动芯片采用P h i l i p s半导体公司的PDIUSBD12, 该芯片的数据端口D0-D7接单片机的P0口, 引脚WR_N、RD_N、及A0分别接单片机的P3.6、P3.7、P3.5引脚。整个硬件电路图如图1所示。当USB设备硬件设计完成之后, 接着就必须根据硬件特点和需要完成的功能, 设计出合乎产品的USB驱动程序, 否则, 设备将无法被PC机识别, 不能正常使用。
2 WDM型的USB驱动程序结构
U S B设备的驱动程序是一种典型的W D M驱动程序。W D M驱动程序是分层的。对于USB设备驱动程序来说, 其驱动程序包括两个层次:设备 (功能) 驱动程序层和总线 (底层) 驱动程序层。USB底层驱动程序由操作系统提供, 不要开发者自己编写, 它位于USB功能驱动程序的下面, 负责与实际的USB硬件打交道, 实现复杂而繁琐的底层通信;USB功能驱动程序必须要由开发者编写, 它不与实际的USB硬件打交道, 是把包含URB (USB Request Block, USB请求块) 的IRP发送到USB底层驱动程序, 来实现对USB设备信息的发送和接收。 (图2) 给出了USB驱动程序的结构模型。
3 USB驱动开发编程环境的建立
开发一个W M D驱动程序, 必须要搭建合适的开发环境以此来减小开发难度。对于W D M驱动的开发, 一般必须使用的软件是VC++6.0和DDk (Driver Development Kit, 驱动程序开发工具包) 。但为了进一步降低开发难度, 选择使用了第三方驱动开发工具--Driver Studio。它以类的方式对D D K进行封装, 可以十分容易地利用它提供的向导来产生一个必需的驱动程序框架。
一般首先安装V C++6.0, 接着安装DDK, 如果需要的话, 还可以安装Windows SDK来辅助开发, 最后安装Driver Studio 3.2。因为Driver Studio的类库要使用D D K库函数, 所以在安装好D r i v e r Studio之后必须首先要编译出一个库文件, 否则会提示找不到库文件vdw_wdm.lib等错误。编译该库文件的步骤如下:启动VC++6.0, 找到并打开Driver Studio3.2安装目录下的vdw Libs.dsw工程文件, 然后选择Driver Studio->DDK Build Settings, 在弹出的对话框中设置DDK的安装路径和运行的操作系统。然后选择菜单Build->Batch Build, 要根据驱动运行的平台来选择对应的工程文件, 这里选择了x 8 6对应的工程, 正确选择之后, 单击Rebuild All按钮, 开始编译库文件。这个类库只需编译一次, 以后开发其他的驱动就不必再次编译了。
4 USB驱动创建方法及步骤
该驱动程序的主要功能包括:端点0采用控制传输, 可以保证传输过程中的数据的完整性和正确性, 主要负责USB枚举过程中的数据的读写。另外, 又增加了端点1和端点2。端点1采用中断传输, 这种传输主要用在数据量不大, 但对时间要求较严格的设备中。因此, 模块满足了实时性的特点;端点2采用批量传输, 该种传输通常用在数据量大、对数据的实时性要求不高的场合中, 利用该方式可以完成大量数据的快速传输, 可以与高速的ECP并行口相匹配, 因此, 模块满足了高速数据传输的要求。
单击VC菜单栏下的Driver Studio菜单项, 选择Driver Wizard菜单, 会出现一个驱动向导对话框。单击Start a new Driver Project将创建一个新的驱动工程。然后按照向导生成该驱动程序的框架。具体步骤如下: (1) 设置工程名和路径。在弹出的对话框中, 设置工程名为Usb To ECP、路径为D:。 (2) 选择驱动工程的类型。在对话框中选择WDM Driver, 驱动框架选择Driver Works C++Framework。 (3) 选择W D M驱动类型。在弹出的对话框中选择WDM Function Driver。 (4) 选择驱动总线的类型。在对话框中选择为U S B总线, 然后在分别设定USB Vendor ID和USB Product ID。 (5) 设置USB的端点资源。单击A d d增加端点。这里增加4个端点, Pipe Name分别是Ep1_In、Ep1_Out、Ep2_In和Ep2_Out。其中Ep1_In和Ep1_Out选择中断传输, 端点地址均为1, 传输方向分别为输入和输出, 最大包长为8字节, 最大传输大小为4096字节。Ep2_In和Ep2_Out选择批量传输, 端点地址均为2, 传输方向分别为输入和输出, 最大包长为64字节, 最大传输大小为40960字节。 (6) 选择需要处理请求类型。这里选择I R P_M J_D E V I C E_C O N T R O L、I R P_M J_R E A D和I R P_M J_W R I T E。它们分别与API函数D e v i c e I o C o n t r o l、Read File和Write File一一对应。 (7) 设备I/O操作方式。配置I R P_M J_R E A D和I R P_M J_W R I T E的缓冲方式分别为Buffered。另外还需要增加4个IO Control的控制代码:E P 1_R E A D、E P 1_W R I T E、EP2_READ、EP2_WRITE。打开方式选择Interface。 (8) 添加注册表项。可以根据自己需要增加, 这里增加了一个设备名称。 (9) 设置电源管理。选择Device requires an inrush of power at startup, 说明该设备启动时需要大电流, 这样做的目的是防止相同的设备同时上电, 减少对电源的冲击。步骤10-13按默认配置即可。
5 驱动的编程
USB驱动程序的编程最主要的就是编写端点1和端点2的数据处理函数, 其中主要编写的是Usb To ECPDevice类成员函数Read () 、Write () 、及Device Control () 中调用的4个Io Control () 函数。
R e a d () 函数对应着W I N 3 2A P I的Read File函数, 其参数通过KIrp I传递过来。因为端点1指定的缓冲方式为Buffered方式, 所以调用K I r p类的成员函数I.Buffered Read Dest () 来获取保存数据的缓冲区地址, 调用I.Read Size () 来获取读到的数据长度。如果获取到的缓冲区地址为N U L L, 则说明参数无效, 则以U S B_S T A T U S_I N V A L I D_P A R A M E T E R来完成该I R P, 然后返回U S B_S T A T U S_I N V A L I D_P A R A M E T E R。若读取的字节数是0, 就直接完成该IRP, 不需要进行数据处理。接着创建一个URB来完成数据的处理。因为端点1采用的是中断传输, 所以必须创建一个中断传输的URB并提交它, 端点管道KUsbPipe类提供一个创建中断传输U R B的函数BuildInterruptTransfer。这样底层的USB总线驱动程序就会负责从端点1读取数据, 当完成数据的读取后, 提交相应URB的函数就会返回。当URB创建成功后, 利用KUsbPipe类的成员函数SubmitUrb () 来提交这个URB, 否则返回资源不足的错误信息。SubmitUrb () 函数返回后, 可以用URB的成员变量Transfer Buffer Length来获取实际读到的字节数, 最后删除创建的U R B。
Write () 函数的处理方法与Read () 函数的方法非常相似, 不同之处在于利用KIrp类I的成员函数Buffered Write Source () 和W rite Size () 来分别获取缓冲区的地址和传输的字节数。另外, 函数EP1_READ_Handl er () 和EP1_WRITE_Handler () 的实现与Rea d () 和Write () 函数基本是一样的, 略有不同。
端点2的EP2_READ_Handler (KIrp I) 和EP2_WRITE_Handler (KIrp I) 与端点1的EP1_READ_Handler (KIrp I) 和EP1_WR ITE_Handler (KIrp I) 处理方式几乎是一样的, 主要的不同是在创建URB时要用到创建批量传输URB的函数Build Bulk Transfe r () , 其参数及意义与Build Interrupt Transfer () 相同。
6 驱动的安装
在对端点1和端点2编程完成之后, 然后对其进行编译, 如果没有错误, 可以看到编译报告中有一行“M O D U L E=.objfrei386Usb To ECP.sys”, 这个就是所要的驱动文件, 另外, 在目录下还产生一个inf文件, 其也是安装驱动时需要的一个重要的文件, 它里面有一些重要的安装信息, 可以根据需要进行修改。一般主要是对inf的Stings进行修改, 表1给出了该驱动的Strings段的几个重要属性的修改。
将该设备与PC机连接, 系统会提示安装驱动, 首先指定驱动安装所要使用的inf文件所在的位置, 该inf文件可以在驱动工程目录的driver目录下找到, 是由向导自动生成的。然后选择安装驱动所需要的U s b T o E C P.s y s文件, 该文件在D:Usb To ECPdriverobjfrei386下。正确安装驱动之后, 打开计算机的设备管理器, 将会看到该USB设备。如下图3所示。打开图3中的Class for Bin Bin Usb devices下的Bin Bin Usb Device属性, 选择相应标签, 将会看到如下图4的驱动信息。
7 结语
USB设备驱动的开发是设备开发过程中必不可少的一项任务。通过研究利用VC++、DDK和Driver Studio对USB驱动程序的设计方法, 成功地设计了基于单片机的USB转并口设备的驱动程序。通过测试, 使用该驱动的USB转并口设备运行稳定, 达到了预期的效果。这种USB驱动的设计方法简化了开发难度, 开发的驱动稳定可靠, 必将受到USB设备开发者的广泛关注, 同时也给其他的基于W D M驱动的开发提供一个新途径。
参考文献
[1] 荣佳波, 常明志, 井科伟, 杨少勇.USB 设备的WDM驱动程序设计[J].应用科技, 2004, 31 (3) ;39-41.
USB驱动程序 第8篇
1 系统软件架构
PC上软件分为三层:
(1) Application:应用层。
(2) USBIO.dll:链接库。
(3) USB Driver:驱动层。
单片机的程序包含四个部分:
(4) Application:应用层。
(5) Application Interface:用户接口层, 提供库内核和应用层之间的接口。
(6) USB Library Core:USB库内核层, 该层管理使用USP IP硬件和USB标准协议的直接传输。
(7) Firmware Library:STM32F10xxx固件库。
在单片机部分, 由于ST公司提供了USB库及STM32F10xxx固件库, 开发起来较为方便, 而PC部分由于需要自行开发驱动, 对于大多数应用层的开发者来说, 存在较大难度, 因此本文主要描述PC端的程序设计。
2 驱动层和链接库
这两层采用C++结合WINDDK和Driver Studio工具包来开发, 开发环境为VC6.0。
首先, 利用Driver Studio通过代码向导生成这两层源代码的框架, 其中有两步需要格外注意:
(1) 设置Vendor ID和Product ID, 必须与USB设备固件程序里的设备描述符一致。
(2) 添加端点, USB所有的通信都是基于端点, 这里我们使用端点2接收数据, 通过端点3发送数据。
按照向导配置完后, 就可以生成代码框架, 该框架已经包含了进行基础通信所必要的代码, 只需要针对具体应用作一定优化即可。
3 应用层
应用层采用MFC开发, 主要功能是对设备进行参数配置和数据回收, 不同的指令会采取不同的读取模式, 例如本应用中“读取文件总数”、“读取文件目录”、“读取已存储页数”这三个功能项通信数据量小, 于是采用了同步模式, “回收文件”和“回收全部”则通过新建线程在后台完成通信, 前台显示回收进度条, 通信部分核心代码如下:
4 结语
基于VC的USB接口通信程序设计 第9篇
随着信息技术的迅速发展,数据采集和处理技术广泛应用于雷达、通信、遥测、遥感等领域。而在早期的计算机系统上通常使用串口或并口来发送数据,每个接口都需要占用计算机内部很多的资源,传统的接口一般采用PCI总线或RS-232串行总线。PCI总线有较高的传输速率,可达132 Mbit/s,也可以即插即用,但是它们的扩充槽有限且插拔不方便;RS-232串行总线连接比较方便,但是传输速率太慢,不易用于高速传送数据和传送大量数据。USB(通用串行总线)集中了PCI和RS-232串行总线的优点,具有方便的即插即用和热插拔特性以及较高的传输速率,因此,将USB技术应用于数据采集是非常合适的,可以达到数据采集系统的高速度处理。目前,USB已经推出了其协议的2.0版本,速率高达480 Mbit/s。
本文研发了一套基于USB接口的数据采集系统,整个系统的设计涉及到硬件、设备固件(Firmware)、USB设备驱动程序及客户应用软件。下面分别加以说明。
1 USB接口芯片
本文介绍的USB数据采集系统采用了Cypress公司EZ-USB FX2系列的CY7C68013-128AC芯片,它同时集成了8051微控制器和USB2.0收发器,在提高集成度的同时也加快了数据传输的速度。在系统中,CY7C68013-128AC既是数据采集控制器又是USB控制器,EZ-USB FX2系列有3种型号:CY7C68013-56PVC、CY7C68013-100AC、CY7C68013-128AC。该系列的芯片都是针对USB2.0的,并且与USB1.1兼容。其中,CY7C68013-128AC是128脚,TPQF封装,功能非常完善,与另外两种相比,主要是增加了16位地址总线和8位数据总线以及更多的IO口,因此,CY7C68013-128AC的可扩展性最好。图1是该芯片的内部结构图[1]。
2 USB的固件和驱动程序设计
2.1 固件
固件是储存在程序内存中的代码,它使得USB接口芯片与主机和外设中其他电路能够通信。Cypress公司给出了一个固件库和固件框架(Frame Works),均是用Keil C51开发的。固件库提供了一些常量、数据结构、宏、函数来简化用户对芯片的使用;固件框架实现了初始化芯片、处理USB标准设备请求以及挂起状态下的电源管理等功能。该框架不添加任何代码,编码后产生的 .HEX文件载入芯片就能与主机进行基本的USB通信,只是不能完成特定的任务。对于用户而言,主要的工作就是选择适当的传输方式,添加需要使用的端点(Endpoint),考虑到本系统要求实现一定数量数据的快速采集,并要迅速地将采集到的数据传输和进行分析处理,并且对数据的完整性要求较高,我们采用了块传输方式(Bulk Transfers),在TD-Init( )函数中添加初始化代码,亦即选择块传输方式和选择端点2、6分别为输出、输入端口,在TD-Poll( )函数中添加功能代码,以实现发送和接收数据功能,关键代码分别如下:
2.2 USB设备驱动程序
USB设备驱动程序主要是使操作系统能够识别USB设备,建立起主机端与设备端之间的通信,它们之间的通信是通过Windows提供的API函数实现的,这些函数可以控制显示器、处理信息、访问存储器、读写磁盘和其他设备。
图2是USB设备驱动程序的整体结构图。
USB设备驱动的整体结构包括如下5个主要部分:USB应用程序接口、USB设备驱动函数、USB中断服务程序、USB回调接口程序、USB标准事件处理程序。
2.2.1 USB应用程序接口
USB应用程序接口主要功能是对USB驱动器进行软硬件初始化、打开端口、关闭端口、读端口、写端口和端口控制操作。当设备驱动器装入系统设备表时,I/O系统就调用该应用程序接口。
USB应用程序接口的一个例程主要包含:
a)对 USB端口安装、初始化和硬件配置(USB_init( ))。初始化步骤为:将USB设备驱动器安装到I/O系统设备表中,获取USB控制器使用的中断号,初始化USB驱动器数据结构与USB端口状态寄存器,启动USB标准事件处理程序。
b)打开USB端口(USB_open( ))。USB_open函数允许应用程序打开一个USB端口和选择DMA数据传输方式。
c)关闭USB端口(USB_close( ))。USB_close函数允许应用程序关闭一个端口,并关闭DMA通道。
d)对USB端口进行读操作(USB_read( ))。USB_read函数允许应用程序从输出端口或控制端口读取一定量的数据。
e)对USB端口进行写操作(USB_write( ))。USB_write函数与USB_read函数功能类似,允许应用程序写数据到输入端口或控制端口。
f)对USB设备进行I/O控制操作(USB_ioctl( ))。
2.2.2 USB中断服务程序
USB控制器产生单一中断,多个端口共享。每个端口产生ACK、NACK/ERROR中断;输出端口产生接收零字节包或短包中断;控制端口0接收设置包时产生中断;USB控制器产生USB事件中断,如帧起始(SOF)、挂起、恢复和复位。先识别发生USB中断的类型以清除中断产生的条件,再读USB状态寄存器,获取当前配置、接口或帧起始时间戳状态信息,最后向USB控制器消息队列或回调函数的接收消息队列发送中断消息。
2.2.3 USB标准事件处理程序
USB驱动器初始化后,启动USB标准事件处理程序负责处理枚举过程和异步USB事件。事件处理程序使用控制端口0,直到完成枚举过程。当USB应用程序处于非活动状态时,除控制端口0以外端口均不可访问。事件处理程序在端口0上执行控制操作,响应USB标准请求,并负责通知USB应用程序枚举完成和接口活动状态,USB事件通过回调接口传递到USB外设应用程序。当对USB端口枚举操作完成,USB应用程序就可打开并使用USB端口。
3 客户应用软件
开发系统应用软件的底层,需要极好的兼容性和稳定性。对于广大用户而言,与系统的交互是通过应用程序实现的,因此,如何设计出运行效率高、界面友好、稳定性高的应用程序是至关重要的因素。VC++是开发Windows应用程序的主流开发工具,充分利用它的面向对象特性的C++和功能强大的MFC来开发专业级的应用程序,MFC是一个强大的、扩展的C++类层次结构,它能使开发Windows 应用程序变得更加容易,而且在整个 Windows 家族中都是兼容的。LabWindows/CVI是以ANSI C为核心的交互式虚拟仪器开发环境,它将功能强大的C语言与测控技术有机结合,具有灵活的交互式编程方法和丰富的库函数。本设计就是采用Visual C++6.0和LabWindows/CV提供的Graph控件来开发应用程序的,应用程序的主要功能有:打开/关闭USB设备,检测USB设备,实现向USB设备发送指定数量的数据。
下面是各部分的一些代码及说明:
1)查找、打开USB设备
2) 线程(Thread)
线程就是程序中单独顺序的流控制。线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程不拥有系统资源,只有运行必须的一些数据结构;它与父进程的其他线程共享该进程所拥有的全部资源。图3是线程的状态转换图。
线程被分为两种:用户界面线程和工作线程(又称为后台线程)。本程序设计主要使用工作线程来执行数据的读写操作等,它与用户界面线程的区别是不用从CWinThread类派生来创建,对它来说最重要的是如何实现工作线程任务的运行控制函数。
对于工作线程来说,启动一个线程,首先需要编写一个希望与应用程序的其余部分并行运行的函数,如Fun( ),接着定义一个指向CWinThread对象的指针变量*pThread,调用AfxBeginThread(Fun,param,priority)函数,返回值赋给pThread变量的同时启动该线程执行上述Fun1( )函数,其中Fun是线程要运行的函数的名字,亦即控制函数的名字,param是准备传送给线程函数Fun的任意32位值,priority是定义该线程的优先级别,是预定义的常数,可参考MSDN。
本程序设计中的关键代码如下:
4 实例
本例中使用了LabWindows/CVI的Graph图形显示控件,用来显示各类信号波形,如普通连续波信号波形、单载频矩形脉冲信号波形、调频(非线性调频)脉冲压缩信号波形和二相编码波形等。图4为各类信号波形图。这些信号均为数据采集系统的测试信号,可由DDS(直接数字频率合成器)芯片AD9858实现。
将图4中各类信号波形的频率、宽度、幅度和载频信号频率等参数读出来,分别进行一些计算,将计算出的结果通过USB口传送到DDS来产生波形;其他公共参数如“DDS时钟频率”根据实际采用的时钟频率设置。比如线性调频信号,一般关心的是一个信号的带宽、起始频率和调频斜率这3个值。这3个参数其实就是信号波形中的起始频率fs、终止频率f0和持续时间t,它们是等价的,现在把这些参数的值从测试信号波形中读出来,然后代入下式:DFRRW(8(f0-fs)/t)231/SCLK[2]。式中:SCLK是DDS的时钟频率,它的值设为1 GHz;DFRRW为步进频率斜率控制字,它的值设为1,代表每8 ns更新一次。最后把计算出的DFTW(步进频率调节字)值通过USB口传送到DDS。
另外,二相编码的实现是通过控制DDS的POW(相位补偿字)来实现的,通过改变PS0和PS1的值,就可以改变信号的相位,而且相位的改变可以是绝对调相和相对调相。这里使用了4个工作组,其中2个工作组的POW为0,另外2个工作组中的POW为π。将上面测试信号波形中的参数读出来,代入POW=214W/360中,其中W为波形的相位值,再把计算出的POW值通过USB口传送到DDS即可。
5 结束语
本设计中使用的USB2.0作为接口部分,具有接口简单、传输速率高和即插即用等特点;应用程序充分利用VC的MFC框架的比较丰富的资源和LabWindows/CVI丰富的库函数,在进行数据采集和控制时,具有界面友好、兼容性和工作可靠、稳定等特点。经实际运用证明,本设计合理,使用方便,在数据采集过程中,很容易实现高速度传输数据并进行分析处理。
参考文献
[1]王奕.基于USB2.0的数据采集系统的设计与实现[J].电子工程师,2002,28(12):15-17.
[2]张永强,杨文革,张若禹.基于AD9858的线性调频源设计[J].国外电子元器件,2004(8):57-59.
[3]陈天华.面向对象程序设计与Visual C++6.0教程[M].北京:清华大学出版社,2006.
[4]胡晓军,张爱成.USB接口开发技术[M].西安:西安电子科技大学出版社,2005.
[5]黄维通.Visual C++面向对象与可视化程序设计[M].北京:清华大学出版社,2003.
USB驱动程序 第10篇
在设计开发一个USB外设的时候,开发者主要需要编写3部分的程序:固件程序、USB驱动程序和客户端应用程序[1]。当把设备连接到主机上(USB连接线插入插孔)时,上位机可以发现新设备,然后建立连接。因此,编写固件程序的一个最主要的目的就是让Windows可以检测和识别设备。固件程序可以在Keil C51软件环境中,用C语言开发。Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,Keil C51软件提供了大量的库函数和功能强大的集成开发调试工具,使用的是全Windows界面,具有方便实用的特点[2]。另外,Keil C51生成的目标代码效率非常高,多数语句生成的汇编代码很紧凑,容易理解。因此,本文考虑采用此方法开发PDIUSBD12芯片的USB固件程序。
1 固件程序主要完成的工作
固件设计的目标就是完成主机与设备之间的命令与数据传输与转换,使PDIUSBD12在USB上达到最大的传输速率[3]。它的操作方式与硬件联系紧密,包括USB设备的连接、USB协议、中断处理等。在系统中,当PDIUSBD12从USB接收到一个数据包,就对CPU产生一个中断请求,CPU立即响应中断。在ISR(中断服务程序)中,固件读取数据,并将数据值保存到循环数据缓冲区,随后置相应事件的标志位,CPU继续前台程序,检测事件标志,执行完成相应的事件任务[4,5]。
USB单片机固件程序通常由3部分组成:初始化单片机和所有的外围电路 (包括PDIUSBD12);主循环部分:这部分是可中断的;中断服务程序,可以中断执行[6]。根据USB协议,任何传输都是由主机开始的,这样单片机作它的前台工作,等待中断。主机首先要发令牌包给USB设备(这里是PDIUSBD12),PDIUSBD12接收到令牌包后就给单片机发中断,单片机进入中断服务程序,首先读PDIUSBD12的中断寄存器,判断 USB令牌包的类型,然后执行相应的操作,因此,USB单片机程序主要就是中断服务程序的编写,在USB单片机程序中要完成对各种令牌包的响应。
单片机与PDIUSBD12的通信主要是靠单片机给PDIUSBD12发命令和数据来实现的。PDIUSBD12的命令字分为3种:初始化命令字、数据流命令字和通用命令字[7]。PDIUSBD12给出了各种命令的代码和地址,单片机先给PDIUSBD12的命令地址发命令,根据不同命令的要求再发送或读出不同的数据。因此,可以将每种命令做成函数,用函数实现各个命令,以后直接调用函数即可。
2 固件程序的流程及结构
USB设备启动流程如下[8]:
(1) USB设备接入USB口,发出连接USB命令;
(2) 主机发出读设备描述符2次;
(3) 主机根据设备描述符(厂商ID、产品ID),启动相应设备驱动程序;
(4) 设备驱动程序初始化USB设备:
① 读设备描述符;
② 读配置描述符;
③ 选择接口、端点(管道),确定传输方式。
在编写USB的单片机固件程序时,单片机的中断应设置为电平触发,中断后一定要读上次传输状态寄存器(命令40H~45H),以清除中断寄存器中的中断标志,这样PDIUSBD12的中断输出变回为高电平[9]。
PDIUSBD12固件编写采用分层结构简洁且易于修改和测试,既增加了代码的可读性,又增加了程序的通用性。PDIUSBD12固件的开发一般都是在周立功单片机公司提供的固件源码的基础上做相应的修改。由于该固件采用分层分模块的结构,在做移植的时候只要修改部分代码就可以运行于特定的平台,比较方便。
固件程序采取如图1的积木式结构[7]。
2.1 硬件提取层
epphal.c文件是固件中的最底层代码,由于在具体应用时所提供的硬件平台都是不同的,因此该文件必须进行修改以适应当前应用。该文件里主要包含了读写PDIUSBD12寄存器的函数,PDIUSBD12芯片各控制线与单片机I/O口的连接等。
读写PDIUSBD12主要有2种方式:多路复用地址/数据总线方式和A0地址位方式。不同的方式其电路连接完全不同,因此其读写函数也完全不同。本处采用多路复用地址/数据总线方式,即用地址/数据总线的最低位标识总线上是数据还是命令,1代表命令,0则代表数据。
2.2 D12命令接口
d12ci.c文件中定义了一套访问D12 功能的命令接口。
D12的命令包括:4个初始化命令、24个数据流命令和2个普通命令。该文件包含了单片机对上述命令的实现函数,基本无须修改。
2.3 中断服务程序
isr.c部分的代码主要处理PDIUSBD12产生的中断请求。
硬件设计中,将PDIUSBD12中断一般连到单片机的外部中断0或者1中。由于只有一个中断源,如果要知道是什么中断,就需要读取PDIUSBD12中的中断寄存器的值进行判断。该文件包含了需要处理的各个中断的处理函数。其中许多处理函数仅仅是将相应标志位置1,用来在主函数中处理各类事务。在各个输入/输出端点引发的中断处理函数中,分别进行了读取缓冲区数据和发送数据到缓冲区等动作。其中,控制输入端点的中断处理函数还将相应控制位置1,以用来在主函数中触发标准设备请求和厂商请求。
2.4 主循环
主函数文件mainloop.c是一个大循环。在该文件中要执行各个初始化函数,发送USB请求和处理USB总线事件等。设备的各项功能需要在该文件中添加。
首先,初始化I/O口;然后初始化定时器2,设置中断,设置DMA(设备未用到DMA方式,置为00)等,通过连接指令指示D12完成软连接(SoftConnect)后,电脑就会检测到新设备。
在进入主循环后,需要用51的定时器2每隔1 ms检测一次电键的电平高低,并且将此信号通过USB接口发送出去,同时将P1.2口取反,以产生500 Hz的方波信号作为电键音。
2.5 协议层
chap_9.c:标准设备请求文件。该文件包含了所有设备相关的描述符,以及各个USB设备标准请求的实现函数。一个USB设备的各个特性都包含在了其所有的描述符内,而各个设备都有各自的特点,因此每个设备的描述符都要进行相应修改。其中,设备描述符里的idVendor与idProduct是联系PC端驱动的标志,必须与驱动一致。而各类标准设备请求是每个标准USB设备都要能够响应的,因此也就无须修改了。
protodma.c:该文件用来描述厂商请求。如果USB设备需要响应厂商请求,那么就要编写该厂商请求的实现函数。由于终端操作平台无须定义特殊的厂商请求,因此该文件不用修改。
3 端点配置
在D12芯片内存在三套输入/输出端点,根据配置不同可完成不同的工作,终端操作平台中的固件中是按照表1配置的。
根据端点的配置和各端点的特点,设置端点1为控制命令的传输端点,接收来自电脑的状态控制指令,共两个字节,如表2所示。
设置端点2为电键信号传输端口,手电键的按下或抬起通过00和01来标识,传输间隔为1 ms。
4 固件程序
多路复用地址/数据总线方式的实现,通过地址线的最低位来分辨命令和数据:
主循环程序首先做初始化I/O口,设置中断等准备工作,然后进入主循环,在主循环内查询事件标志,并做出相应处理。
5 结 语
本文实现了USB固件程序的开发。该固件编写采用分层结构简洁且易于修改和测试,既增加了代码的可读性,又增加了程序的通用性和移植性。
摘要:随着计算机技术的更新换代,USB接口已经成为个人计算机上最重要的外部设备扩展接口,在进行USB外设开发的过程中需要编写其固件程序。在此对USB接口固件程序进行了开发,在Keil C51软件环境中,采用C语言开发。介绍了固件程序的主要功能,给出了固件程序的流程、结构和端点配置,并给出了重点地方的具体程序。该固件编写采用分层结构简洁且易于修改和测试,既增加了代码的可读性,又增加了程序的通用性和移植性。
关键词:PDIUSBD12,USB,固件程序,分层结构
参考文献
[1]李英伟,王成儒,练秋生,等.USB2.0原理与工程开发[M].北京:国防工业出版社,2007.
[2]高卫东.51单片机原理与实践[M].北京:北京航空航天大学出版社,2005.
[3]夏益民,王光君.基于USB的高速数据采集系统[J].国外电子元器件,2003(10):20-23.
[4]周涛,张辉.采用PDIUSBD12的USB系统固件程序设计[J].电子技术应用,2003(5):1-3.
[5]张念淮,江浩.USB总线接口开发指南[M].北京:国防工业出版社,2001.
[6]周立功.PDIUSBD12USB固件编程与驱动开发[M].北京:北京航空航天大学出版社,2003.
[7]王梅,陈海峰.基于PDIUSBD12芯片的USB通用设备开发[J].电脑知识与技术,2006(3):175-176.
[8]SERRA PA,ROCCHITTA G,BAZZU G,et al.Design andconstruction of a low cost single-supply embedded telemetrysystem for amperometric biosensor applications[J].Sensorsand Actuators:B,Chemical,2007,122(1):118-126.
[9]SKIERUCHA W,WILCZEK A,WALCZAK R T.Recentsoftware improvements in moisture(TDR method),matricpressure,electrical conductivity and temperature meters ofporous media[J].International Agrophysics,2006,20(3):229-235.
USB驱动程序
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。