基于WINDOWSDDK的USB键盘驱动开发

龙源期刊网 http://www.qikan.com.cn

基于WINDOWSDDK的USB键盘驱动开发

作者:卢晓娟 陈根生

来源:《电子世界》2013年第10期

【摘要】USB接口具有方便快速等优点,已经发展成为一种比较普遍的计算机与外设的接口。基于微软windows系统DDK,本文介绍了一种非标准USB键盘的windows设备驱动程序的开发过程与方法。

【关键词】设备驱动;驱动开发包;非标准键盘 1.引言

USB总线的成功关键是使用户感到了使用USB设备的方便。即插即用(PnP)概念的使用使某些硬件的安装过程得到了简化。USB规范中指出,适合迁移到USB1.1上的硬件限定于那些低速到中速的外设,包括键盘,鼠标等。即这些设备的数据传输速率低于12Mb/sec,并且能通过单一的PC接口被系统软件识别。现在标准的usb键盘设备只需要遵循一些hid设备的协议就可以被windows操作系统自动识别无需设备制造商开发驱动程序,但有些键盘带有特殊功能,所以需要设备驱动程序。 2.Usb软件系统简介

USB设备对于USB系统来说是一个端点的集合,端点被分成组,一组端点实现一个接口,如图1所示。设备端点和主机软件之间利用管道进行数据交互。设备驱动程序就是通过这些接口和管道与设备进行通信的。

USB数据传输就是指发生在主机软件和USB设备上特定端点(endpoint)之间的数据交互,一个设备可以具有若干管道(pipe)。一般情况下,一个管道中数据传输与其他管道中的数据传输是相互独立的。这种发生在管道中的数据流动共有4种基本类型: (1)控制传输,一般发生在设备枚举阶段 (2)块传输,一般用于usb disk

(3)中断传输,一般用于键盘鼠标类设备 (4)流传输,一般用于语音视频流设备

龙源期刊网 http://www.qikan.com.cn

USB设备驱动程序都必须使用这些管道和接口来管理设备,而不是直接通过内存或I/O端口来存取来管理。

3.Windows驱动程序的工作原理 3.1 Windows驱动程序基本架构

驱动程序与应用程序的最大差别在于驱动程序的架构。应用程序从头到尾都在main或者winmain函数的控制下执行,驱动程序不存在这样的函数,而只是一个由I/O管理组件根据需要调用的子例程的集合,I/O管理组件根据不同的情况调用驱动程序中不同的例程。构成内核模式驱动程序的主要例程包括:初始化和清除例程,I/O系统服务调度例程,数据传输例程和资源回调例程,下面是一个基本的驱动例程架构: extern”C” NTSTATUS

DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) {

DriverObject->DriverUnload=Driver Unload;

DriverObject->DriverExtension->AddDevice=AddDevice; DriverObject->DriverStartIo=StartIo;

DriverObject->MajorFunction[IRP_MJ_PNP]=DispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER]=DispatchPower;

DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]=DispatchWmi; ...

servkey.Buffer=(PWSTR)ExAllocatePool(PagedPool,RegistryPath->Length+sizeof(WCHAR)); if(!servkey.Buffer)

return STATUS_INSUFFICIENT_RESOURCES;

龙源期刊网 http://www.qikan.com.cn

servkey.Maximum Length=Registry Path->Length+sizeof(WCHAR); RtlCopyUnicodeString(&servkey,RegistryPath); return STATUS_SUCCESS; }

(1)前三条语句为驱动程序的其它入口点设置了函数指针。在这里,我用了能表达其功能的名字命名了这些函数:DriverUnload、AddDevice、StartIo。

(2)每个WDM驱动程序必须能处理PNP、POWER、SYSTEM_CONTROL这三种请求;应该在这里为这些请求指定派遣函数。在早期的Windows 2000 DDK中,

IRP_MJ_SYSTEM_CONTROL曾被称作IRP_MJ_WMI,所以我把系统控制派遣函数命名为DispatchWmi。

(3)在省略号处,你可以插入设置其它MajorFunction指针的代码。

(4)如果驱动程序需要访问设备的服务键,可以在这里备份RegistryPath串。例如,如果驱动程序要作为WMI生产者,则需要备份这个串。这里我假设已经在某处声明了一个类型为UNICODE_STRING的全局变量servkey。

(5)返回STATUS_SUCCESS指出函数成功。如果函数失败,应该返回NTSTATUS.H中的一个错误代码,或者返回用户定义的错误代码。STATUS_SUCCESS的值为0。 3.2 Windows系统的I/O过程

为了实现操作系统的兼容性,可移植性,Windows操作系统不允许用户的应用程序对硬件设备进行操作,而由操作系统的I/O管理组件管理几乎所有的I/O操作请求,并最终由驱动程序完成所有的操作。具体过程如下:

(1)对I/O的每种用户其请求,I/O管理程序从分页系统内存中分配一个I/O请求包(IRP),基于用户请求的文件句柄和I/O函数,I/O管理程序将IRP传递给对应的驱动程序调度例程;

(2)调度例程检查请求的参数,如合法,把IRP包传递给驱动程序的Start I/O例程; (3)Start I/O例程使用IRP的内容开始一个设备I/O操作;

(4)当操作完成,驱动程序的DpcForIsr例程将最后状态代码保存在IRP中,并将它返回给I/O管理程序;

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4