USB驱动程序的编写采用WDM驱动程序
- 格式:docx
- 大小:333.25 KB
- 文档页数:12
引言WDM是“Windows驱动程序模型”的简称,即“Windows Driver Model”。
实际上它是一系列集成在操作系统之中的常规系统服务集,用于简化硬件驱动程序的编写,并保证它们在Windows 98/Me/2000中的二进制兼容,WDM(Windows Driver Model)模型是从WinNT3.51和WinNT4的内核模式设备驱动程序发展而来的。
WDM主要的变化是增加了对即插即用、电源管理、Windows Management Interface(WMI)、设备接口的支持。
WDM模型的主要目标,是实现能够跨平台使用、更安全、更灵活、编制更简单的Windows 设备驱动程序。
WDM采用了“基于对象”的技术,建立了一个分层的驱动程序结构。
WDM 首先在Windows98中实现,在Windows2000中得到了进一步的完善,并在后续开发的Windows操作系统中都将存在,比如Windows Me和Windows XP。
微软在通过WDM 模型的引入,希望减轻设备驱动程序的开发难度和周期,逐渐规范设备驱动程序的开发,应该说,WDM将成为以后设备驱动程序的主流。
USB技术的全称是通用串行总线,是英文Universal Serial Bus的缩写。
它是一种应用在PC领域的新型接口技术,虽然USB2.0已经被广泛应用,但是初始的Windows 2000是支持USB1.0协议的,如果希望支持USB2.0协议,需要在微软网站上下载升级包。
实际上,对于键盘或者鼠标来说,传输的速度非常小,使用USB1.0或者是USB2.0的区别并不大。
闪存盘之类的存储设备,则需要重视传输速度。
USB1.0版本主要应用在鼠标,键盘等HID设备上,这就是本驱动程序中引用的头文件版本是USB1.0的原因。
本毕业设计的目的是希望对Windows 2000操作系统体系结构和驱动程序开发以及调试等方面的问题有一个比较深入的了解,对USB协议和USB体系有做一个比较深入的了解。
开发WDM型USB设备驱动程序USB设备驱动程序开发⼯具开发USB设备驱动程序需要专门的开发⼯具,⽬前应⽤⼴泛的⼯具主要有两⼤类。
⼀类是Microsoft公司提供的Windows DDK(Device Driver Kit)。
它有Windows 98 DDK 和Windows 2000 DDK两个版本。
Windows 98 DDK能够开发Windows 95/98/Me/NT下的VxD、KMD和WDM驱动程序。
Windows 2000 DDK 能够开发Windows 98/Me/NT/2000下的KMD和WDM驱动程序。
由于DDK基于汇编语⾔的编程⽅式和内核模式的调⽤,对没有深厚的OS原理和编程⽔平的⼈员来说,任务相当艰巨。
另⼀类是NuMega公司提供的DriverStudio,它是⼀个⼤的开发⼯具包,包含VtoolsD、SoftICE和DriverWorks等开发⼯具。
VtoolsD开发包提供了对VxD编程的C/C++类库⽀持,利⽤VtoolsD中的QuickVxD⼯具可以快速⽣成VxD的C/C++代码框架,开发者可以在此基础上根据各⾃的需要添加⾃⼰的代码。
DriverWorks⽤于开发KMD和WDM驱动程序,并且对DDK函数进⾏了类的封装,从⽽为开发Windows NT、Windows 2000和Widnwos98 WDM设备驱动程序提供了⼀个⾃动化的⽅法。
DriverWorks,提供了VC++下的开发向导Driver Wizard,按照它的提⽰可以迅速地⽣成驱动程序的框架。
这个框架结构提供可以正确执⾏WDM动态环境中IRP的请求,⽽且,也包含⽤于简化系统提供的标准类驱动程序(如HID、流)和总线驱动程序(如PCI和USB)接⼝的类等。
总之,利⽤DriverWorks开发WDM驱动程序,可以⼤⼤简化开发⼈员的⼯作量、缩短开发周期以及降低开发驱动程序的难度。
[1]⽤DriverWorks开发WDM型USB设备驱动程序要想使⽤DriverWorks,必须先安装以下软件:DriverStudio2.5,VisualStudio6.0,以及Windows2000DDK。
基于WDM的USB驱动程序研究与设计牛继来,王海霞( 哈尔滨商业大学 计算机与信息工程学院, 哈尔滨 150028)摘要:USB设备驱动程序的开发是USB设备开发的一个重要组成部分。
详细介绍了WDM 及USB的相关特点和层次结构,讨论了基于WDM模式下的USB驱动程序的基本原理,并对部分关键例程进行了分析。
关键字:USB设备,WDM,驱动程序,DriverStudio中图分类号:TP302.7 文献标识码:A Study and design of the USB driver based on WDMNIU Ji-Lai,WANG Hai-Xia(School of Computer and Information Engineering, Harbin University of Commerce, Harbin 150028, China) Abstract:The development of USB driver is an important part of the development of USB device.Introduce the relative characteristics and structure of WDM and USBparticularly; discuss the basic principle of USB driver based on WDM, and makeanalysis for partial key process.Key words:USB device,WDM,Driver,DriverStudio0 引言随着计算机及通信技术的不断发展,对高速、实时数据传输的需求越来越高,开发高速、高集成的总线接口设备也就成为必然趋势。
USB(Universal Serial Bus),即通用串行总线,是为实现计算机和通信的集成而提出的一种用于扩充PC体系结构的工业标准。
U S B驱动程序的编写采用W D M驱动程序Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】USB驱动程序的编写采用WDM 驱动程序。
WDM 驱动程序是一些例程的集合,它们被动地存在,等待主机系统软件(PnP 管理器、I/O 管理器、电源管理器等)来调用或激活它们。
具体驱动程序不同,其所包含的例程也不同。
一个WDM 驱动程序的基本组成包括以下5个例程:(1)驱动程序入口例程:处理驱动程序的初始化。
(2)即插即用例程:处理PnP 设备的添加、删除和停止。
(3)分发例程:处理用户应用程序发出的各种 I/O 请求。
(4)电源管理例程:处理电源管理请求。
(5)卸载例程:处理驱动程序的卸载。
包含文件:, ,, , , makefile,sources)在文件中,包含了上述五个例程:中定义了各种数据结构还有各种IOCTL控制码,用于不同数据的读写。
中实现了各种驱动例程。
包含了上述五个所说例程外还包含了其他例程,课程从下面的驱动程序入口例程得出一些信息。
驱动程序入口例程:NTSTATUSDriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath){NTSTATUS ntStatus = STATUS_SUCCESS;PDEVICE_OBJECT deviceObject = NULL;DriverObject->MajorFunction[IRP_MJ_CREATE] = Ezusb_Create; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ezusb_Close; ources. If you want to add a new source # file to thiscomponent. This file merely indirects to the real make file # that is shared by all thedriver components of the Windows NT DDK # !INCLUDE $(NTMAKEENV) 不要编辑这个文件。
事实上每个WDM程序所需要的makefile的内容都是一样的,只需要简单地copy一个makefile到新的项目中就可以了2、SourcesTARGETNAME= TARGETTYPE=DRIVER DRIVERTYPE=WDM TARGETPATH=lib INCLUDES=$(BASEDIR)inc; $(BASEDIR)incddk; TARGETLIBS=$(BASEDIR)lib*SOURCES= \这个文件指定了驱动程序目标名是,是一个WDM驱动程序,生成的文件存放在lib目录中。
值得注意的是,“=”前后不能有空格,否则编译的时候会出错。
开始编译:“开始”->“程序”->“Development Kits”->“Windows 2000 DDK”->“Checked Build Environment”屏幕将显示:(有“回车”的那行是需要读者你亲自打进去的)New or updated MSVC detected. Updating DDK envi ronment…. Setting environment for usingMicrosoft Visual C++ tools. Starting dirs creation…Completed. D:NTDDK>cd jtag_usb (回车)D:HelloWDM>build (回车)如果源代码没有错误的话,生成的将存放在lib目录中。
安装驱动程序:利用INF文件实现驱动的安装。
我们一般是采用INF文件,inf文件如下所示::[Version] Signature = "$CHICAGO$" Class = USB DriverVer = 11/11/2007,1.00.00 ClassGUID ={36FC9E60-C465-11CF-40000} provider = %ECICT% [SourceDisksNames] 1=%CYUSB_INSTALL%,,, [SourceDisksFiles] = 1 [Manufacturer] %MfgName%=ECICT[Ecict] %VID_0547&%=CyUsb, USB\VID_0547&PID_1002 [DestinationDirs]= 10,System32\Drivers [] AddReg= []CopyFiles= AddReg= [ AddReg= Addservice = CyUsb, 0x00000002, [] DisplayName = %% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ;SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL ServiceBinary = %10%\System32\Drivers\ LoadOrderGroup = Base [] HKR,,DevLoader,,*ntkern HKR,,NTMPDriver,, [ [ ;---------------------------------------------------------------; [Strings] CYUSB_INSTALL = "Your Device Installation Disk" ECICT = "ECICT" MfgName ="ECICT" VID_0547& = "USB_Jtag Controler" ;------------Replace GUID belowwith custom GUID-------------; = "{07BBF83D-D0B2-4915-870C-FC5B0B049DFC}" 准备好这个文件后,插入控制器,然后跳出设备驱动安装的对话框。
我想从列表选择硬件”->“其它设备”->“从磁盘安装”,选择所在的路径,然后安装。
当安装完成后,系统就会添加上你写好的驱动程序了。
(可以在“设备管理器”中查看到),这个驱动程序就投入使用。
驱动程序与应用程序的接口对用户来说,所用的应用程序都通过I/O控制来访问设备驱动程序。
用户的应用程序首先通过调用Win32函数CreateFile()来取得访问设备驱动的句柄。
然后,用户程序使用Win32函数DeviceIoControl()来提交I/O控制码,并为 CreateFile 函数返回的设备句柄设置I/O缓冲区。
下面的例程验证所获取的EZ-USB设备的句柄:HANDLE DeviceHandle;DeviceH andle=CreateFile( “\\\\.\\ezusb-0”,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);随后,用户的应用程序通过调用Win32函数DeviceIoControl()来向设备驱动程序发送请求。
下面显示的是DeviceIoControl()函数的原型。
EZ-USB设备驱动程序IOCTL使用相同的函数参数名。
BOOL DeviceIoControl() {HANDLEhDevice, //外设句柄DWORDdwIoControlCode, //I/O操作控制代码LPVOIDlpInBuffer, //输入缓冲区指针DWORDnInBufferSize, //输入缓冲区大小LPVOIDlpOutBufferSize, //输出缓冲区指针DWORDnOutBufferSize, //输出缓冲区大小LPDWORDlpBytesReturned, //实际返回的字节数LPOVRLAPPERlpOverLapper //用于异步操作的重叠指针}其中I/O操作控制代码是在USB设备驱动程序中定义和实施实际数据操作的,如在驱动程序中定义的:IOCTL_EZUSB_GET_DEVICE_DESCRIPTOR, IOCTL_EZUSB_BULK_READ, IOCTL_EZUSB_BULK_WRITE 等控制代码。
例如:(1)通过红色标注的ioctl控制码写入一个地址值。
//******************************************************* VENDOR_OR_CLASS_REQUEST_CONTROL myRequest; //在中定义的数据结构ULONG nBytes;WORD pvBuffer[1]; //temp for data and addresspvBuffer[0]=Addr; //地址//------------写地址--------------------------=0x00;//0-HOST T0 DEVICE,1-DEVICE TO HOST=2;//1-class,2-vendor=0;//0-device,1-interface,2-endpoint,3-ot her=0xb4;=0x00;//在这里不起作用=0x00;DeviceIoControl (hDevice,IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST, //ioctl控制码&myRequest, sizeof(VENDOR_OR_CLASS_REQUEST_CONTROL),pvBuffer,2,&nBytes,**********************************************************//(2)大块数据的写//******************************************************* BULK_TRANSFER_CONTROL bulkControl; // pipe type selected PWORD pData=0; //通道0用于写,通道1用于读。
pData=(PWORD)malloc(lenth*2);DeviceIoControl (hDevice,IOCTL_EZUSB_BULK_WRITE, //数据块的写IOCTL码&bulkControl,sizeof(BULK_TRANSFER_CONTROL),pData,length*2,&nBytes,**********************************************************//(2)大块数据的读//******************************************************* BULK_TRANSFER_CONTROL bulkControl; // pipe type selected PWORD pData=1; //通道0用于写,通道1用于读。