当前位置:首页>>开发编程>>综合开发>>新闻内容
开发WDM型的USB设备驱动程序
作者:鲜征征 杨皓 发布时间:2004-11-21 12:57:25 文章来源:计算机与信息技术

    用Driver Studio工具包开发WDM型的USB设备驱动程序

  前文所提及的WDM驱动程序开发方法,笔者都曾尝试过。个人认为用DriverStudio开发工具包来开发USB驱动程序行之有效。其中的Driver Wizard是创建WDM驱动程序框架的一个很好的工具,后文将介绍用它来创建USB设备驱动程序的基本框架。

  1、搭建开发平台

  由于利用 DriverStudio 开发WDM驱动程序在搭建开发平台的过程中对软件的安装顺序要求颇高,在开发过程中我也曾因为安装顺序的颠倒而失败。在实践中总结了以下的安装步骤,有必要在此作以介绍。

  ①在已装了Windows 2000 操作系统的机子上安装 Microsoft Visual C++6.0。 ②安装 Win2000 DDK 。③安装 NuMega DriverStudio 2.0 ( or 2.6 ) 驱动程序开发工具包。它包含DriverWorks( 用于开发内核模式WDM驱动程序 )、SoftICE( 用于调试WDM驱动程序 )等开发工具。④由于DriverWorks 所用的类库是对 DDK 函数的封装,必须在 VC中编译,创建自己的库文件。⑤设置 DDK 路径。

  2、利用DriverStudio 的DriverWorks生成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设备驱动程序框架和一个测试该驱动程序的测试程序大体框架。然后在其中添加需要的功能代码。

  3、USB设备驱动程序中的关键例程代码实现

  下面以我们的驱动程序为例,介绍USB驱动程序开发中的几个关键例程的实现。本驱动程序的主要功能是控制USB设备上LED灯通断并且对设备进行读写。

  1) 初始化例程 DriverEntry()

  设备驱动程序与应用程序不同,它没有main()或WinMain()函数,而是有一个名为DriverEntry()的入口函数,它通常完成一些初始化工作。当设备驱动程序被加载时,操作系统调用这个入口。在使用DriverWizard 创建的驱动程序基本框架中,DriverEntry()函数已经写好了,无需添写代码。在该例程中,驱动程序要向操作系统登记并注册一些消息处理器,通过RegistryPath来找到位于注册表中的驱动程序参数,当驱动程序正确安装后,在注册表KEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Service 下可以找到MyUSB 项。而用DDK编写该入口函数还需初始化Dispatch(分派)例程入口。

  2) 创建设备例程 AddDevice()

  大多数的PDO 都是在 PnP 管理器调用该程序入口点时被创建的。插入新设备后,系统启动时,总线枚举器会发现总线上的所有设备,会自动寻找并安装设备的驱动程序,并由驱动程序中的处理 PnP 功能模块自动处理 AddDevice() 例程及其他PnP消息。此例程使用IoCreateDevice() 函数创建设备对象,再使用 IoRegisterDeviceInterface() 函数将设备组成为一个特定的设备接口,然后使用IoAttachDeviceToDeviceStack() 函数关联设备栈。

NTSTATUS MyUSBDevice::AddDevice( PDEVICE_OBJECT Pdo )
{
 // 产生一个DDK中KDevice类新的设备对象
 MyUSBDevice *pDevice = new ( static cast<PCWSTR>( KUnitizedName(L“MyUSBDevice”,m_Unit) ),// 设备名
  FILE_DEVICE_UNKNOWN, // 设备类型
  NULL, // 指针链接名
  0, // 设备特征标志位
  DO_BUFFERED_IO| DO_POWER_PAGABLE); // I/O传输方式
 MyUSBDevice(Pdo, m_Unit);
 if ( pDevice == NULL )
 {
  return STATUS_INSUFFICIENT_RESOURCES;
 }
 NTSTATUS status = devices -> ConstructorStatus();
 if ( !NT_SUCCESS(status) ) // 不成功,返回错误状态并删除指针
 {
  delete pDevice;
 }
 else // 如果成功,向系统报考设备的电源状态变化为PowerDeviceD0
 {
  m_Unit++;
  pDevice -> ReportNewDevicePowerState( PowerDeviceD0 );
 }
 return status;
}

  3) LED控制处理例程 MyUSB_IOCTL_LED_Handler()

  该例程是实现本驱动程序功能的关键例程,它是用来控制设备上的LED灯通断,主要利用USB Vendor Request来向设备传送。其中,request=1的时候表示让LED亮,request=0的时候让LED灭。它是通过DeviceControl由上层应用程序传下来。实现代码如下:

