随着微机技术水平的日益提高,传统的计算接口已经不能满足当前计算机高速发展的需求,计算机业界迫切需要新的通用型、高速总线接口。通用外设接口标准USB应运而生。USB,全称为通用串行总线(Universal Serial Bus),它是Compaq、IBM等PC大厂商联合开发的一种新型的、基于令牌的、高速的串行总线标准。开发者要设计USB设备接口,就必须首先了解USB协议,在此基础上有针对性的开发USB设备驱动程序。
驱动程序开发平台搭建成功后,我们可利用驱动程序生成向导Driver Wizard,根据硬件设置较为容易的生成USB设备驱动程序的大体框架。本人的设置如下:①选择WDM的驱动程序类型和Windows 2000运行平台。②选择USB总线类型,系统选择的USB芯片是Philip公司的ISP1581,填写它的VID(供应商ID)和PID(设备ID),这些信息由芯片的供应商提供。③增加端点1和端点2,它们分别具有IN和OUT属性。④根据需要选择对设备的操作有:Read、Write、Device Control和CleanUp。⑤选择给端点2产生BULK Read和Write的代码, 向导会自动产生一套对端点2进行读、写的代码。⑥设置驱动程序的属性,采用WDM接口;在选取读写方式时应遵循一条原则:需要快速传送大量数据时,用 Direct I/O ,反之用Buffer I/O ,这里选择BufferI/O;由于无特殊的电源需求,故选用系统默认的Manage Power For This Device。⑧增加IOCTL接口,在其生成的代码框架中加入自己的操作,以实现一个完整的USB设备驱动程序。最后就生成了一个WDM型的USB设备驱动程序框架和一个测试该驱动程序的测试程序大体框架。然后在其中添加需要的功能代码。
设备驱动程序与应用程序不同,它没有main()或WinMain()函数,而是有一个名为DriverEntry()的入口函数,它通常完成一些初始化工作。当设备驱动程序被加载时,操作系统调用这个入口。在使用DriverWizard 创建的驱动程序基本框架中,DriverEntry()函数已经写好了,无需添写代码。在该例程中,驱动程序要向操作系统登记并注册一些消息处理器,通过RegistryPath来找到位于注册表中的驱动程序参数,当驱动程序正确安装后,在注册表KEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Service 下可以找到MyUSB 项。而用DDK编写该入口函数还需初始化Dispatch(分派)例程入口。
status = m_Lower.SubmitUrb(pUrb, NULL, NULL, 5000L);
//若请求在此处理,设置I.Information指示多少数据拷贝回用户
I.Information()=0;
I.Status()=status;
return status;
}
4.3.4访问硬件例程 DeviceControl()
上层应用软件程序就是通过此例程来将IRP传到下层。
NTSTATUS MyUSBDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
switch (I.IoctlCode())
{
case MyUSB_IOCTL_LED:
status = MyUSB_IOCTL_LED_Handler(I);
break;
default: // 未被声明的I/O 控制请求
status = STATUS_INVALID_PARAMETER;
break;
}
}
限于篇幅,这里仅介绍本驱动程序中的部分例程实现代码。编写完驱动程序后,首先在Visual C++ 中编译通过,然后连接硬件,用DriverStudio 工具包中的SoftICE调试器调试该驱动程序,并且修改编译DriverStudio产生的该驱动程序的测试程序,就通过命令行来测试我们的驱动程序。最后对于LED的控制,我们可以直观的在设备上看到。