NTSTATUS MyUSBDevice::MyUSB_IOCTL_LED_Handler(KIrp I)
{
 NTSTATUS status = STATUS_INVALID_PARAMETER;
 //检查输入参数是否正确,如果不正确,返回STATUS_INVALID_PARAMETER
 if(I.IoctlOutputBufferSize() || !I.IoctlBuffer() ||(I.IoctlInputBufferSize() != sizeof(UCHAR)))
  return status;
 //处理MyUSB_IOCTL_LED_ON请求
 PURB pUrb = m_Lower.BuildVendorRequest(NULL, // 传输缓冲区
  0, // 传输缓冲区大小
  0, // 请求保留位
  (UCHAR)(*(PUCHAR)I.IoctlBuffer()), // 请求1=LED_ON ,0=LED_OFF
  0 ); // 值
 //向下传送URB
 status = m_Lower.SubmitUrb(pUrb, NULL, NULL, 5000L);
 //若请求在此处理,设置I.Information指示多少数据拷贝回用户
 I.Information()=0;
 I.Status()=status;
 return status;
}

  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的控制,我们可以直观的在设备上看到。

  结束语

  USB技术的不断发展和完善,已经使其逐渐成为先进总线接口技术的标志和方向,如今USB OTG标准已经发布,那么USB的应用领域也将越发的广泛。开发一些特定功能的USB接口并设计其设备驱动程序也将成为应用USB技术的关键。通过对USB的学习和Windows 2000下的WDM驱动程序的研究,本文已经给出了编写WDM型USB设备驱动程序的一般方法,读者可以在实际应用中逐步提高对USB和驱动程序的认识,取得事半功倍的效果。




[首页]    [上一页]    [下一页]    [末页]    
最新更新
·wml中页面自动跳转的实现方法
·Alexa排名数据接口的简要介绍
·利用U盘进行软件加密的方法(VB)
·优秀程序员的十个习惯
·项目管理:如何逃离垃圾客户
·QQ2009去广告部分核心源代码
·让程序更容易理解:13个代码注释的小技
·nx1和nx2后缀名是什么数据库文件?
·正则表达式符号解释大全
·什么是RIA?介绍几种RIA客户端开发技术
相关信息
画心
愚爱
偏爱
火苗
白狐
画沙
犯错
歌曲
传奇
稻香
小酒窝
狮子座
小情歌
全是爱
棉花糖
海豚音
我相信
甩葱歌
这叫爱
shero
走天涯
琉璃月
Nobody
我爱他
套马杆
爱是你我
最后一次
少女时代
灰色头像
断桥残雪
美了美了
狼的诱惑
我很快乐
星月神话
心痛2009
爱丫爱丫
半城烟沙
旗开得胜
郎的诱惑
爱情买卖
2010等你来
我叫小沈阳
i miss you
姑娘我爱你
我们都一样
其实很寂寞
我爱雨夜花
变心的玫瑰
犀利哥之歌
你是我的眼
你是我的OK绷
贝多芬的悲伤
哥只是个传说
丢了幸福的猪
找个人来爱我
要嫁就嫁灰太狼
如果这就是爱情
我们没有在一起
寂寞在唱什么歌
斯琴高丽的伤心
别在我离开之前离开
不是因为寂寞才想你
爱上你等于爱上了错
在心里从此永远有个你
一个人的寂寞两个人的错